2011-01-09 3 views
1

J'essaie donc de concevoir une base de données assez volumineuse pour gérer les vidéos et leurs tags. Parce que seul un nombre fini de tags peut être sélectionné pour une vidéo (27), je les stocke dans une table de 28 colonnes de large (une colonne pour chaque tag + video_id).MySQL: Plus de requêtes de requêtes et plus de requêtes

Mon problème se pose lorsque je veux obtenir le nombre de fois qu'un utilisateur a aimé/n'a pas aimé une vidéo avec une certaine étiquette (disons # 24). Chaque Like/Dislike obtient une ligne dans une autre table.

Voici les deux options que j'ai considérées.

1) Ajouter 27 autres colonnes tinyint à la table utilisateur, chacune représentant le nombre de fois où elle a voté sur une vidéo avec tagX.
PRO: facilement sélectionnés
CON: double la quantité de données nécessaire pour chaque utilisateur

2) Utilisation des jointures internes
PRO: Keeps petite taille
CON: plus fort sur le système

deux parce que je suis optimiste et parce que j'essaie d'utiliser les bonnes pratiques, j'essaie d'optimiser mes bases de données pour plus de 300 000 utilisateurs, et ces chiffres seront très utiles. J'ai fait le calcul et même avec 300 000 utilisateurs cela ajouterait seulement environ 27 mégaoctets à ma base de données.

Que faire !?

Répondre

0

27 colonnes à la table utilisateur ne fonctionnent que si vous avez 27 étiquettes différentes. Donc, ajouter une autre balise nécessite un changement de schéma (ce qui est une mauvaise chose).

Je vote pour quelque chose comme ceci:

table users(
    user_id 
    ,primary key(user_id) 
); 

table videos(
    video_id 
    ,primary key(video_id) 
); 

table tags(
    tag_id 
    ,tag_name 
    ,primary key(tag_id) 
); 

table video_tags(
    video_id 
    ,tag_id 
    ,primary key(video_id, tag_id) 
); 

table user_likes(
    user_id 
    ,video_id 
    ,primary key(user_id, video_id) 
); 

Pour afficher le nombre de voix par étiquette, vous feriez quelque chose comme ceci:

select c.tag_name 
     ,count(*) 
    from user_likes a 
    join video_tags b uing(video_id) 
    join tags  c using(tag_id) 
where a.user_id = ? 
group 
    by c.tag_name; 
4

(ce qui est juste mon avis)

Je pense que vous optimisez trop tôt (et probablement à tort). Les jointures ne sont pas si chères. Vous devriez avoir une table users, une table de tags et une table similaire. En fonction de vos requêtes exactes, vous trouverez probablement cela marginalement moins cher.

Vous feriez mieux de passer du temps à vous assurer que vous avez les bons index que de créer une mise en page conçue pour des performances supérieures à la maintenance.

+0

Merci pour les conseils! Je vais certainement faire ça – DropDeadFred81

1

Votre rationalité denormazling est imparfaite. Aujourd'hui, vous pourriez penser que 27 vidéos est le maximum mais il y en aura toujours un ou deux ou plus dans le futur.

Questions connexes