41 votes

Tables sans clé primaire

J'ai plusieurs tables dont le seul et unique de données est un type uniqueidentifier (Guid) de la colonne. Parce que les guid sont non-séquentiel (et ils sont à côté client généré donc je ne peux pas utiliser newsequentialid()), j'ai fait un non-primaire, index non ordonné en clusters sur ce champ ID plutôt que de donner les tables de un cluster de clé primaire.

Je me demandais ce que les conséquences de performance sont pour cette approche. J'ai vu certaines personnes suggèrent que les tables doivent avoir une auto-incrémentation ("identité") int comme un cluster de clé primaire même si il n'a pas de sens, car cela signifie que le moteur de base de données elle-même pouvez utiliser cette valeur pour chercher rapidement une ligne au lieu d'avoir à utiliser un signet.

Ma base de données de fusion est répliqué sur un tas de serveurs, donc j'ai évité de l'identité int colonnes comme ils sont un peu poilu pour obtenir le droit dans la réplication.

Quelles sont vos pensées? Devrait tables des clés primaires? Ou est-ce ok pour ne pas avoir des index en cluster si il n'y a pas judicieux des colonnes de l'index de cette façon?

33voto

JeremiahClark Points 3020

Lorsque vous traitez avec des index, vous devez déterminer ce que votre table va être utilisé pour. Si vous êtes d'abord l'insertion de 1000 lignes une seconde et ne fais pas de l'interrogation, puis un index cluster est un coup à la performance. Si vous faites 1000 requêtes par seconde, puis de ne pas avoir un indice de conduire à une très mauvaise performance. La meilleure chose à faire lorsque vous essayez de paramétrer les requêtes/index consiste à utiliser l'Analyseur de Plan de Requête et le générateur de profils SQL dans SQL Server. Cela va vous montrer où vous êtes en cours d'exécution dans de coûteuses analyses de table ou de performance-bloquants.

Comme pour le GUID vs argument ID, vous pouvez trouver des gens en ligne qui ne jurent que par les deux. J'ai toujours été appris à utiliser le Guid à moins que j'ai une très bonne raison de ne pas. Jeff a un bon post qui parle des raisons pour l'utilisation de Guid: http://www.codinghorror.com/blog/archives/000817.html.

Comme avec la plupart des rien de développement liés, si vous êtes à la recherche pour améliorer les performances il n'y a pas une seule bonne réponse. Cela dépend vraiment de ce que vous essayez d'accomplir et la façon dont vous êtes à la mise en œuvre de la solution. La seule vraie réponse est de tester, tester et tester à nouveau contre des mesures de rendement pour s'assurer que vous respectez vos objectifs.

[Modifier] @Matt, après avoir fait un peu plus de recherche sur le GUID/ID débat, je suis tombé sur ce post. Comme je l'ai mentionné avant, il n'y a pas une vrai bonne ou de mauvaise réponse. Il dépend de vos besoins de mise en œuvre. Mais ce sont des raisons valables d'utiliser Guid comme clé primaire:

Par exemple, il existe un problème connu comme un "hotspot", où certaines pages de données dans une table est relativement élevée de la monnaie de contention. Fondamentalement, ce qui se passe est la plupart du trafic sur une table (et donc au niveau de la page des verrous) se produit sur une petite zone de la table, vers la fin. Les nouveaux enregistrements toujours aller à ce hotspot, car l'IDENTITÉ est un numéro séquentiel du générateur. Ces inserts sont gênants car ils nécessitent Exlusive verrouillage de page sur la page, ils sont ajoutés à (hotspot). Effectivement cela sérialise tous les inserts à une table grâce à la page mécanisme de verrouillage. NewID() d'autre part ne souffre pas de points chauds. Les valeurs générées à l'aide de la fonction NewID() ne sont séquentielles pour de courtes rafales de plaquettes (où la fonction est appelée, très vite, comme lors d'un multi-ligne insert), ce qui provoque les lignes insérées à se propager de façon aléatoire dans les données de la table des pages au lieu de tout à la fin éliminant ainsi un point d'accès à partir de plaquettes.

Aussi, parce que les plaquettes sont distribuées de façon aléatoire, la chance de fractionnements de page est considérablement réduit. Alors qu'un fractionnement de la page ici, et il n'est pas trop mauvais, les effets ne s'additionnent rapidement. Avec l'IDENTITÉ, la page du Facteur de Remplissage est assez inutile comme un mécanisme de réglage et peut ainsi être fixée à 100% - les lignes ne seront jamais être inséré dans n'importe quelle page, mais le dernier. Avec NewID(), vous pouvez réellement faire de l'utilisation de Facteur de Remplissage de performance activation de l'outil. Vous pouvez définir le Facteur de Remplissage à un niveau qui se rapproche de volume estimé de la croissance de l'indice des reconstructions, et ensuite planifier la reconstruction pendant les heures creuses à l'aide de la commande dbcc réindexer. Ce efficacement les retards les performances de fractionnements de page jusqu'à ce que les heures creuses.

