2009-04-14 3 views
1

Alle meine Tabellen haben ein Id Feld eines Typs (UserId, PostId, FooId, etc). Ich mache dies normalerweise zu einem Primärschlüssel.Primärer Datenbankschlüssel -> Ein Identitätsfeld UND ein Namensfeld?

Eine Tabelle, die ich habe, heißt Countries. Es hat

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

Nun, ich weiß die Name eindeutig sein. Alle Ländernamen sind einzigartig. Ist es gut/schlecht/ru-roh, wenn ich die PrimaryKey == CountryId ASCundName ASC mache?

Wenn es gut ist, kann jemand erklären, warum es besser ist, als nur die Id ist die PK? Ist es nur, dass es die Datenintegrität gewährleistet (z. B. keine zwei Ländernamen in der Tabelle vorhanden sind). Wenn es schlecht ist ... warum?

danke nett.

+0

#Duplicate * 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 Und das sind nur die, die ich auf der rechten Seite sehen konnte, diese Frage wurde schon einige Male gestellt. – cgp

Antwort

6

machen den Primärschlüssel beide CountryIdundName stellt nicht sicher, die Namen eindeutig sind. Es stellt nur sicher, dass jedes CountryId - NamePaar einzigartig ist, und offensichtlich ist CountryId bereits einzigartig, eine "ID". So könnte man zB noch und 19-US haben, da die Paare eindeutig sind.

Der einzige Grund, sie zum Primärschlüssel zu machen, besteht darin, dass Sie häufig Abfragen ausführen, bei denen sowohl CountryId als auch Name in der Where-Klausel verwendet werden. Der Primärschlüssel standardmäßig erstellt einen gruppierten Index, der die Tabelle physisch sortiert, so dass die Suche nach Zeilen mit diesen Prädikaten sehr schnell erfolgt.

Ein weiterer wichtiger Punkt ist, dass Sie in Ihrem speziellen Beispiel eine Liste von Ländern speichern, die a) sehr kurz ist und b) sich nicht viel ändert. Lookups gegen diese Tabelle werden extrem schnell sein, egal was du tust. Selbst wenn SQL Server jedes Mal einen vollständigen Tabellenscan durchführen muss, werden Sie es wahrscheinlich nicht einmal bemerken. Sie müssen sich nicht um eine Seitenfragmentierung kümmern. Sie könnten einfach die ID-Spalte überspringen und die Name als Primärschlüssel verwenden.

Oder, wenn Sie eine ID behalten möchten, aber auch die Eindeutigkeit nur der Ländernamen erzwingen möchten, können Sie put a Unique Constraint in der Spalte Name eingeben.

Es ist schwierig, das Problem von Primärschlüsseln, gruppierten Indizes und Indizes im Allgemeinen in zu viel Tiefe in einer einzigen Antwort zu behandeln.Hier sind ein paar gute Ressourcen, um loszulegen:

+0

"Der Primärschlüssel sortiert die Tabelle physikalisch" Nicht auf meinem RDBMS ist es nicht; das muss explizit gemacht werden und kann für jeden Index gemacht werden. Ansonsten ist das ein solider Rat. – kquinn

+0

@kquinn danke, fügte diese Klarstellung hinzu. Ich meinte, dass auf der Anfängerstufe (die hier zu sein scheint) der Primärschlüssel automatisch auch einen Clustered-Index enthält. –

+0

Danke :) Ich hätte keine Länder Tabelle als mein Beispiel verwenden sollen, weil es ein kleiner Tisch ist. Die Frage war gegen eine beliebige Tabelle gerichtet. Aber ich fühle mich, als wäre es trotzdem erledigt :) –

1

den Namen der PK werden zu haben ist nicht immer die beste Lösung, glaube ich CountryId genug ist, als PK für Ihre Tabelle, aber wenn Name ein Feld ist, das Sie viel verwenden, um mit ie zu suchen: wählt, Joins, sollten Sie dieses Feld auf diese Weise indexieren eine Abfrage, die durch dieses Feld Filtern verbessert

viel Glück :)

0

Das einzige, was ich mir vorstellen kann, ist ziemlich offensichtlich: Ihr Index wird ein wenig größer sein. Wenn das so ist, ist das nicht so ein großer Deal, da Ihr Tisch nur Länder speichern wird. Aber warum möchten Sie einen solchen Index? Wenn Sie nach CountryId sortieren, dann sortieren Sie nach Name als zweites Feld ist sinnlos. Sie werden immer die gleiche Reihenfolge erhalten.

Eine Sache, die wirklich eine schlechte Idee ist Fremdschlüssel haben zu einem großen Primärschlüssel zeigt, so stellen Sie sicher, dass, wenn Sie, dass Primärschlüssel, Ihre Fremdschlüssel Länder zeigen verwenden immer noch nur countryid Säule.

0

Es ist bekannt, dass sich die Namen von Ländern ändern, ohne die Identität des Landes zu ändern. Das deutet darauf hin, dass der Name nicht Teil des PK sein sollte.

0

Wenn Sie die Eindeutigkeit erzwingen müssen, verwenden Sie eine Einschränkung.

1

Erstellen Sie einen eindeutigen Index auf der Spalte Name.