Tak, absolutnie istnieją negatywne konsekwencje używania łańcucha zamiast typu liczbowego dla klucza podstawowego, a tym bardziej, jeśli PK jest klastrowany (co w rzeczywistości tak jest w twoim przypadku). Jednak stopień, w jakim widzisz efekt (y) użycia pola ciągu, jest funkcją a) liczby wierszy w tej tabeli oraz b) liczby wierszy w innych tabelach z kluczem obcym dla tej PK. Jeśli masz tylko 10 tys. Wierszy w tej tabeli i 100 tys. Wierszy w kilku innych tabelach, które FK do tej tabeli za pośrednictwem tego pola, być może nie będzie to tak zauważalne. Ale te efekty z pewnością stają się bardziej zauważalne wraz ze wzrostem liczby wierszy.
Należy wziąć pod uwagę, że pola w indeksie klastrowanym są przenoszone do indeksów nieklastrowanych. Więc nie patrzysz tylko na 40 bajtów na wiersz, ale (40 * jakiś_numer) bajtów. I w dowolnych tabelach FK masz te same 40 bajtów w wierszu, a częściej w tym polu będzie indeks nieklastrowany, ponieważ jest on używany w połączeniach, więc teraz jest naprawdę podwojony w tabelach, do których FK ten. Jeśli ktoś uważa, że 40 bajtów * 1 milion wierszy * 10 jego kopii nie ma się czym martwić, zobacz mój artykuł Dysk jest tani! ORLY? które wyszczególniają wszystkie (lub przynajmniej większość) obszary, na które wpływa ta decyzja.
Inną rzeczą do rozważenia jest to, że filtrowanie i sortowanie ciągów, szczególnie gdy nie jest używane sortowanie binarne (zakładam, że używasz domyślnej bazy danych, która zazwyczaj nie rozróżnia wielkości liter) jest znacznie mniej wydajne (tj. Trwa dłużej) niż przy użyciu INT
/ BIGINT
. Wpływa to na wszystkie zapytania filtrujące / łączące / sortujące w tym polu.
Dlatego użycie czegoś podobnego CHAR(5)
byłoby prawdopodobnie OK dla klastrowanego PK, ale głównie, jeśli zostało to również zdefiniowane za pomocą COLLATE Latin1_General_100_BIN2
(lub czegoś takiego).
I czy wartość [CODE]
kiedykolwiek może się zmienić? Jeśli tak, to jeszcze więcej powodów, aby nie używać go jako PK (nawet jeśli ustawisz FK na ON UPDATE CASCADE
). Jeśli to nie może lub nigdy się nie zmieni, to dobrze, ale wciąż istnieje wystarczający powód, aby nie używać go jako PK.
Oczywiście pytanie może być niepoprawnie sformułowane, ponieważ wydaje się, że masz już to pole w swoim PK.
Niezależnie od tego, jak dotąd najlepszą opcją jest użycie [ID_CODE]
jako klastrowanego PK, użycie tego pola w powiązanych tabelach jako FK i zachowanie go [CODE]
jako UNIQUE INDEX
(co oznacza, że jest to „klucz zastępczy”).
Aktualizacja
Trochę więcej informacji na podstawie tego pytania w komentarzu do tej odpowiedzi:
Czy [ID_CODE], jako PODSTAWOWY KLUCZ, jest najlepszą opcją, jeśli używam kolumny [KOD] do wyszukiwania w tabeli?
Wszystko zależy od bardzo wielu czynników, z których niektóre już wspomniałem, ale powtórzę:
Klucz podstawowy to sposób identyfikacji pojedynczego wiersza, niezależnie od tego, czy jest do niego przypisany jakikolwiek klucz obcy. Sposób, w jaki system wewnętrznie identyfikuje wiersz, jest związany, ale niekoniecznie taki sam, z tym, jak użytkownicy identyfikują się / ten wiersz. Każda kolumna NOT NULL z unikatowymi danymi może działać, ale należy wziąć pod uwagę kwestie praktyczne, zwłaszcza jeśli PK są w rzeczywistości przywołane przez dowolne FK. Na przykład identyfikatory GUID są unikalne i niektórzy ludzie naprawdę lubią ich używać z różnych powodów, ale są dość złe dla indeksów klastrowych ( NEWSEQUENTIALID
jest lepszy, ale nie idealny). Z drugiej strony, identyfikatory GUID są w porządku jako klucze alternatywne i są używane przez aplikację do wyszukiwania wiersza, ale JOIN są nadal wykonywane przy użyciu INT (lub podobnej) PK.
Do tej pory nie powiedziałeś nam, jak [CODE]
pole wpasowuje się w system ze wszystkich stron, poza tym, że wspomniałeś, że tak właśnie wyglądasz wiersze, ale czy to dotyczy wszystkich zapytań czy tylko niektórych? W związku z tym:
Tej decyzji nie można podjąć wyłącznie na pytanie „NVARCHAR tak czy nie?”. Jeszcze raz powiem, że ogólnie rzecz biorąc nie uważam tego za dobry pomysł, ale z pewnością są chwile, kiedy jest w porządku. Biorąc pod uwagę tak małą liczbę pól w tej tabeli, jest mało prawdopodobne, że istnieje więcej lub przynajmniej niewiele indeksów. Więc może być dobrze, tak czy inaczej, [CODE]
jako indeks klastrowany. A jeśli żadne inne tabele nie odwołują się do tej tabeli, może być również w porządku, czyniąc ją PK. Ale jeśli inne tabele odwołują się do tej tabeli, wybrałbym [ID_CODE]
pole jako PK, nawet jeśli nie jest klastrowane.