Jak ci się podobają klucze główne? [Zamknięte]


88

W dość ożywionej dyskusji w moim zespole zmuszono mnie do zastanowienia się, co większość ludzi lubi jako klucze główne. Mieliśmy następujące grupy:

  1. Int / BigInt, które autoincrement są wystarczająco dobre klucze podstawowe.
  2. Klucz podstawowy powinien zawierać co najmniej 3 kolumny.
  3. Identyfikator, identyfikator GUID i identyfikatory wierszy czytelne dla człowieka powinny być traktowane inaczej.

Jakie jest najlepsze podejście dla PK? Byłoby wspaniale, gdybyś mógł uzasadnić swoją opinię. Czy jest lepsze podejście niż powyższe?

EDYCJA: Czy ktoś ma prostą próbkę / algorytm do generowania czytelnych dla człowieka identyfikatorów dla wierszy, które dobrze się skalują?


1
Ponieważ jest to subiektywne, powinno to być wiki społeczności
John Sheehan

2
„Klucz podstawowy powinien zawierać co najmniej 3 kolumny”? Co to znaczy? Czy możesz podać dalsze definicje? A może to część # 3?
S.Lott

@ PK(NEWID(),NEWID(),NEWID())

@pst: Dlaczego jest to wymóg? Dlaczego w PK muszą być trzy kolumny? Dlaczego jeden lub cztery?
S.Lott,

Widziałem trzykolumnowe PK wyglądające jak ... LocalID (Auto inkrementacja int), GlobalID (GUID), ForeignId (klucz obcy jak RolesType), itp. LocalID + ForiegnId może być kombinacją klawiszy złożonych. Przewodnik jest używany do innych witryn / usług. Osobiście nie zrobiłbym tego, po prostu użyłbym Guid + ForiegnId.
Jerad,

Odpowiedzi:


77

Jeśli zamierzasz wykonywać jakąkolwiek synchronizację między bazami danych z czasami połączonymi aplikacjami, powinieneś używać identyfikatorów GUID dla kluczy głównych. Jest to trochę uciążliwe przy debugowaniu, więc poza tym przypadkiem mam tendencję do trzymania się ints tej autoinkrementacji.

Wartości domyślne autoincrement powinny być domyślne, a ich nieużywanie powinno być uzasadnione.


3
Identyfikator GUID nie jest konieczny, po prostu zmień krok na 10 lub 20 lub na dowolną liczbę serwerów, z którymi prawdopodobnie będziesz musiał zsynchronizować się w przyszłości.
Robert C. Barth

44
Co najmniej w 90% przypadków identyfikator GUID nie jest potrzebny i zajmuje miejsce.
Jonathan Leffler

8
Naprawdę uważam, że identyfikatory GUID to przesada. Nigdy, przenigdy nie potrzebowałem identyfikatorów GUID jako moich kluczy podstawowych.
Cyril Gupta,

7
Lub zamiast marnować miejsce i ryzykować kolizję z identyfikatorem GUID, utwórz klucz złożony z oryginalnego klucza podstawowego i małego identyfikatora, w którym mały identyfikator jest inny dla każdego źródła synchronizacji.
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

5
Sklep, w którym pracowałem, używał identyfikatorów GUID do wszystkiego, nawet jeśli były dostępne identyfikatory publiczne, takie jak kody krajów lub języków ISO. I nawet jeśli wartość logiczna lub CHAR(1)wystarczyłaby, na przykład sex. Nie trzeba dodawać, że praca z tym była koszmarem.
Lumi

56

Nie widzę odpowiedzi, która wskazuje (co uważam za) naprawdę fundamentalną kwestię - mianowicie, że klucz podstawowy gwarantuje, że nie otrzymasz dwóch wpisów w tabeli dla tej samej encji ze świata rzeczywistego (jak modelowane w bazie danych). Ta obserwacja pomaga ustalić, które opcje są dobre, a jakie złe dla klucza podstawowego.

