2010-06-30 6 views
3

Disons que j'ai une base de données simple avec des tables 'posts' et 'tags'. Les messages peuvent contenir de nombreux tags et tags peuvent appartenir à de nombreux articles.Meilleure façon de stocker une relation many-to-many dans MySQL?

Quelle est la meilleure façon de structurer la base de données? J'ai pensé à utiliser une liste/sérialiser:

tags 
idx tag_id, str tag_name 

posts 
idx post_id, str title, list tag_ids 

OU d'avoir une autre table avec les associations. Le problème est l'utilisation de ce que je ne sais même pas comment structurer la requête pour tirer les noms de balises associées lorsque je reçois un message.

posts 
idx post_id, str title 

post_tags 
fk post_id, fk tag_id 

En fait, je ne les aime pas. Y a-t-il un meilleur moyen?

+0

double possible de [nombreux à-plusieurs dans MySQL] (http://stackoverflow.com/questions/2632965/many-to-many-relationships-in-mysql) –

Répondre

19

Le post_tags est le moyen approprié pour implémenter une relation plusieurs à plusieurs dans la base de données.

Le seul ajout que je ferais à ce que vous avez posté est que les deux colonnes dans ce devrait être la clé primaire pour s'assurer qu'il n'y a pas de doublons.

+0

+1: yup, c'est la voie à suivre – RedFilter

+0

+1 choses simples sont les meilleurs! :) –

+4

+1 ici aussi. Ne pas l'aimer est une mauvaise raison de ne pas le faire, surtout si vous n'êtes pas le seul à maintenir le code. –

2

Utilisez la table avec les associations - c'est ce qu'on appelle une table de jonction .

Pour obtenir les tags pour un poste:

SELECT tag_name FROM tags, post_tags WHERE post_tags.tag_id = tags.tag_id AND post_tags.post_id = 12345; 
+1

Ne faites pas de jointures implicites, les jointures implicites me font pleurer. – friedo

2

Vous presque certainement vouloir utiliser une "intersection" ou une table de jointure. Cette table peut contenir les clés primaires de la table posts et tags, et (facultativement) sa propre clé primaire distincte. La jonction des trois tables devrait être simple:

select ... 
from post_tags 
inner join posts on post_tags.postID = posts.postID 
inner join tags on post_tags.tagID = tags.tagID 
... 

Vous pouvez créer une vue qui fait la jointure de base que vous pouvez ensuite référencer dans votre code.

Questions connexes