7
votes

Touche principale / clé en cluster pour les tables de jonction

Disons que nous avons une table de produits et une table de commande et un producteur (table de jonction).

Le producteur aura un productidit et une commande.
Dans la plupart de nos systèmes, ces tables ont également une colonne AutoNumber appelée ID.

Quelle est la meilleure pratique pour placer la clé primaire (et la clé en cluster)?

  • dois-je conserver la clé principale du champ ID et créer un index non clustered pour la paire de clé étrangère (Productible et Perchecid)

  • ou dois-je mettre la clé primaire de la paire de clé étrangère (productided et orderid) et mettre un index non clusterné sur la colonne ID (si nécessaire)

  • ou ... (remarque intelligente de l'un d'entre vous :))


0 commentaires

4 Réponses :


1
votes

Ceci semble être pour un système dynamique où de nombreuses commandes seront ajoutées. L'indice en cluster doit donc être sur votre colonne Autonumbered.

Vous pouvez indiquer la clé primaire et mettre un autre index unique sur la paire de colonnes. Ou, vous pouvez faire la paire de colonnes la clé primaire (mais non clustée).

Le choix de l'utilisation de la clé principale ou d'une clé d'index unique est à vous de vous. Mais je m'assurerais que celui qui est clustered est pour votre colonne auto-numériques.


2 commentaires

Je ne suis pas d'accord. La colonne AutoNumber n'a aucune signification, sauf "Ceci est la commande que les enregistrements ont été créés". Le cluster commandera les lignes par la clé de cluster. Aucune numérisation automatique «par ordre de création» n'est souvent pas la commande que vous interrogez la table. Très probablement, cette table sera utilisée dans une jointure contre les produits et les commandes en utilisant le produit et la commande. J'aurais une grappe pour la commande afin que la clé de cluster soit dans le même ordre que la table de conduite de la requête la plus commune, sinon vous gaspillez l'indice de cluster.


Je suppose que la question revient à quel point cette table est occupée? S'il y a beaucoup d'insertions, vous pourriez accéder à un état où la table doit être restructurée sur chaque insert. Cela ralentirait le système, en particulier avec une grande table. Avec l'indice en cluster sur le carburant automatique, cela ne se produit pas. L'autre index pourrait avoir un rembourrage pour donner une place supplémentaire pour éviter la restructuration.



6
votes

Je sais que ces mots pourraient vous faire grincer, mais "cela dépend".

Il est fort probable que vous souhaitiez que l'ordre soit basé sur le produit Producteur et / ou OrderID et non la colonne AutOnumber (Cherroplate), car le nombre automatique n'a pas de sens naturel dans votre base de données. Vous voulez probablement commander la table de jointure du même champ que la table des parents.

  1. Comprenez d'abord pourquoi et comment vous utilisez l'identifiant de la clé de substitution en premier lieu; Cela dictera souvent comment vous l'indiquez. je Supposons que vous utilisez la clé de substitution parce que vous utilisez certains Cadre qui fonctionne bien avec des clés de colonne unique. Si il n'y a pas raison spécifique de design, puis pour une table de jointure, je simplifierais le problème et simplement supprimer l'ID d'auto-numérisation, s'il ne fait aucun autre avantage. La clé principale devient la (Productible, OrderID). Si non, Vous devez au moins vous assurer que votre index sur le (productide, Orderid) tuple est unique pour préserver l'intégrité des données.

  2. Les index en cluster sont bons pour les scans / jointures séquentielles lorsque le La requête nécessite les résultats dans le même ordre que l'index est commandé. Donc, regardez vos habitudes d'accès, figurez par quelle (s) clé (s) vous fera des sélections / analyses de plusieurs lignes séquentielles, et par lesquelles clé Vous ferez un accès aléatoire et individuel et créerez le Index en cluster sur la clé Vous rechercherez la plupart et les non regroupés Index de clé sur la clé que vous utiliserez pour un accès aléatoire. Vous devez Choisissez l'un ou l'autre, car vous ne pouvez pas regrouper les deux.

    Remarque: Si vous avez des exigences contradictoires, il existe une technique ("astuce") qui peut aider. Si toutes les colonnes d'une requête sont trouvées dans un index, cette index est une table candidate pour le moteur de base de données à utiliser pour satisfaire aux exigences de la requête. Vous pouvez utiliser ce fait pour stocker des données dans plus d'une ordonnance, même si elles sont en conflit l'un de l'autre. Soyez juste au courant des avantages et des inconvénients d'ajouter plus de champs à un index et de prendre une décision consciente après la compréhension de la nature et de la fréquence des requêtes qui seront traitées.


0 commentaires

1
votes

Ma préférence a toujours été de créer un audiengle pour les clés primaires. Ensuite, je crée un index unique sur les deux clés étrangères afin qu'elles ne soient pas dupliquées.

La raison pour laquelle je le fais est parce que plus je normalise mes données, plus je dois utiliser les clés dans les jointures. Je me suis retrouvé avec des conceptions de six à sept niveaux profondes, et si j'utilise des touches qui coule d'un niveau à un autre, je pourrais potentiellement se retrouver avec une clé n ^ 2 dans la jointure.

Essayez de convaincre mes développeurs SQL d'utiliser tout cela pour une seule requête, et ils vont comme moi .

Je le garde simple.


3 commentaires

Pourquoi ajouter une colonne 3ème lorsque les tables liées utilisent déjà des colonnes automobiles? Inutile


Ne laissez pas les développeurs dicter le design simplement parce qu'ils sont trop paresseux pour écrire des jointures ou des points de vue. Les tables de liaison n'ont aucune entreprise ayant une colonne AutoNumber, comme indiqué déjà, car ils sont un détail de mise en œuvre qui ne devrait pas être évident. Vous ne devriez pas interroger ou exposer la table de liaison par elle-même, il fera toujours partie d'une jointure. Pensez à écrire une vue, laissez les développeurs utiliser la vue et la table de liaison ne sera jamais évidente.


@gbn et @mrjoltcola: la plupart des tables de jointure ont des attributs supplémentaires. Une table de commande peut avoir l'élémentPrice afin que les modifications apportées à la table d'éléments de recherche ne changent pas le prix de commande de la citation à l'envoi. Donc, je fais une ordonnance pour cette table. Lorsque cela se joint à la table de livraisonLocessionItems, j'ai une jointure de 2 touches au lieu d'une joindre à 1 clé. Lorsque je reviendrai avec les livraisfirmatioforitems, j'ai de nouveau une clé étrangère à 1 colonne au lieu de 8 cols ou plus pour les détails de l'expédition, les mécanismes de livraison et de signature. Faites cela pour toutes les tables de participation et gardez les choses uniformes.



3
votes

La réponse correcte et seule est:

  • clé primaire est ('orderid', 'productID')
  • Un autre index sur ("productid", 'orderid')
  • peut être regroupé, mais pk est par défaut

    parce que:

    • Vous n'avez pas besoin d'un index sur OrderId ou ProductID Seul: L'optimiseur utilisera l'un des index
    • vous utiliserez probablement la table "les deux" façons
    • Vous n'avez pas besoin d'une clé de substitution, car vous les avez déjà sur les tables liées. Donc, une 3ème colonnes gaspille de l'espace.

2 commentaires

J'ai lu que c'était considéré comme une mauvaise pratique pour ajouter des colonnes à partir de l'index clustered aux index non clusters: l'index en cluster est toujours ajouté à l'indice non en cluster. L'indice "Producteur" + 'orderid' n'aurait pas de sens?


@ZYPHRAX: L'ordre de colonne en fait un index complètement différent