2008-12-10 8 views

Répondre

1

Je ne sais pas comment vous le feriez sans une redondance énorme et horrible. La façon standard de gérer une relation plusieurs-à-plusieurs entre deux tables est via une troisième table qui contient deux valeurs de clé primaire, une pour la première table, une pour la deuxième table, avec une contrainte unique (lire 'index') la combinaison de toutes ces colonnes, et éventuellement avec un ou deux doublons (non uniques) sur les clés primaires séparées. Dans les grandes lignes:

CREATE TABLE Table1 (pkcol1 ... PRIMARY KEY, ...); 
CREATE TABLE Table2 (pkcol2 ... PRIMARY KEY, ...); 
CREATE TABLE MtoM_Table1_Table2 
(
    pkcol1 ... REFERENCES Table1, 
    pkcol2 ... REFERENCES Table2, 
    PRIMARY KEY (pkcol1, pkcol2) 
); 
-- CREATE INDEX fk1_mtom_table1_table2 ON MtoM_Table1_Table2(pkcol1); 
-- CREATE INDEX fk2_mtom_table1_table2 ON MtoM_Table1_Table2(pkcol2); 

Si votre SGBD est intelligent, vous pouvez sauter l'index séparé sur la colonne principale de la clé primaire depuis l'index sur la clé primaire peut également être utilisé lors de la recherche du juste la valeur principale. Supposons que Table1 et Table2 sont la même table (donc, en fait, nous avons juste Table1), comme dans la question; cela nécessiterait normalement toujours la table de mappage MtoM_Table1_Table1 - une table distincte de la table principale. La table de mappage doit avoir des noms distincts pour la colonne PK (clé primaire), mais les deux colonnes (ou ensembles de colonnes) dans la table de mappage se référeront aux colonnes PK dans Table1.

CREATE TABLE Table1 (pkcol1 ... PRIMARY KEY, ...); 
CREATE TABLE MtoM_Table1_Table1 
(
    pkcol1 ... REFERENCES Table1(pkcol1), 
    akcol1 ... REFERENCES Table1(pkcol1), 
    PRIMARY KEY (pkcol1, akcol1) 
); 
-- CREATE INDEX fk1_mtom_table1_table1 ON MtoM_Table1_Table1(pkcol1); 
-- CREATE INDEX fk2_mtom_table1_table1 ON MtoM_Table1_Table1(akcol1); 

Si vous voulez éliminer la table de mappage trop, alors vous devez avoir une deuxième colonne au tableau 1 pour maintenir l'autre valeur PK - appeler FKcol1 (pour la colonne de clé étrangère). Cela vous laisse alors avec un dilemme: quelle est la clé primaire? Ce doit être la combinaison de PKCol1 et FKCol1. Mais FKCol1 est censé référencer la clé primaire d'une autre rangée - donc vous avez une contradiction. Même en supposant que vous ayez réussi à éviter cela comme problème (comment, exactement?), D'avoir "plusieurs lignes" dans le côté référence de la relation plusieurs-à-plusieurs, vous devez avoir plusieurs lignes dans la table principale avec les mêmes données toutes les colonnes sauf FKcol, mais celles-ci référenceront un nombre (plus d'un, en général) d'autres lignes dans la table. C'est une contradiction plus un cauchemar de redondance, plus vous avez perdu votre clé primaire simple, plus il serait horrible de comprendre ce qui se passe.

CREATE TABLE Table1 
(
    pkcol1 ... /* PRIMARY KEY */, 
    fkcol1 ... /* FOREIGN KEY REFERENCES Table1(pkcol1) */, 
    ... 
); 
-- CREATE INDEX fk1_table1 ON Table1(pkcol1); 
-- CREATE INDEX fk2_table1 ON Table1(fkcol1); 

Alors, je suis convaincu que la seule réponse raisonnable est « Non - vous ne pouvez pas représenter les deux extrémités d'un grand nombre à plusieurs dans la même table, vous devez utiliser une table de correspondance pour conserver beaucoup de chance de tout ce qui fonctionne «comme d'habitude» dans le système ».

0

Si vous utilisez des annotations hibernate, il existe un @ManyToMany, pas sûr de l'équivalent XML. Il devrait apparaître dans la documentation API de votre distribution

Questions connexes