Clé primaire Composite

je travaille à la conception d'une base de données qui sera utilisée pour stocker des données provenant de différentes sources. Les instances que je stocke se voient attribuer des id uniques par les sources originales. Chaque instance que je stocke devrait contenir des informations sur la source d'où elle vient, ainsi que L'ID QU'elle a été associée par cette source.

à titre d'exemple, considérons le tableau suivant qui illustre le problème:

----------------------------------------------------------------
| source_id | id_on_source | data                              |
----------------------------------------------------------------
| 1         | 17600        | ...                               |
| 1         | 17601        | ...                               |
| 2         | 1            | ...                               |
| 3         | 1            | ...                               |
----------------------------------------------------------------

notez que pendant que le id_on_source est unique pour chaque source, il est possible que le même id_on_source a trouver dans différentes sources.

j'ai une bonne compréhension des bases de données relationnelles, mais je suis loin d'être un expert ou même un utilisateur expérimenté. Le problème que je rencontre avec cette conception est ce que je devrais utiliser comme clé primaire. Les données tendent à imposer l'utilisation d'une clé primaire composite de (source_id, id_on_source). Après un peu googling j'ai trouvé quelques débats chauffés sur les avantages et les inconvénients des clés primaires en composite cependant, me laissant un peu confus.

la table aura une relation de un à plusieurs avec les autres tables, et sera donc mentionnée dans les clefs étrangères des autres tables.

je ne suis pas attachée à une RDBMS et je ne sais pas si c'est important pour les fins de la discussion, mais disons que je préfère travailler avec SQLite et MySQL.

Quels sont les avantages et les inconvénients de l'utilisation d'une clé étrangère composite dans ce cas? Laquelle préférez-vous?

19
demandé sur AlphaMale 2009-09-05 15:09:21

8 réponses

je trouve personnellement que les clés primaires composites sont douloureuses. Pour chaque table que vous souhaitez joindre à votre table "sources", vous devrez ajouter à la fois le champ source_id et le champ id_on_source.

je créerais une clé primaire standard à incrémentation automatique sur votre table sources et j'ajouterais un index unique sur les colonnes source_id et id_on_source.

Ceci vous permet alors d'ajouter l'id de la table de sources de clé étrangère sur d'autres tables.

en général, j'ai aussi trouvé un support pour les clés primaires composites dans de nombreux cadres et les produits d'outillage d'être "inégal" au mieux et inexistant dans d'autres

26
répondu Steve Weet 2009-09-05 11:24:16

les clés composites sont difficiles à gérer et lentes à joindre. Puisque vous construisez un tableau sommaire, utilisez une clé de substitution (c.-à-d. une colonne auto-identification/identité). Laissez vos colonnes clés naturelles ici.

Cela a beaucoup d'autres avantages, aussi. Principalement, Si vous fusionnez avec une entreprise et ils ont une des mêmes sources, mais clés réutilisées, vous allez avoir des problèmes si vous ne sont pas à l'aide d'une clé de substitution.

C'est le plus largement reconnu meilleur pratique de l'entreposage de données (une entreprise beaucoup plus importante que ce que vous faites, mais toujours pertinente), et pour de bonnes raisons. Les substituts assurent l'intégrité des données et les jointures rapides. Vous pouvez être brûlé très rapidement avec les clés naturelles, donc restez loin d'eux comme un identificateur, et ne les utilisez que sur le processus d'importation.

12
répondu Eric 2009-09-05 11:29:06

vous avez l'obligation commerciale que la combinaison de ces deux attributs soit unique. Donc, vous devriez avoir un UNIQUE contrainte sur ces deux attributs. Si vous appelez ça UNIQUE contrainte "primaire" est vraiment juste une préférence, elle n'a pas beaucoup d'impact en dehors de la documentation.

La seule question est de savoir si vous ajoutez une colonne supplémentaire et le marque UNIQUE. La seule raison que je vois pour faire cela est la performance, qui est une raison.

personnellement, je n'aime pas l'approche qui consiste à transformer chaque base de données en un graphe, où les colonnes générées sont essentiellement des pointeurs et où vous ne faites que passer de l'un à l'autre. Je pense que jette tout de la grandeur d'un système relationnel. Si vous prenez du recul et que vous y réfléchissez, vous introduisez un tas de colonnes qui n'ont aucun sens pour votre entreprise, du tout. Vous pouvez être intéressé à mon blog liées.

