Version courte
Je dois ajouter un nombre fixe de propriétés supplémentaires à chaque paire dans une jointure plusieurs-à-plusieurs existante. En passant aux diagrammes ci-dessous, laquelle des options 1 à 4 est la meilleure façon, en termes d'avantages et d'inconvénients, d'y parvenir en étendant le scénario de base? Ou, y a-t-il une meilleure alternative que je n'ai pas envisagée ici?
Version plus longue
J'ai actuellement deux tables dans une relation plusieurs-à-plusieurs, via une table de jointure intermédiaire. Je dois maintenant ajouter des liens supplémentaires vers des propriétés qui appartiennent à la paire d'objets existants. J'ai un nombre fixe de ces propriétés pour chaque paire, bien qu'une entrée dans le tableau des propriétés puisse s'appliquer à plusieurs paires (ou même être utilisée plusieurs fois pour une paire). J'essaie de déterminer la meilleure façon de procéder et j'ai du mal à savoir comment penser la situation. Sémantiquement, il semble que je puisse le décrire comme l'un des éléments suivants également:
- Une paire liée à un ensemble d'un nombre fixe de propriétés supplémentaires
- Une paire liée à de nombreuses propriétés supplémentaires
- Plusieurs (deux) objets liés à un ensemble de propriétés
- De nombreux objets liés à de nombreuses propriétés
Exemple
J'ai deux types d'objets, X et Y, chacun avec des ID uniques, et une table de liaison objx_objy
avec des colonnesx_id
et y_id
, qui forment ensemble la clé primaire du lien. Chaque X peut être lié à plusieurs Y et vice versa. Il s'agit de la configuration de ma relation plusieurs-à-plusieurs existante.
Cas de base
Maintenant, en plus, j'ai un ensemble de propriétés définies dans une autre table et un ensemble de conditions dans lesquelles une paire (X, Y) donnée doit avoir la propriété P. Le nombre de conditions est fixe et le même pour toutes les paires. Ils disent essentiellement "Dans la situation C1, la paire (X1, Y1) a la propriété P1", "Dans la situation C2, la paire (X1, Y1) a la propriété P2", et ainsi de suite, pour trois situations / conditions pour chaque paire dans la jointure table.
Option 1
Dans ma situation actuelle il y a exactement trois conditions, et je n'ai aucune raison de penser que d'augmenter, une possibilité est d'ajouter des colonnes c1_p_id
, c2_p_id
et c3_p_id
à featx_featy
, en spécifiant une donnée x_id
et y_id
qui la propriété p_id
à une utilisation dans chacun des trois cas .
Cela ne me semble pas être une excellente idée, car cela complique le SQL pour sélectionner toutes les propriétés appliquées à une fonctionnalité et ne s'adapte pas facilement à davantage de conditions. Cependant, il impose l'exigence d'un certain nombre de conditions par paire (X, Y). En fait, c'est la seule option ici qui le fait.
Option 2
Créez une table de conditions cond
et ajoutez l'ID de condition à la clé primaire de la table de jointure.
Un inconvénient est qu'il ne spécifie pas le nombre de conditions pour chaque paire. Un autre est que lorsque je ne considère que la relation initiale, avec quelque chose comme
SELECT objx.*, objy.* FROM objx
INNER JOIN objx_objy ON objx_objy.x_id = objx.id
INNER JOIN objy ON objy.id = objx_objy.y_id
Je dois ensuite ajouter une DISTINCT
clause pour éviter les entrées en double. Cela semble avoir perdu le fait que chaque paire ne devrait exister qu'une seule fois.
Option 3
Créez un nouvel «ID de paire» dans la table de jointure, puis créez une deuxième table de liens entre la première et les propriétés et conditions.
Cela semble avoir le moins d'inconvénients, à part le manque d'imposer un nombre fixe de conditions pour chaque paire. Est-il judicieux de créer un nouvel ID qui n'identifie rien d'autre que les ID existants?
Option 4 (3b)
Fondamentalement les mêmes que l'option 3, mais sans la création du champ ID supplémentaire. Ceci est accompli en plaçant les deux ID d'origine dans la nouvelle table de jointure, afin qu'elle contienne des champs x_id
et y_id
, au lieu de xy_id
.
Un avantage supplémentaire de ce formulaire est qu'il ne modifie pas les tables existantes (bien qu'elles ne soient pas encore en production). Cependant, il duplique essentiellement une table entière plusieurs fois (ou se sent de cette façon, de toute façon) donc ne semble pas non plus idéal.
Sommaire
Mon sentiment est que les options 3 et 4 sont suffisamment similaires pour que je puisse choisir l'une ou l'autre. J'aurais probablement maintenant, sinon pour l'exigence d'un petit nombre fixe de liens vers les propriétés, ce qui rend l'option 1 plus raisonnable qu'elle ne le serait autrement. Sur la base de quelques tests très limités, l'ajout d'unDISTINCT
clause à mes requêtes ne semble pas affecter les performances dans cette situation, mais je ne suis pas sûr que l'option 2 représente la situation ainsi que les autres, en raison de la duplication inhérente provoquée par le placement les mêmes paires (X, Y) sur plusieurs lignes de la table de liens.
L'une de ces options est-elle ma meilleure voie à suivre ou existe-t-il une autre structure que je devrais envisager?
DISTINCT
clause, je pensais à une requête comme celle à la fin de # 2, qui relie x
et y
traverse xyc
mais ne fait pas référence à c
... Donc, si j'ai (x_id, y_id, c_id)
contraint UNIQUE
avec des lignes (1,1,1)
et (1,1,2)
, alors SELECT x.id, y.id FROM x JOIN xyc JOIN y
, je vais en récupérer deux identiques lignes (1,1)
, et (1,1)
.