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?
la source
DISTINCT
clause, je pensais à une requête comme celle à la fin de # 2, qui reliex
ety
traversexyc
mais ne fait pas référence àc
... Donc, si j'ai(x_id, y_id, c_id)
contraintUNIQUE
avec des lignes(1,1,1)
et(1,1,2)
, alorsSELECT x.id, y.id FROM x JOIN xyc JOIN y
, je vais en récupérer deux identiques lignes(1,1)
, et(1,1)
.Réponses:
Option 1
Cela ne complique pas nécessairement la requête SQL (voir conclusion ci-dessous).
Il évolue facilement vers plus de conditions, tant qu'il existe un nombre fixe de conditions et qu'il n'y en a pas des dizaines ou des centaines.
C'est le cas, et bien que vous disiez dans un commentaire que c'est "la moins importante de mes exigences", vous n'avez pas dit que cela n'avait pas d'importance du tout.
Option 2Je pense que vous pouvez rejeter cette option en raison des complications que vous mentionnez. Le
objx_objy
tableau est susceptible d'être le moteur de certaines de vos requêtes (par exemple, "sélectionner toutes les propriétés appliquées à une fonctionnalité", ce que j'entends par toutes les propriétés appliquées à unobjx
ouobjy
). Vous pouvez utiliser une vue pour pré-appliquer leDISTINCT
donc il ne s'agit pas de compliquer les requêtes, mais cela va très mal évoluer en termes de performances pour un gain très faible.Option 3Non, ce n'est pas le cas - l'option 4 est meilleure à tous égards.
Option 4
Cette option est très bien - c'est la façon évidente de mettre en place les relations si le nombre de propriétés est variable ou sujet à changement
Conclusion
Ma préférence serait l'option 1 si le nombre de propriétés par
objx_objy
est susceptible d'être stable, et si vous ne pouvez pas imaginer en ajouter plus d'une poignée supplémentaire. C'est également la seule option qui applique la contrainte «nombre de propriétés = 3» - appliquer une contrainte similaire sur l'option 4 impliquerait probablement l'ajout dec1_p_id
… colonnes à la table xy de toute façon *.Si vous ne vous souciez pas vraiment de cette condition et que vous avez également des raisons de douter que le nombre de propriétés sera stable, choisissez l'option 4.
Si vous ne savez pas laquelle, choisissez l'option 1 - c'est plus simple et c'est certainement mieux si vous avez l'option, comme d'autres l'ont dit. Si vous êtes mis hors option 1 "... car cela complique le SQL pour sélectionner toutes les propriétés appliquées à une fonctionnalité ..." Je suggère de créer une vue pour fournir les mêmes données que la table supplémentaire dans l'option 4:
tables option 1:
vue pour «émuler» l'option 4:
"sélectionner toutes les propriétés appliquées à une entité":
dbfiddle ici
la source
Je crois que n'importe laquelle de ces options pourrait fonctionner, mais j'irais avec l'option 1 si le nombre de conditions est vraiment fixé à 3, et l'option 2 si ce n'est pas le cas. Le rasoir d'Occam fonctionne également pour la conception de bases de données, tous les autres facteurs étant égaux, la conception la plus simple est généralement la meilleure.
Bien que si vous souhaitez suivre des règles strictes de normalisation de la base de données, je pense que vous devrez utiliser 2, que le nombre de conditions soit fixe ou non.
la source