Na przykład w tabeli nazw i kodów stanów (USA) nazwa lub kod mogą być kluczem podstawowym - stanowią one dwa różne klucze kandydujące, a jeden z nich (zwykle krótszy - kod) jest wybierany jako klucz podstawowy. W teorii zależności funkcjonalnych (i zależności sprzężonych - od 1NF do 5NF - to klucze kandydujące są kluczowe, a nie klucz podstawowy.

Dla kontrprzykładu imiona ludzkie generalnie są złym wyborem dla klucza podstawowego. Jest wielu ludzi, którzy nazywają się „John Smith” lub mają inne podobne imiona; nawet biorąc pod uwagę drugie imię (pamiętaj: nie każdy je ma - na przykład ja nie), istnieje wiele możliwości powielania. W rezultacie ludzie nie używają nazw jako kluczy podstawowych. Wymyślają sztuczne klucze, takie jak numer ubezpieczenia społecznego (SSN) lub numer pracownika, i używają ich do wyznaczenia osoby.

Idealny klucz główny jest krótki, niepowtarzalny, niezapomniany i naturalny. Wyjątkowość tych cech jest obowiązkowa; reszta musi się zgiąć, biorąc pod uwagę ograniczenia rzeczywistych danych.

Jeśli chodzi o określenie klucza podstawowego danej tabeli, musisz przyjrzeć się, co ta tabela reprezentuje. Jaki zestaw lub zestawy wartości kolumn w tabeli jednoznacznie identyfikuje każdy wiersz w tabeli? To są klucze kandydatów. Teraz, jeśli każdy klucz kandydujący składa się z 4 lub 5 kolumn, możesz zdecydować, że są one zbyt niezdarne, aby utworzyć dobry klucz podstawowy (głównie ze względu na krótkość). W takich okolicznościach możesz wprowadzić klucz zastępczy - sztucznie wygenerowaną liczbę. Bardzo często (ale nie zawsze) prosta 32-bitowa liczba całkowita jest wystarczająca dla klucza zastępczego. Następnie wyznaczasz ten klucz zastępczy jako klucz podstawowy.

Jednak nadal musisz upewnić się, że inne klucze kandydujące (ponieważ klucz zastępczy jest również kluczem kandydującym, a także wybrany klucz podstawowy) są utrzymywane jako niepowtarzalny identyfikator - zwykle poprzez umieszczenie unikalnego ograniczenia na tych zestawach kolumn.

Czasami ludziom trudno jest zidentyfikować, co sprawia, że ​​wiersz jest wyjątkowy, ale powinno być coś do zrobienia, ponieważ zwykłe powtórzenie informacji nie czyni jej bardziej prawdziwą. A jeśli nie jesteś ostrożny i otrzymujesz dwa (lub więcej) wiersze rzekomo przechowujące te same informacje, a następnie musisz zaktualizować informacje, istnieje niebezpieczeństwo (szczególnie jeśli używasz kursorów), że zaktualizujesz tylko jeden wiersz zamiast każdego wiersza, więc wiersze są niezsynchronizowane i nikt nie wie, który wiersz zawiera poprawne informacje.

Pod pewnymi względami jest to dość ostry pogląd.

Nie mam szczególnego problemu z używaniem GUID, gdy są potrzebne, ale są one zwykle duże (jak w przypadku 16-64 bajtów) i są używane zbyt często. Bardzo często wystarczyłaby idealnie dobra 4-bajtowa wartość. Użycie identyfikatora GUID, w którym wystarczyłaby 4-bajtowa wartość, marnuje miejsce na dysku i spowalnia nawet indeksowany dostęp do danych, ponieważ na stronę indeksową przypada mniej wartości, więc indeks będzie głębszy i trzeba będzie odczytać więcej stron, aby dostać się do Informacja.


10
Jeśli chodzi o twoją próbkę z nazwami stanów w USA, wolałbym oddzielny klucz zastępczy, po prostu dlatego, że kody są czymś poza twoją kontrolą. Jeśli z jakiegoś powodu się zmienią, pojawi się problem.
Dirk Vollmar

1
(ciąg dalszy) Na przykład w latach 90-tych po zjednoczeniu Niemcy zastąpiły 4-cyfrowy system kodów pocztowych systemem 5-cyfrowym.
Dirk Vollmar

@divo: Jestem zdecydowanym zwolennikiem sztucznych / zastępczych kluczy, ale nawet ja nie widzę zmiany 4-cyfrowego na 5-cyfrowego kodu pocztowego jako dobrego przykładu. Kody pocztowe nie są zwykle używane jako klucze do niczego. (Kiedy ostatnio musiałeś przeszukiwać tabelę PostalCode, aby dowiedzieć się czegoś o tym kodzie? Nie, jest on używany prawie wyłącznie jako część adresu, bez odniesienia w innych tabelach. Powiedziałbym, że Twoja sugestia jest prawie równa użyciu klucze zastępcze dla samych adresów)
ErikE,

@Emtucifor: Tak, może ZIP nie jest zbyt praktycznym przykładem, ale chodziło mi o to, że jeśli część twojego zastępczego klucza wymyka się spod kontroli i zmienia się z jakiegokolwiek powodu, masz kłopoty. Pomyśl o kimś, kto tworzy nowy system numerów ubezpieczenia społecznego, nowy system ISSN lub - może bardziej realistycznie - o firmie decydującej się na stworzenie nowego systemu identyfikacyjnego produktu po fuzji, przydzielając swoim pracownikom nowe numery pracowników w celu dostosowania ich rozwoju itp. wszystkie to tylko fikcyjne przykłady, ale, jak pokazuje mój poprzedni przykład z ZIP, czasami dobrze ugruntowany system może się zmienić.
Dirk Vollmar

2
Twój pierwszy punkt jest poprawny. Jest nazwa dla tego ograniczenia. Nazywa się to „integralnością bytu”. EI wymaga, aby każdy podmiot miał unikalną tożsamość. Klucze podstawowe często spełniają ten wymóg, z wyjątkiem sytuacji, gdy używana jest funkcja automatycznego numerowania. Dzięki autonumerowaniu możesz uzyskać dwa identyczne wiersze, z wyjątkiem autonumerowania. Zwykle narusza to integralność jednostki.
Walter Mitty,

26

Jest to tylko kwestia religijna, ponieważ ludzie szukają uniwersalnej, właściwej odpowiedzi. Fakt, że zarówno Twój zespół, jak i ten wątek SO wykazują tak wiele nieporozumień, powinien być wskazówką, że istnieją dobre powody, aby wykorzystać wszystkie opisane przez Ciebie rozwiązania w różnych okolicznościach.

  • Klucze zastępcze są przydatne, gdy żaden inny atrybut lub zestaw atrybutów w tabeli nie jest odpowiedni do jednoznacznego identyfikowania wierszy.
  • Jeśli to możliwe, preferowane są klucze naturalne, aby tabela była bardziej czytelna dla człowieka. Klucze naturalne pozwalają również, aby klucz obcy w tabeli zależnej zawierał rzeczywistą wartość zamiast zastępczego identyfikatora. Np. Kiedy chcesz zapisać state(CA, TX, NY), równie dobrze możesz użyć char(2)klucza naturalnego zamiast int.
  • W razie potrzeby użyj złożonych kluczy głównych. Nie dodawaj idniepotrzebnego klucza zastępczego, jeśli istnieje idealnie dobry klucz złożony (jest to szczególnie prawdziwe w przypadku tabel „” wiele do wielu). Mandat na trzykolumnowy klucz w każdej tabeli to absolutny nonsens.
  • Identyfikatory GUID są rozwiązaniem, gdy trzeba zachować niepowtarzalność w wielu witrynach. Są również przydatne, jeśli chcesz, aby wartości w kluczu podstawowym były unikalne, ale nie uporządkowane ani kolejne.
  • INT vs. BIGINT: nie jest powszechne, że tabela wymaga zakresu 64-bitowego dla kluczy podstawowych, ale wraz ze wzrostem dostępności sprzętu 64-bitowego nie powinno to stanowić obciążenia i daje większą pewność, że nie zostanie przepełniony. INT jest oczywiście mniejszy, więc jeśli przestrzeń jest na wagę złota, może dać niewielką przewagę.

7
Nie zgadzam się na tyle, na ile osoba może to zrobić. Naturalne klucze są okropne. A jeśli ktoś chce zmienić dane? Nie możesz. Pisanie złączeń na kompozytowych klawiszach naturalnych jest uciążliwe. Noszenie tego złożonego klucza do wszystkich powiązanych tabel to marnotrawstwo.
Robert C. Barth

2
@Robert: przeczytaj o „UPDATE CASCADE”. Ale rozumiem, co mówisz, i zgadzam się, że najlepiej jest używać klucza zastępczego przez większość czasu, ponieważ atrybuty podlegają zmianom i nie są unikalne.
Bill Karwin

2
Klucze podstawowe powinny być niezmienne. Aktualizacje kaskadowe to tylko brzydki hack na złą decyzję projektową w tym przypadku. Naturalne klucze NIGDY nie są preferowane. To samo dotyczy kluczy kompozytowych, które rozprzestrzeniają się jak zaraza. Wiedziałby o tym każdy, kto ma ponad 3 miesiące doświadczenia w tworzeniu baz danych.
FDCastel

7
@FD: Nie zgadzam się z Twoim jednoznacznym stwierdzeniem i rozwijam się z bazami danych SQL od 1992 roku. Ale z pewnością prawdą jest, że klucze zastępcze najlepiej mogą pozostać niezmienione.
Bill Karwin

20

Lubię blog The Database Programmer jako źródło tego rodzaju informacji.

3 kolumny dla klucza podstawowego? Powiedziałbym, że kolumny powinny mieć odpowiednie unikalne ograniczenia, zgodnie z wymaganiami reguł biznesowych, ale nadal mam oddzielny klucz zastępczy. Klucze złożone oznaczają, że logika biznesowa jest wprowadzana do klucza. Jeśli logika się zmieni, cały schemat jest zepsuty.


2
Zmienili swój link, oto zaktualizowana zakładka: database-programmer.blogspot.com/2008/09/…
Bryan Rehbein

Właśnie odziedziczyłem taki projekt. I pierwsza rzecz, którą chcieli zrobić, wysadziła schemat. Klucze zastępcze FTW. Logika biznesowa w DB FTL.
Jason


11

Trochę nie na temat, ale czuję się zmuszony do rozmowy z ...

Jeśli klucz podstawowy to identyfikator GUID, nie rób z niego indeksu klastrowego . Ponieważ identyfikatory GUID nie są sekwencyjne, dane zostaną ponownie uporządkowane na dysku podczas prawie każdego wstawiania. (Fuj.) Jeśli używasz identyfikatorów GUID jako kluczy podstawowych, powinny to być indeksy nieklastrowe.


1
Bardzo dobry punkt - trzeba odróżnić LOGICAL pojęciem klucza podstawowego (może być ważne, aby użyć GUID za to, zwłaszcza jeśli replikacja jest zaangażowany) i FIZYCZNE pojęcie klucza klastrowego - powinna nigdy być GUID od prowadzi to do nadmiernej fragmentacji indeksu
marc_s

3
W rzeczywistości nie jest to dokładne. Dane zostaną wstawione w kolejności, która biorąc pod uwagę losowy charakter identyfikatora GUID, może znaleźć się w dowolnym miejscu w tabeli. Jeśli nie ma miejsca, nastąpi podział strony, ale z pewnością nie „ponowne ułożenie na dysku przy każdym wstawianiu”, nawet nie zamknięte.
Ralph Shillington

@Ralph, masz rację, nie KAŻDA wkładka, ale wystarczająca, aby spowodować 20-krotny wzrost wydajności. sql-server-performance.com/articles/per/…
Portman

Funkcja SQL Server newsequentialid () rozwiązuje problem fragmentacji indeksu za pomocą identyfikatorów GUID (chociaż 24 bajty to wciąż trochę za dużo, jeśli absolutnie nie potrzebujesz globalnej unikalności). Zobacz msdn.microsoft.com/en-us/library/ms189786.aspx.
ErikE

10

Zawsze używam zastępczego klucza. Klucz zastępczy (zwykle kolumna tożsamości, autoincrement lub identyfikator GUID) to taki, w którym klucz nie występuje w samych danych. Z drugiej strony klucz naturalny to taki, który sam w sobie jednoznacznie identyfikuje wiersz. O ile wiem, w życiu prawie nie ma prawdziwych naturalnych kluczy. Nawet rzeczy takie jak SSN w Stanach Zjednoczonych nie są naturalnym kluczem. Złożone klucze podstawowe to katastrofa, która czeka. Nie możesz edytować żadnych z tych danych (co jest główną wadą każdego klucza naturalnego, złożonego lub nie), ale co gorsza, w przypadku klucza złożonego musisz teraz utrwalić te kluczowe dane w każdej powiązanej tabeli. Co za gigantyczne marnotrawstwo.

Teraz do wyboru klucza zastępczego trzymam się kolumn identyfikacyjnych (pracuję głównie w MS SQL Server). GUID są zbyt duże i Microsoft zaleca przed użyciem ich jako PK. Jeśli masz wiele serwerów, wszystko, co musisz zrobić, to zwiększyć o 10 lub 20 lub cokolwiek myślisz maksymalną liczbę serwerów, które kiedykolwiek będziesz musiał zsynchronizować / rozszerzyć, i po prostu dodać ziarno dla każdej tabeli na każdym kolejnym serwerze i nigdy nie dojdzie do kolizji danych.

Oczywiście ze względu na przyrost robię kolumnę tożsamości jako BigInt (znaną również jako long [64 bity]).

Trochę matematyki, nawet jeśli zwiększysz przyrost o 100, nadal możesz mieć w tabeli 92 233 720 368 547 758 (> 92 biliardów) wierszy.


9

Myślę, że użycie słowa „Podstawowy” w wyrażeniu „Podstawowy” Klucz jest w prawdziwym sensie mylące.

Najpierw użyj definicji, że „klucz” to atrybut lub zestaw atrybutów, które muszą być unikalne w tabeli,

Wówczas posiadanie dowolnego klucza służy kilku często sprzecznym celom.

  1. Aby użyć jako warunków łączenia z jednym lub wieloma rekordami w tabelach podrzędnych, które są powiązane z tą tabelą nadrzędną. (Jawne lub niejawne definiowanie klucza obcego w tych tabelach podrzędnych)
  2. (powiązane) Zapewnienie, że rekordy podrzędne muszą mieć rekord nadrzędny na karcie nadrzędnej; e (tabela podrzędna FK musi istnieć jako klucz w tabeli nadrzędnej)
  3. Aby zwiększyć wydajność zapytań, które wymagają szybkiego zlokalizowania określonego rekordu / wiersza w tabeli.

  4. Aby zapewnić spójność danych, zapobiegając wstawianiu zduplikowanych wierszy, które reprezentują tę samą jednostkę logiczną, do tabeli. (Nazywa się to często kluczem „naturalnym” i powinien składać się z atrybutów tabeli (jednostki), które są względnie niezmienne).

Oczywiście każdy nie mający znaczenia, nienaturalny klucz (taki jak identyfikator GUID lub automatycznie generowana liczba całkowita) jest całkowicie niezdolny do spełnienia # 4.

Ale często, przy wielu (większości) tabelach, całkowicie naturalny klucz, który może zapewnić # 4, często będzie składał się z wielu atrybutów i będzie zbyt szeroki lub tak szeroki, że użycie go do celów # 1, # 2 lub # 3 spowoduje niedopuszczalne konsekwencje wydajności.

Odpowiedź jest prosta. Użyj obu. Użyj prostego, automatycznie generującego się klucza integralnego dla wszystkich sprzężeń i SK w innych tabelach podrzędnych, ale upewnij się, że każda tabela, która wymaga spójności danych (bardzo niewiele tabel nie), ma alternatywny naturalny, unikalny klucz, który zapobiegnie wstawianiu niespójnych wierszy danych. .. Plus, jeśli zawsze masz jedno i drugie, to wszystkie obiekcje wobec używania klucza naturalnego (a co, jeśli się zmieni? Muszę zmienić każde miejsce, do którego odnosi się jako FK) stają się dyskusyjne, ponieważ nie używasz go do tego. .. Używasz go tylko w jednej tabeli, w której jest PK, aby uniknąć niespójnych zduplikowanych danych ...

Jeśli chodzi o identyfikatory GUID, używaj ich bardzo ostrożnie, ponieważ używanie przewodników w indeksie może spowodować fragmentację indeksu. Najpopularniejsze algorytmy używane do ich tworzenia umieszczają „losową” część guidu w najbardziej znaczących pozycjach bitowych ... Zwiększa to wymagania dotyczące regularnej defragmentacji indeksu / ponownego indeksowania w miarę dodawania nowych wierszy.


Funkcja SQL Server newsequentialid () rozwiązuje problem fragmentacji indeksów w identyfikatorach GUID (chociaż 24 bajty to wciąż trochę za dużo, jeśli absolutnie nie potrzebujesz globalnej unikalności). Zobacz msdn.microsoft.com/en-us/library/ms189786.aspx.
ErikE

Ups, chciałem powiedzieć 16 bajtów.
ErikE

8

Nigdy nie powinieneś używać inteligentnego klucza. Jest to klucz, w którym informacje o rekordzie są zakodowane w samym kluczu i ostatecznie cię ugryzie.

Pracowałem w jednym miejscu, gdzie kluczem podstawowym był identyfikator konta, będący kombinacją liter i cyfr. Nie pamiętam żadnych szczegółów, ale na przykład te konta, które były określonego typu, były w przedziale 600, a innego typu zaczynały się od 400. To było świetne, dopóki klient nie zdecydował się poprosić o oba rodzaje pracy. Albo zmienił rodzaj wykonywanej pracy.

Inne miejsce wykorzystało lokalizację w drzewie jako klucz podstawowy dla rekordów. Więc byłyby takie rekordy jak poniżej.

Cat1.subcatA.record1
Cat1.subcatA.record2
Cat1.subcatB.record1
Cat2.subcatA.record1

Oczywiście pierwszą rzeczą, jakiej chcieli klienci, był sposób na przenoszenie elementów w drzewie. Cały zestaw oprogramowania umarł, zanim to się stało.

Proszę, proszę, proszę, jeśli piszesz kod, który kiedykolwiek będę musiał utrzymywać, nie używaj inteligentnego klucza!


Całkowicie się zgadzam. Smartkeys = głupi.
Robert C. Barth

2
Nie oznacza to jednak, że naturalne klawisze są głupie. Ale słuszna uwaga.

4

Jestem fanem automatycznego zwiększania wartości jako klucza podstawowego. W głębi serca wiem, że jest to wymówka, ale tak łatwo jest sortować dane według daty ich dodania (ORDER BY ID DESC, na przykład).

3 kolumny brzmią okropnie surowo do analizy po ludzku.

I to jest kompromis - ile zdolności relacyjnych potrzebujesz, a uczynienie TEGO TUTAJ TUTAJ TUTAJ zrozumiałym dla człowieka, który ją przesłuchuje (w przeciwieństwie do procedury składowanej lub interfejsu programistycznego).

auto-przyrost jest dla nas, ludzi. :-(


4

Generalnie to zależy.

Osobiście lubię ints autoincrement.

Ale jedno, co mogę powiedzieć, to nigdy nie ufać danym z innych źródeł jako kluczowi. Przysięgam, za każdym razem, gdy to robię, wraca, by mnie ugryźć. Cóż, nigdy więcej!


3

Powinny istnieć co najmniej 3 kolumny, które składają się na klucz podstawowy.

Nie rozumiem tego.

Czy mówisz o „kluczu naturalnym”, np. „Imię i data urodzenia”? Naturalny klucz może być idealny, jeśli istnieje, ale większość kandydatów na klucz naturalny albo nie jest unikalna (kilka osób o tej samej nazwie), albo nie jest stała (ktoś może zmienić swoje imię).

Int / BigInt, które autoincrement są wystarczająco dobre klucze podstawowe.

Wolę Guid. Potencjalnym problemem związanym z autoinkrementacją jest to, że wartość (np. „Identyfikator zamówienia”) jest przypisywana przez instancję bazy danych (np. Przez „bazę danych sprzedaży”) ... która nie będzie działać całkowicie (zamiast tego zaczniesz potrzebować kluczy złożonych), jeśli kiedykolwiek będziesz musiał łączyć dane utworzone przez więcej niż jedną instancję bazy danych (np. z kilku biur sprzedaży, każde z własną bazą danych).


Klucze podstawowe muszą być unikalne, ale nie muszą być stałe. Stąd klucze obce zadeklarowane jako "ON UPDATE CASCADE". Jednak założenie, że klucze podstawowe są stałe, pomaga uprościć wiele aplikacji. Jest to jedna z zalet kluczy zastępczych.
Bill Karwin

3

RE GUID

Uważaj, jeśli to będzie naprawdę, NAPRAWDĘ, NAPRAWDĘ duża baza danych, dużo obciążenia i szybki dostęp.

Podczas mojej ostatniej pracy, w której mieliśmy bazy danych zawierające od 100 do 500 milionów rekordów, nasi faceci z bazy danych zdecydowanie sprzeciwiali się identyfikatorom GUID i żądali odpowiedniej wielkości liczby dziesiętnej. Uważali, że (pod Oracle) różnica wielkości w pamięci wewnętrznej dla ciągu znaków Guid - vs - wartość dziesiętna spowodowałaby bardzo zauważalną różnicę w wyszukiwaniu. (Większe klawisze = głębsze drzewa do przemierzania)

Losowy charakter identyfikatorów GUID znacznie zmniejsza również współczynnik wypełnienia dla stron indeksowych - to dramatycznie zwiększa zrywanie i operacje wejścia / wyjścia dysku.


„Zmniejsza współczynnik wypełnienia”? Nie jestem pewien, co to może oznaczać. Współczynnik wypełnienia to jednorazowa transakcja, definiowana jako procent wolnej przestrzeni żądanej na poziomie liścia indeksu w momencie tworzenia indeksu. Wartości GUID według ich losowego rozkładu na szerokości poziomu liścia na wstawkach do wolnej przestrzeni podanym przez współczynnik wypełnienia.
Ralph Shillington,

1
Od kiedy GUID jest łańcuchem? Identyfikatory GUID powinny być przechowywane wewnętrznie jako 16 bajtów przez dowolny szanowany system DBMS. Przechowywanie jako 32 bajtów w reprezentacji szesnastkowej byłoby niegodne! (lub 36 z kreskami lub 38 z nawiasami klamrowymi)
ErikE

2

Kolumny z automatycznym zwiększaniem. Jestem w stanie sprawić, by mój kod bezproblemowo współpracował z SQL Server lub Oracle, jeden używając tożsamości, drugi używając sekwencji przez mój DAL, i nie mogłem być szczęśliwszy. Zgadzam się, identyfikatory GUID są czasami niezbędne, jeśli wykonujesz replikację lub wysyłasz dane, aby otrzymać je później po przetworzeniu.


2

Zawsze używałem klucza zastępczego - automatycznie zwiększającej się liczby całkowitej o nazwie „id”. Widzę wiele powodów, aby to zrobić, nawet jeśli inna opcja jest oczywista:

  • Konsystencja
  • Niezależne od danych (unikalne, nie niszczone przez zmiany formatu)
  • Czytelny dla człowieka

... i nie ma rozsądnego powodu, aby nie:

  • Niejednoznaczność w połączeniach? - Aliasing tabele to lepsza praktyka, IMHO
  • Optymalne stoły? - Usunięcie jednego bajta na wpis to przedwczesna optymalizacja, IMHO
  • Decyzja dotycząca stołu? - Już nie spójne
  • Problemy ze skalowaniem? - Ech? Czemu?
  • Hierarchiczna struktura danych? - To denormalizacja, zupełnie inny temat religii. Wystarczy powiedzieć, że w teorii jestem fanem w kilku okolicznościach, ale w praktyce nigdy :)

rozsądne powody, o których nie pomyślałem lub których jeszcze nie spotkałem, są zawsze mile widziane ...


1

To jest klasyczne „to zależy”. Nie ma jednej właściwej odpowiedzi dla każdego projektu. Lubię różne rzeczy w różnych sytuacjach. To zależy od tego, czy używam ORM i co obsługuje. Zależy to od ogólnej architektury (rozproszonej lub nie, itp.). Po prostu wybierz taki, który Twoim zdaniem będzie działał i przejdź do sporu o tabulatory i spacje.


Nadal chce wiedzieć, JAK to zależy; tylko mając ich świadomość, można zaufać sobie w wyborze ...
Nicholas Leonard.

1

Zwykle używam opcji nr 1 lub nr 3 w zależności od rozmiaru, liczby łączących się osób i tego, czy jest to sytuacja z wieloma serwerami baz danych, czy nie.

Opcja nr 2 nie ma dla mnie większego sensu. Jeśli którykolwiek z trzech nie wystarczy do zidentyfikowania unikalnego rekordu, możliwe jest (bez przechodzenia przez dodatkowe machinacje), że dwa rekordy pojawią się z tymi samymi wartościami we wszystkich trzech kolumnach. Jeśli chcesz wymusić niepowtarzalność w dowolnej kombinacji tych trzech, po prostu dodaj dla nich indeks.


1

Używam tylko int auto-inkrementacji lub GUID. W 99% przypadków używam int. Właśnie tego nauczyłem się używać, kiedy po raz pierwszy dowiedziałem się o bazach danych i nigdy nie natknąłem się na powód, aby ich nie używać (chociaż znam powody, dla których GUID byłby lepszy).

Lubię automatyczne zwiększanie wartości int, ponieważ pomaga to w czytelności. Na przykład mogę powiedzieć „spójrz na rekord 129383” i ktoś może łatwo wejść i go znaleźć. Z GUID jest to prawie niemożliwe.


2
Dlaczego to mówisz? Wygląda na to, że wiele osób używa automatycznej liczby całkowitej. Nie może być tak źle, jeśli działa i działa dobrze dla tego, czego potrzebujesz.
dtc

1

Pomijając podstawową odpowiedź definicyjną, to, co stanowi dobry klucz główny, pozostaje w dużej mierze kwestią religii i argumentów na przerwę. Jeśli masz coś, co jest i zawsze będzie mapować unikalnie do pojedynczego wiersza, będzie działać dobrze jako klucz podstawowy. Po tym punkcie istnieją inne kwestie:

  • Czy definicja klucza podstawowego nie jest nadmiernie złożona? Czy unika się wprowadzania niepotrzebnej złożoności w celu przestrzegania „najlepszej praktyki”?
  • Czy istnieje lepszy możliwy klucz podstawowy, który wymagałby mniejszego narzutu do obsługi bazy danych (np. INTEGER, VARCHAR itp.)?
  • Czy jestem ABSOLUTNIE pewny, że niepowtarzalność i niezmienność zdefiniowanego klucza głównego nie ulegną zmianie?

To ostatnie jest prawdopodobnie tym, co przyciąga większość ludzi do używania takich rzeczy, jak identyfikatory GUID lub samoczynnie zwiększające się kolumny z liczbami całkowitymi, ponieważ poleganie na takich rzeczach, jak adresy, numery telefonów, imiona / nazwiska itp., Po prostu nie ograniczaj tego. Jedynym niezmiennikiem ludzi, o których przychodzi mi do głowy, są SSN, ale nie mam nawet 100% pewności, czy ci pozostaną na zawsze wyjątkowi.

Miejmy nadzieję, że pomoże to zwiększyć jasność ...


Istnieją historyczne przypadki, w których numery Stoczni Szczecińskiej nie są wyjątkowe.
Bill Karwin

1

Sposób, w jaki podchodzę do kluczy głównych (i uważam, że jest najlepszy), polega na unikaniu podejścia „domyślnego”. Oznacza to, że zamiast po prostu uderzać w automatycznie zwiększającą się liczbę całkowitą i nazywać ją dniem, patrzę na problem i mówię „czy istnieje kolumna lub grupa kolumn, która zawsze będzie niepotrzebna i nie ulegnie zmianie?” Jeśli odpowiedź brzmi tak, przyjmuję takie podejście.


Czy to oznacza, że ​​„unikasz autoinkrementacji liczb całkowitych, kiedy tylko możesz”? Zrozumiałem, że eksperci branżowi uważali, że najlepsza wydajność w dużych bazach danych pochodzi z indeksowanych, przyrostowych jednokolumnowych PK z minimalną sygnaturą.
Hardryv

1
Zawsze myślałem, że eksperci używają najlepszego narzędzia do tego zadania
Andrew G. Johnson

1

Prawie zawsze liczby całkowite.

Mają inne dobre powody, poza tym, że są mniejsze / szybsze w przetwarzaniu. Który wolisz zapisać - „404040” czy „3463b5a2-a02b-4fd4-aa0f-1d3c0450026c”?


Ta ostatnia może być liczbą całkowitą z dodanymi myślnikami i ma podstawę 16. Ale tak, 404040 jest szybsze w przetwarzaniu niż długi identyfikator GUID. Z drugiej strony, 0 jest jeszcze szybsze w przetwarzaniu, ponieważ nie wymaga ani jednego bitu danych!
strager

1

Tylko nieznacznie istotne, ale jedną z rzeczy, które zacząłem ostatnio robić, kiedy mam małe tabele klasyfikacyjne (zasadniczo takie, które reprezentowałyby ENUM w kodzie) jest to, że zmienię klucz podstawowy jako char (3) lub char (4). Następnie sprawiam, że te klucze główne są reprezentatywne dla wartości wyszukiwania.

Na przykład mam system ofertowy dla naszych wewnętrznych przedstawicieli handlowych. Mamy „Kategorie kosztów”, do których każdy element zamówienia w ofercie ma przypisaną jedną z… Mam więc tabelę wyszukiwania typów o nazwie „tCostCategories”, w której klucz podstawowy to „MTL”, „SVC”, „TRV”, „TAX”, „ODC”. Inne kolumny w tabeli przeglądowej przechowują więcej szczegółów, takich jak zwykłe angielskie znaczenie kodów, „Materiał”, „Usługa”, „Podróże”, „Podatki”, „Inne koszty bezpośrednie” i tak dalej.

Jest to naprawdę fajne, ponieważ nie zajmuje więcej miejsca niż int, a kiedy patrzysz na dane źródłowe, nie musisz łączyć tabeli przeglądowej, aby wiedzieć, jaka jest ta wartość. Na przykład wiersz cytatu może wyglądać następująco:

1 PartNumber 40 $ MTL
2 Other PartNumber 29,99 $ SVC
3 PartNumber2 150 $ TRV

O wiele łatwiej jest użyć int do reprezentowania kategorii, a następnie połączyć 1, 2, 3 we wszystkich wierszach - masz dane przed sobą, a wydajność nie wydaje się w ogóle mieć wpływu (nie to, że ja naprawdę przetestowane.)

Jeśli chodzi o prawdziwe pytanie ... Lubię unikalne identyfikatory RowGUID. Nie jestem w 100% w tym, ale nie wszystkie wiersze i tak mają wewnętrzne RowGuid? Jeśli tak, to użycie RowGuid zajęłoby w rzeczywistości mniej miejsca niż ints (lub cokolwiek innego). Wiem tylko, że jeśli jest wystarczająco dobre, aby M $ mogło być używane w GreatPlains, to jest dla mnie wystarczająco dobre. (Powinienem uchylić się ??)


1

Jeszcze jeden powód, dla którego używam identyfikatorów GUID - używam hierarchicznej struktury danych. Oznacza to, że mam tabelę „Firma” i tabelę „Dostawca”, dla których pasują do siebie Klucze główne. Ale mam też tabelę „Producent”, która również „dziedziczy” po firmie. Pola, które są wspólne dla dostawców i producentów, nie pojawiają się w tych tabelach - pojawiają się w firmie. W tej konfiguracji używanie int jest znacznie bardziej bolesne niż Guids. W każdym razie nie możesz używać podstawowych kluczy tożsamości.


1
Tak, możesz po prostu nie nadawać tabelom podtypów właściwości tożsamości, zamiast tego otrzymują one jawne wstawienia wartości tabeli nadtypów. Zobacz stackoverflow.com/questions/2112882/…
ErikE

1

Lubię naturalne klucze, kiedy tylko mogę im zaufać. Jestem gotów zapłacić niewielką cenę za wykonanie, aby używać kluczy, które mają sens dla ekspertów w danej dziedzinie.

W przypadku tabel opisujących encje powinien istnieć prosty naturalny klucz, który identyfikuje poszczególne wystąpienia w taki sam sposób, jak ludzie. Jeśli przedmiot nie ma wiarygodnych identyfikatorów dla jednej z jednostek, skorzystam z klucza zastępczego.

W przypadku tabel opisujących relacje używam klucza złożonego, w którym każdy składnik odwołuje się do jednostki uczestniczącej w relacji, a zatem do wiersza w tabeli jednostek. Ponownie, wydajność użycia klucza złożonego jest ogólnie minimalna.

Jak zauważyli inni, termin „klucz podstawowy” jest trochę mylący. W relacyjnym modelu danych używany jest termin „klucze kandydujące”. Dla jednej tabeli może być kilka kluczy kandydatów. Logicznie rzecz biorąc, każdy jest tak samo dobry jak inny. Wybór jednego z nich jako „podstawowego” i dokonanie wszystkich odniesień za pomocą tego klucza jest po prostu wyborem, którego może dokonać projektant.


Proszę opisać przykładowe godne zaufania klucze naturalne?
ErikE

1
„Godny zaufania” nie jest sam w sobie właściwością klucza. Raczej ma to związek z kluczem w kontekście osób, które dostarczają dane. Jeśli piszesz aplikację, która ma być sprzedana komuś, kto faktycznie będzie zarządzał danymi, musisz odgadnąć, które klucze będą godne zaufania dla klienta, czy nie. Biorąc pod uwagę różnorodność klientów, prawie na pewno zgadniesz źle dla jakiejś części swoich klientów.
Walter Mitty,

Powiedziawszy powyższe, oto przykład klucza, któremu ufaliśmy już dawno. Mieliśmy bazę danych o kursach. Obejmuje podręczniki i inne materiały dotyczące kursów, oferty kursów zaplanowanych, instruktorów posiadających kwalifikacje do prowadzenia kursów, wymagania wstępne dotyczące kursów, czesne i tak dalej. Kiedy programista stworzył nowy kurs, jedną z pierwszych rzeczy, które zrobili, było przypisanie kodu kursu. Byli odpowiedzialni za upewnienie się, że kody kursów są unikalne i że kursy nigdy nie zmieniły swojego kodu po przypisaniu. To była część danych, które zostały nam dane.
Walter Mitty,

Innym dobrym przykładem zaufanego klucza naturalnego jest VIN (numer identyfikacyjny pojazdu). Od wielu lat każdy sprzedawany jako nowy pojazd ma dołączony VIN. Można im ufać, że są wyjątkowe i niezmienne.
Walter Mitty,

1

Guids.period.

W przypadku konieczności skalowania w poziomie lub przypisania klucza głównego w inny sposób, będą one Twoim przyjacielem. Możesz dodać indeksy do wszystkiego innego.


aktualizacja wyjaśniająca moje oświadczenie.

Pracowałem na wielu różnych witrynach. Od małych pojedynczych serwerów do dużych, opartych na wielu bazach danych i serwerach WWW. Z pewnością istniały aplikacje, które radziłyby sobie dobrze z automatycznym zwiększaniem liczby int jako kluczy podstawowych. Jednak te nie pasują do modelu tego, jak robię rzeczy.

Korzystając z identyfikatora GUID, możesz wygenerować identyfikator w dowolnym miejscu. Może być generowany przez serwer zdalny, aplikację internetową, w samej bazie danych lub nawet w wielu bazach danych w sytuacji z wieloma wzorcami.

Z drugiej strony, automatycznie zwiększany INT można bezpiecznie wygenerować tylko w podstawowej bazie danych. Ponownie, może to być w porządku, jeśli masz aplikację, która będzie ściśle powiązana z tym jednym zapasowym serwerem DB, a skalowanie w poziomie nie jest czymś, co Cię interesuje.

Jasne, użycie identyfikatorów GUID oznacza, że ​​musisz co noc przeprowadzać procesy reindeksowania. Jeśli jednak używasz czegokolwiek innego niż automatycznie zwiększana wartość INT, i tak powinieneś to zrobić. Heck, nawet z INT jako podstawowym, prawdopodobnie masz inne indeksy, które wymagają regeneracji, aby poradzić sobie z fragmentacją. Dlatego użycie identyfikatorów GUID nie powoduje dokładnie kolejnego problemu, ponieważ zadania te muszą być wykonywane niezależnie.

Jeśli spojrzysz na większe aplikacje, zauważysz coś ważnego: wszystkie używają identyfikatorów GUID zakodowanych w Base64 jako kluczy. Powód jest prosty, użycie identyfikatorów GUID umożliwia łatwe skalowanie w poziomie , podczas gdy przy próbie skalowania w poziomie INT może być wiele przeszkód do przeskoczenia.

Nasza najnowsza aplikacja przechodzi okres ciężkich wkładek, który trwa około miesiąca. Następnie 90 +% zapytań to wszystkie wybrane do raportowania. Aby zwiększyć pojemność, mogę dodać dodatkowe serwery DB podczas tego długiego okresu wstawiania; a później łatwo połączyć je w jedną bazę danych do raportowania. Próba zrobienia tego z INT byłaby absolutnym koszmarem.

Szczerze mówiąc, za każdym razem, gdy klastrujesz bazę danych lub konfigurujesz replikację, serwer bazy danych i tak zażąda posiadania identyfikatorów GUID w tabeli. Tak więc, jeśli myślisz, że Twój system może wymagać rozwoju, wybierz ten, który jest dobry.


Czy kiedykolwiek sprawdzałeś współczynnik wypełnienia swoich indeksów? Losowy charakter GUID czyni je szwajcarskim serem - radykalnie zmniejszając ich skuteczność.
stephbu

2
„Guids.period”: To takie złe. W stosownych przypadkach należy używać identyfikatorów GUID. Jak zauważył inny komentator, może to ułatwić życie programisty, ale wpływa na ogólny rozmiar i wydajność bazy danych.
Mitch Wheat

Ostatecznie mogę bez problemu skalować swoje aplikacje na wiele serwerów baz danych. Ale myślę, że pracujecie na małych stronach.
NotMe

3
GUID może być w porządku dla logicznego klucza podstawowego, ale NIGDY NIGDY nie używaj kolumny GUID jako klucza CLUSTERING - będziesz topić się w fragmentacji indeksu prowadzącej do
SŁABEJ

Z pewnością nie ogłosiłbym „Guids.period”. na ten temat - w rzeczywistości nawet w branży tak pełnej „najlepszych praktyk” tego rodzaju stwierdzenie domyślnie stawia cię na niepewnym gruncie (szczególnie w przypadku tego stwierdzenia). Wszystko, co jest tak bolesne, jak GUID, wymaga twardego uzasadnienia i jak mówi JL, myślę, że większość z nas uznałaby to za ostateczność. To tak, jakbyś pisał bez czytania reszty wątku.
Hardryv

0

To złożony temat, niezależnie od tego, czy zdałeś sobie z tego sprawę, czy nie. Może znaleźć się w sekcji tego często zadawanego pytania na temat StackOverflow.

Jakich pytań nie powinienem tutaj zadawać?

Unikaj zadawania pytań, które są subiektywne, dyskusyjne lub wymagają dłuższej dyskusji. To miejsce na pytania, na które można znaleźć odpowiedź!

To było przedmiotem debaty od lat i będzie przedmiotem debaty jeszcze przez lata. Jedyne wskazówki co do konsensusu, jakie widziałem, to to, że odpowiedzi są w pewnym stopniu przewidywalne w zależności od tego, czy pytasz faceta OO (GUID to jedyna droga!), Modelarza danych (klucze naturalne to jedyna droga!), lub DBA zorientowany na wyniki (INT to jedyna droga!).


Nie pozwolę, by dyskusja trwała długo. Byłem po prostu ciekawy ogólnego konsensusu.
Perpetualcoder

1
Mówię: zadawaj dowolne pytania! W przeciwnym razie ta społeczność stanie się statyczna i nadmiernie kontrolowana, jak wydaje się być wikipedia. Wydaje mi się, że czasami trzeba pozwolić ludziom zapytać, o cokolwiek zdecydują się poprosić. Zaufaj im, a mogą zaufać sobie!
Nicholas Leonard
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.