2010-03-16 14 views
3

J'ai une base de données avec deux tables - appelons-les Foo et Bar. Chaque foo peut être lié à n'importe quel nombre de barres, et chaque barre peut être liée à un nombre quelconque de foos. Je veux être capable de récupérer, avec une requête, les foos associés à une certaine barre, et les barres qui sont associées à un certain truc. Ma question est la suivante: quelle est la meilleure façon d'enregistrer ces relations? Devrais-je avoir une table distincte avec des enregistrements de chaque relation (par exemple, deux colonnes, foo et bar)? La table foo devrait-elle avoir une colonne pour une liste de barres, et vice versa? Y a-t-il une autre option que je néglige?Théorie de la base de données - relation entre deux tables

Répondre

11

Cela s'appelle une relation plusieurs-à-plusieurs. La solution "standard" consiste à configurer une troisième table, avec la clé primaire de chaque table dans chaque ligne où il y a une relation.

La troisième table est appelée une table de jonction. "Table de jonction" de Wikipedia: http://en.wikipedia.org/wiki/Junction_table

À titre d'exemple:

Foo 
UID 
Col1 
Col2 

Bar 
UID 
Col1 
Col2 

Foo_Bar 
UID 
Foo_UID 
Bar_UID 

Ainsi, dans ce qui précède, il pourrait y avoir beaucoup de baby-foot et de nombreux bars. Chaque foo qui se rapporte à une barre et chaque barre qui se rapporte à un foo existerait dans la table Foo_Bar. Pour obtenir tous les foos qui se rapportent à une barre donnée, vous pouvez utiliser l'instruction SQL suivante:

select * 
from foo 
where uid in (
    select foo_uid 
    from foo_bar 
    where bar_uid=<some bar uid>) 

(. N'a pas trouvé de dupes exactes de cette question, mais les questions suivantes se dilatent sur le sujet)

Many to many table design question
Many to Many Relation Design - Intersection Table Design

+0

1) Dans la terminologie Relational, si elle contient ** seulement ** les PK des parents, c'est une table ** Associative **, car elle résout la relation many-to-many; s'il contient d'autres données, c'est une "table" ordinaire. Aucune idée de ce que les wikis vont appeler cette semaine. 2) A moins de vouloir dupliquer des lignes, le PK est '(Foo_UID, Bar_UID)'. 3) Le 'Foo-Bar.UID' est redondant à 100%, une colonne et un index supplémentaires; cela ne sert à rien; il peut être retiré. – PerformanceDBA

1

Il est en effet un grand nombre à plusieurs navires de relation. En plus de la réponse de Michael, je voulais fournir ce qui suit en tant que ressource supplémentaire. Je l'ai vu trop de mise en œuvre de la base de données pauvres de ne pas soulever cette question (et pas seulement pour vous, mais d'autres qui pourraient voir à l'avenir)

Questions connexes