web-dev-qa-db-fra.com

SQL - clé primaire de table plusieurs-à-plusieurs

Cette question se pose après avoir lu un commentaire dans cette question:

Conception de la base de données

Lorsque vous créez une table plusieurs-à-plusieurs, devez-vous créer une clé primaire composite sur les deux colonnes de clé étrangère, ou créer une clé primaire de substitution "ID" à incrémentation automatique, et simplement mettre des index sur vos deux colonnes FK (et peut-être une contrainte unique)? Quelles sont les implications sur les performances pour l'insertion de nouveaux enregistrements/réindexation dans chaque cas?

Fondamentalement, cela:

PartDevice
----------
PartID (PK/FK)
DeviceID (PK/FK)

contre ceci:

PartDevice
----------
ID (PK/auto-increment)
PartID (FK)
DeviceID (FK)

Le commentateur dit:

en faisant des deux identifiants le PK signifie que la table est triée physiquement sur le disque dans cet ordre. Donc, si nous insérons (Part1/Device1), (Part1/Device2), (Part2/Device3), alors (Part 1/Device3) la base de données devra séparer le tableau et insérer le dernier entre les entrées 2 et 3. Pour de nombreux enregistrements, cela devient très problématique car cela implique de mélanger des centaines, des milliers ou des millions d'enregistrements chaque fois qu'un est ajouté. En revanche, un PK à auto-incrémentation permet de clouer les nouveaux enregistrements jusqu'à la fin.

La raison pour laquelle je pose la question est parce que j'ai toujours été enclin à faire la clé primaire composite sans colonne de substitution automatique, mais je ne sais pas si la clé de substitution est réellement plus performante.

117
Andy White

Avec un simple mappage plusieurs-à-plusieurs en deux colonnes, je ne vois aucun avantage réel à avoir une clé de substitution. Avoir une clé primaire sur (col1,col2) est garanti unique (en supposant que votre col1 et col2 les valeurs des tables référencées sont uniques) et un index séparé sur (col2,col1) détectera les cas où l'ordre opposé s'exécuterait plus rapidement. Le substitut est une perte d'espace.

Vous n'aurez pas besoin d'index sur les colonnes individuelles car la table ne doit être utilisée que pour joindre les deux tables référencées ensemble.

Ce commentaire auquel vous faites référence dans la question ne vaut pas les électrons qu'il utilise, à mon avis. Il semble que l'auteur pense que la table est stockée dans un tableau plutôt que dans une structure arborescente multidirectionnelle extrêmement performante.

Pour commencer, il n'est jamais nécessaire de stocker ou d'obtenir le table trié, juste l'index. Et l'index ne sera pas stocké séquentiellement, il sera stocké de manière efficace pour pouvoir être récupéré rapidement.

De plus, la grande majorité des tables de base de données sont lues loin plus souvent qu'écrites. Cela rend tout ce que vous faites du côté de la sélection beaucoup plus pertinent que tout ce qui est du côté de l'insert.

77
paxdiablo

Aucune clé de substitution n'est nécessaire pour les tables de liens.

Un PK activé (col1, col2) et un autre index unique activé (col2, col1) est tout ce dont vous avez besoin

À moins que vous n'utilisiez un ORM qui ne peut pas faire face et dicte votre conception de base de données pour vous ...

Edit: J'ai répondu la même chose ici: SQL: Avez-vous besoin d'une clé primaire auto-incrémentielle pour les tables Many-Many?

18
gbn

Une clé primaire incrémentielle peut être nécessaire si la table est référencée. Il peut y avoir des détails dans la table plusieurs-à-plusieurs qui doivent être extraits d'une autre table à l'aide de la clé primaire incrémentielle.

par exemple

PartDevice
----------
ID (PK/auto-increment)
PartID (FK)
DeviceID (FK)
Other Details

Il est facile de tirer les "autres détails" en utilisant PartDevice.ID comme FK. Ainsi, l'utilisation d'une clé primaire incrémentielle est nécessaire.

12
Jronny

La façon la plus courte et la plus directe de répondre à votre question est de dire qu'il y aura un impact sur les performances si les deux tables que vous liez n'ont pas de clés primaires séquentielles. Comme vous l'avez indiqué/cité, l'index de la table de liens sera soit fragmenté, soit le SGBD travaillera plus dur pour insérer des enregistrements si la table de liens n'a pas sa propre clé primaire séquentielle. C'est la raison pour laquelle la plupart des gens mettent une clé primaire à incrémentation séquentielle sur les tables de liens.

6
Bernhard Hofmann

Il semble donc que si le seul travail consiste à lier les deux tables, le meilleur PK serait le PK à deux colonnes.

Mais s'il sert à d'autres fins, ajoutez un autre NDX en tant que PK avec des clés étrangères et un deuxième index unique.

Index ou PK est le meilleur moyen de s'assurer qu'il n'y a pas de doublons. PK permet à des outils comme Microsoft Management Studio d'effectuer une partie du travail (création de vues) pour vous

2
michael kosak