6
votes

Colonne multiples Contraintes de clé étrangère

Je veux configurer des contraintes de table pour le scénario suivant et je ne sais pas comment le faire ou si cela est même possible dans SQL Server 2005.

J'ai trois tables A, B, c. C est un enfant de B. B aura une clé étrangère facultative (peut être null) référencier A. Pour des raisons de performance, je souhaite également que le tableau C ait la même référence de la clé étrangère à la table A. La contrainte sur le tableau C devrait être que c doit faire référence à son parent (b) et a également la même référence de la clé étrangère à A comme son parent.

Quelqu'un a des idées sur la façon de faire cela?


3 commentaires

Ma réaction est - supprimez ce lien supplémentaire de C à A - Avez-vous été prouvé qu'il existe un problème de performance? Ou est-ce juste pour simplifier une certaine question quelque part?


Principalement destiné à une récupération facile / rapide. C est un enregistrement de détail de B. Dans la plupart des cas, je veux juste que tous les détails en C référencés par une clé de A.


Que diriez-vous d'un exemple réel? Le problème de performance ne peut pas exister du tout et en utilisant des clés naturelles, vous pourrez peut-être rejoindre directement de toute façon.


5 Réponses :


0
votes

J'ai trois tables A, B, c. C est un L'enfant de B. B aura une facultative clé étrangère (peut être null) référencement A. Pour des raisons de performance, je veux aussi Tableau C pour avoir la même clé étrangère Référence au tableau A. La contrainte sur le tableau c devrait être que c doit référence à son parent (b) et a également la même référence de clé étrangère à A comme son parent.

Vous pouvez avoir la table B a une double clé primaire (la clé de A, puis dites une identité), puis utilisez-le pour créer un lien vers C. Cela ne vous permettra pas d'avoir une référence de clé étrangère nulle sur B. Mais les clés étrangères ne sont pas autorisées à être nulle de toute façon.

Vraiment si vous avez des index, etc. Ensemble correctement, il n'y a pas de besoin réel de pousser la clé de A à C. Entrée sur le tableau B pour obtenir une clé de réception ne sera pas essentiellement une performance (comme presque personne ).


1 commentaires

Bonne idée! C'était ma première pensée avant de découvrir que nous ne connaîtrons pas toujours la clé de A. Hum ... Peut-être que je vais essayer la jointure. B Négociez généralement un lot entier, c'est pourquoi j'ai la clé d'une clé dans le tableau C. 90% du temps, j'ai juste besoin de détails sur C utilisant la clé de A.



6
votes

Je ne vois pas besoin d'appliquer explicitement la relation de C à A. Suivez simplement la chaîne de C à B à A.


0 commentaires

1
votes

La dénormalisation aux fins d'améliorer la performance est assez courante, surtout si vous avez des preuves montrant sa valeur. Je suppose que vous avez de bonnes raisons de le faire, alors je ne vais pas aborder cela.

Avez-vous pensé à simplement avoir un déclencheur d'insertion sur C qui définit la table de référencement de colonne A basée sur une recherche dans le tableau B? Vous avez peut-être également besoin de mettre à jour des déclencheurs sur C et B pour vous assurer qu'il est toujours synchronisé. Cela garantirait la colonne du tableau C que les références Le tableau A est toujours correct, même si ce n'est pas "appliqué" par une contrainte réelle.


1 commentaires

Je travaille dans la base de données avec un volume de transaction très élevé afin que la performance soit critique. Je peux tester votre idée et voir quels déclencheurs d'impact sur la performance auront, merci!



2
votes

En général, je ne vois pas une raison spécifique de le faire - cependant, vous avez demandé.

chose à comprendre est qu'un modèle relationnel n'a pas à suivre un modèle OO. Il s'agit d'un moyen standard de présenter de la ligne de commande client code>. Rien de mal à cela. P>

text alt p>

si je veux Pour trouver tous les articles de ligne appartenant à un client, je dois me joindre via la table code> code>, similaire à la notation OO DOT-DOT ( client.order.lineItem code>). p> xxx pré>

supposons que je modifie les touches un peu, comme: p>

 text alt p>

Le CustomerOrderid code> est un numéro de séquence de commande pour chaque client (1,2,3 ...) et le CustomerOrderitemid code> est un numéro de séquence d'élément de ligne pour chacune des commandes du client (1,2,3 ...). Chacun est facile à générer, comme dans p> xxx pré>

maintenant si je veux trouver des éléments de ligne appartenant à un client (et certaines données client), je peux sauter le Commander code> Table. P>

select * 
from LineItem
where CustomerID = 7 ;


0 commentaires

0
votes

On dirait que le cas d'UES commun pour vous est que vous avez la clé de la touche et vous avez besoin de toutes les lignes correspondantes en C. Auquel cas la requête suivante doit être rapide:

select C.* 
from B
join C on C.Bid = B.Bid
where C.Aid = <value>


0 commentaires