Cette question se pose après la lecture d'un commentaire dans cette question:
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 «ID» de substitution à 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 de l'insertion de nouveaux enregistrements / de la réindexation dans chaque cas?
Fondamentalement, ceci:
PartDevice
----------
PartID (PK/FK)
DeviceID (PK/FK)
vs ceci:
PartDevice
----------
ID (PK/auto-increment)
PartID (FK)
DeviceID (FK)
Le commentateur dit:
faire des deux ID le PK signifie que la table est physiquement triée 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 la table et insérer la dernière entre les entrées 2 et 3. Pour beaucoup d'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 aux nouveaux enregistrements d'être cloués à la fin.
La raison pour laquelle je pose la question est que j'ai toujours été enclin à utiliser la clé primaire composite sans colonne d'incrémentation automatique de substitution, mais je ne suis pas sûr que la clé de substitution soit réellement plus performante.
la source
Réponses:
Avec un simple mappage plusieurs à plusieurs à 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 vos valeurscol1
etcol2
dans les 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 un gaspillage 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, à mon avis, les électrons qu'il utilise. Il semble que l'auteur pense que la table est stockée dans un tableau plutôt que dans une arborescence multi-voies équilibrée extrêmement performante.
Pour commencer, il n'est jamais nécessaire de stocker ou d'obtenir à la table triée, 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 beaucoup plus souvent qu'écrites. Cela rend tout ce que vous faites du côté de la sélection beaucoup plus pertinent que tout ce que vous faites du côté de l'insert.
la source
insert
cela importera si cela est fait des milliers de fois par heure. Vous ne pouvez pas simplement l'ignorer simplement parce que le rapport deinsert
àselect
est <1. Dans ce cas, un client se soucie du temps qu'il faut pour passer une commande.Aucune clé de substitution n'est nécessaire pour les tables de liens.
Un PK sur (col1, col2) et un autre index unique sur (col2, col1) est tout ce dont vous avez besoin
Sauf si vous utilisez un ORM qui ne peut pas faire face et qui vous dicte la conception de votre base de données ...
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?
la source
(col2, col1)
n'est pas(col1, col2)
. Le PK de(col1, col2)
peut ne pas convenir à toutes les requêtes et générer des analyses, donc avoir l'inverse de cela améliore les performances car il permet de rechercher où col2 est meilleur. Par exemple, la validation FK lorsque la table avec col2 a une suppression. La table enfant smuts être vérifiéeUne 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
Il est facile d'extraire les «Autres détails» en utilisant PartDevice.ID comme FK. Ainsi, l'utilisation d'une clé primaire incrémentielle est nécessaire.
la source
La manière 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 dit / cité, l'index de la table de liens deviendra fragmenté ou le SGBD travaillera plus dur pour insérer des enregistrements si la table de liens ne possède 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.
la source
Il semble donc que si le seul travail consiste à lier les deux tables, le meilleur PK serait le PK à deux colonnes.
Mais si cela sert à d'autres fins, ajoutez un autre NDX en tant que PK avec une clé étrangère et un deuxième index unique.
L'index ou PK est le meilleur moyen de s'assurer qu'il n'y a pas de doublons. PK laisse des outils comme Microsoft Management Studio faire une partie du travail (création de vues) pour vous
la source