2009-04-14 6 views
1

toutes mes tables ont un champ Id de quelque type (UserId, PostId, FooId, etc). Je fais habituellement ceci une clé primaire .Clé primaire de la base de données -> Un champ d'identité ET un champ de nom?

Une table que j'ai est appelée Countries. Il a

CountryId SMALLINT 
Name VARCHAR(100) -- Yes, english country names only, in this column. 
AndSomeOtherFields. 

Maintenant, je sais que le Name doit être unique. Tous les noms de pays sont uniques. Est-il bon/mauvais/ru-roh si je fais le PrimaryKey == CountryId ASCetName ASC?

Si c'est bon, quelqu'un peut-il expliquer pourquoi c'est mieux, que le Id étant le PK? Est-ce juste que cela garantit l'intégrité des données (par exemple, pas deux noms de pays existant dans le tableau). Si c'est mauvais .. pourquoi?

merci bien.

+0

#Dupliquer * http://stackoverflow.com/questions/166750/should-i-have-a-dedicated-primary-key-field * http://stackoverflow.com/questions/695325/should-i -use-natural-identity-columns-without-guid Et c'est juste ceux que j'ai pu voir sur la droite, cette question a été posée plusieurs fois. – cgp

Répondre

6

La création de la clé primaire à la fois CountryIdetName ne garantit pas que les noms sont uniques. Il s'assure simplement que chaque CountryId - Namela paire est unique, et évidemment CountryId est déjà unique, étant un "ID". Ainsi, vous pouvez toujours avoir, par exemple, 1-US et 19-US, car les paires sont uniques. La seule raison d'en faire à la fois la clé primaire est si vous exécuterez fréquemment des requêtes où CountryId et Name sont utilisés dans la clause Where. La clé primaire par défaut crée un index clusterisé, qui trie physiquement la table, de sorte qu'elle recherche très rapidement les lignes par rapport à ces prédicats.

Un autre point important à soulever est que dans votre exemple particulier, vous stockez une liste de pays qui est a) très courte et b) ne change pas beaucoup. Lookups contre cette table vont être extrêmement rapide, peu importe ce que vous faites. Même si SQL Server doit effectuer une analyse de table complète à chaque fois, vous ne le remarquerez probablement pas. Vous n'avez pas à vous soucier de la fragmentation de la page. Vous pouvez simplement ignorer la colonne ID et utiliser le Name comme clé primaire.

Ou, si vous souhaitez conserver un ID mais également imposer l'unicité des noms de pays, vous pouvez put a Unique Constraint dans la colonne Nom.

Il est difficile de couvrir le problème des clés primaires, des index clusterisés et des index en général, de façon trop approfondie dans une seule réponse.Voici quelques bonnes ressources pour commencer:

+0

"La clé primaire trie physiquement la table" Pas sur mon SGBDR ce n'est pas le cas; cela doit être fait explicitement, et peut être fait pour n'importe quel index. Sinon, c'est un conseil solide. – kquinn

+0

@kquinn merci, a ajouté cette clarification. Je voulais dire qu'au niveau débutant (qui semble être où nous sommes ici) la clé primaire vient automatiquement avec un index clusterisé. –

+0

Merci :) Je n'aurais pas dû utiliser une table de pays comme exemple parce que c'est une petite table. La question était en quelque sorte ciblée sur n'importe quelle table de taille. Mais j'ai l'impression que ça a été affilé pas moins :) –

1

Avoir le nom devenu le PK n'est pas toujours la meilleure solution, je crois CountryId est assez comme PK pour votre table, mais si le nom est un champ que vous utiliserez beaucoup pour interroger avec par exemple: sélectionne, joint, vous devez indexer ce champ ainsi un filtrage des requêtes en ce domaine permettra d'améliorer sa vitesse beaucoup

bonne chance :)

0

La seule chose à laquelle je peux penser est assez évidente: votre index sera un peu plus grand. Cela dit, ce n'est pas un gros problème car votre table ne sera que pour stocker des pays. Mais, pourquoi voudriez-vous un tel indice? Si vous triez par CountryId, puis en le triant par Nom comme deuxième champ est inutile. Vous obtiendrez toujours le même ordre.

Une chose qui est vraiment une mauvaise idée est d'avoir des clés étrangères pointant vers une grande clé primaire, donc, assurez-vous que si vous utilisez cette clé primaire, vos clés étrangères pointant vers pays utilisent encore que CountryId colonne.

0

Les noms de pays ont été connus pour changer sans altérer autrement l'identité du pays. Cela suggère que le nom ne devrait pas faire partie du PK.

0

Si vous devez appliquer l'unicité, utilisez une contrainte.

1

Créez un index unique sur la colonne Name.

Questions connexes