8
répondu Jeff Davis 2009-09-05 17:10:25

je crois que les clés composites créent un modèle de données très naturel et descriptif. Mon expérience vient D'Oracle et je ne pense pas qu'il y ait de problèmes techniques lors de la création d'un composite PK. En fait, toute personne analysant le dictionnaire de données comprendrait immédiatement quelque chose au sujet de la table. Dans votre cas, il serait évident que chaque source_id uniques id_on_source.

l'utilisation des clés naturelles crée souvent un débat brûlant, mais les gens avec qui je travaille aiment les clés naturelles du point de vue d'un bon modèle de données.

6
répondu softveda 2009-09-05 11:42:49

à peu près la seule fois où j'utilise une clé primaire composite, c'est quand la partie haute de la clé est la clé d'une autre table. Par exemple, je pourrais créer une table OrderLineItem avec une clé primaire de OrderId + LineNumber. Comme beaucoup d'accès contre la table OrderLineItem seront " order join orderlineitem using (orderid)" ou une variante de cela, c'est souvent pratique. Il rend également facile en regardant des dumps de base de données pour comprendre ce que les articles de ligne sont connectés à ce ordre.

comme d'autres l'ont noté, les touches composites sont une douleur dans la plupart des autres circonstances parce que vos jointures doivent impliquer toutes les pièces. C'est plus à taper, ce qui signifie plus de possibilités d'erreurs, les requêtes sont plus lentes, etc.

les clés à deux parties ne sont pas mauvaises; je les fais assez souvent. J'hésite à utiliser une clé en trois parties. Plus que trois parties, je dirais, oublie ça.

dans votre exemple, je soupçonne qu'il y a peu à gagner en utilisant la clé composite. Juste inventer un nouveau numéro de séquence et laisser les clés source et source être des attributs ordinaires.

3
répondu Jay 2009-09-05 22:49:15

j'ai rencontré des problèmes en utilisant beaucoup de clés composites et donc je ne le recommande pas (plus bas), j'ai également trouvé qu'il y a des avantages dans une clé indépendante/de substitution (plutôt que naturelle) en essayant de faire reculer les erreurs de l'utilisateur. Le problème était que via un ensemble de relations, une table a joint deux tables où pour chaque partie de rangée du composite était le même (ce qui était approprié dans la 3ème forme normale - une comparaison entre deux parties d'un parent). J'ai dé-dupliqué cette partie du composite. relation dans la table de jointure (donc au lieu de parent1ID, other1ID, parent2ID, other2ID il y avait parentID, other1ID, other2ID) mais maintenant la relation ne pouvait pas mettre à jour les changements à la clé primaire, parce qu'elle a essayé de le faire deux fois via chaque route et a échoué au milieu.

2
répondu tommycrock 2011-11-16 10:05:19

certaines personnes vous recommandent d'utiliser un identifiant unique à l'échelle mondiale (GUID): fusionner la réplication et la réplication transactionnelle avec la mise à jour des abonnements utiliser des colonnes uniqueidentifier pour garantir que les lignes sont identifiées de façon unique à travers plusieurs copies de la table. Si la valeur est globalement unique lorsqu'elle est créée, alors vous n'avez pas besoin d'ajouter source_id pour la rendre unique.


bien qu'un uniqueid soit une bonne clé primaire, je suis d'accord qu'il est généralement mieux de utilisez une clé naturelle différente (pas nécessairement unique) comme votre indice de regroupement. Par exemple, si un ID unique est le PK qui identifie les employés, vous pourriez vouloir que l'index regroupé soit le ministère (si vos énoncés select récupèrent habituellement tous les employés au sein d'un ministère donné). Si vous voulez utiliser un unqiqueid comme indice clustered, voir le NEWSEQUENTIALID () fonction: Cela crée des valeurs séquentielles uniqueid, qui (étant séquentielles) ont un meilleur groupement performance.

1
répondu ChrisW 2009-09-05 12:20:56

L'ajout d'une colonne supplémentaire D'ID vous permettra d'appliquer deux contraintes d'unicité au lieu d'une.

L'utilisation de cette colonne D'ID supplémentaire comme clé étrangère dans d'autres tables de référencement, au lieu de la clé qui se présente naturellement, vous obligera à faire plus de jointures, à savoir dans tous les cas où vous avez besoin de la source originale plus ID_on_source avec les données de la table de référencement.

1
répondu 2009-09-05 16:51:57