Même si vous pensez que vous pourriez avoir besoin pour activer la réplication de la table en question, alors vous pourriez aussi bien faire de la PK de type uniqueidentifier drapeau et le champ guid comme ROWGUIDCOL. La réplication nécessite un unique évalués champ guid avec cet attribut, et il va ajouter un si il n'en existe aucun. Si un champ existe, alors il suffit d'utiliser l'un des thats là.

Encore un autre avantage énorme pour l'utilisation de Guid pour PKs est le fait que la valeur est en effet garanti unique - et pas seulement parmi toutes les valeurs générées par ce serveur, mais toutes les valeurs générées par tous les ordinateurs - qu'il s'agisse de votre serveur de base de données, serveur web, serveur d'application, ou de l'ordinateur client. À peu près chaque langue moderne a la capacité de générer un guid valide maintenant - en .NET, vous pouvez utiliser le Système.Guid.NewGuid. Ce qui est TRÈS pratique lorsque vous traitez avec cache maître-détail ensembles de données en particulier. Vous n'avez pas à employer fou temporaire de dispositifs de verrouillage juste de relier vos documents avant qu'ils ne soient commis. Vous venez de récupérer un parfaitement valide nouveau Guid du système d'exploitation pour chaque nouvel enregistrement permanent de la valeur de la clé au moment de la création de l'enregistrement.

http://forums.asp.net/t/264350.aspx

7voto

Mark Harrison Points 77152

La clé primaire sert trois objectifs:

  • indique que la colonne(s) doit être unique
  • indique que la colonne(s) doit être non null
  • document à l'intention que c'est l'identificateur unique de la ligne

Les deux premiers peuvent être spécifiés dans beaucoup de façons, comme vous l'avez déjà fait.

La troisième raison est la bonne:

  • pour les humains, de sorte qu'ils peuvent facilement voir votre intention
  • pour l'ordinateur, donc un programme qui pourrait les comparer ou de traiter votre table peut interroger la base de données pour la table de la clé primaire.

Une clé primaire ne doit pas être une incrémentation automatique du numéro de champ, donc je dirais que c'est une bonne idée de préciser votre guid colonne comme clé primaire.

7voto

Rob Farley Points 9042

Juste de sauter dans, parce que Matt est amorcée un peu de moi.

Vous devez comprendre que même si un index cluster est mis sur la clé primaire d'une table par défaut, que les deux notions sont distinctes et doivent être considérés séparément. Un CIX indique la façon dont les données sont stockées et visé par NCIXs, alors que le PK offre un caractère unique pour chaque ligne afin de satisfaire les exigences LOGIQUES de la table.

Une table sans CIX est juste un Tas. Une table sans un PK est souvent considéré comme "pas une table". Il est préférable d'obtenir une compréhension à la fois de la PK et de la BRIDE de concepts séparément, de sorte que vous pouvez prendre des décisions judicieuses en conception de base de données.

Rob

3voto

zvolkov Points 9673

Personne n'a répondu libellé de la question: quels sont les avantages et les inconvénients d'une table avec PAS de PK, NI d'un index CLUSTER. À mon avis, si vous optimisez les plus rapides pour les inserts (notamment incrémentaux en vrac-insérer, par exemple lorsque vous vous charger en masse des données dans une table non vide), une telle table: avec PAS d'index cluster, PAS de contraintes, PAS de Clés Étrangères, AUCUN Défaut et PAS de Clé Primaire dans une base de données avec le Modèle de Récupération Simple, est la meilleure. Maintenant, si jamais vous voulez interroger ce tableau (par opposition à la numérisation dans son intégralité), vous pouvez ajouter un non-cluster non-index uniques en tant que de besoin, mais de les garder à un minimum.

0voto

Matthew Schinckel Points 15596

Une Clé Primaire n'a pas besoin d'être un autoincrementing le terrain, dans de nombreux cas, cela signifie juste que vous êtes compliquer votre structure de la table.

Au lieu de cela, une Clé Primaire doit être au minimum de la collection d'attributs (notez que la plupart des SGBD permettra une clé primaire composite) qui identifie de manière unique un tuple.

En termes techniques, il convient de le domaine que tous les autres domaines dans le tuple est entièrement fonctionnellement dépendant. (Si ce n'est pas vous pourriez avoir besoin de normaliser).

Dans la pratique, les problèmes de performance peut signifier que vous fusionner des tables, et d'utiliser une incrémentation de champ, mais il me semble quelque chose au sujet de optimisation prématurée est diabolique...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X