Zalety i wady kluczy bazy danych GUID / UUID

222

W przeszłości pracowałem nad wieloma systemami baz danych, w których przenoszenie wpisów między bazami danych byłoby znacznie łatwiejsze, gdyby wszystkie klucze bazy danych były wartościami GUID / UUID . Rozważałem pójście tą ścieżką kilka razy, ale zawsze jest trochę niepewności, szczególnie w odniesieniu do wydajności i adresów URL, które nie można odczytać przez telefon.

Czy ktoś intensywnie pracował z identyfikatorami GUID w bazie danych? Jakie korzyści uzyskałbym w ten sposób i jakie są prawdopodobne pułapki?

Matt Sheppard
źródło
1
Jeff ma na ten temat post „ Klucze podstawowe: identyfikatory kontra identyfikatory GUID ”.
jfs
1
może również używać Hi-Lo dla zdalnych klientów: stackoverflow.com/questions/282099/whats-the-hi-lo-algorytm
Neil McGuigan
Zaktualizowano lokalizację posta Jeffa Atwooda na temat „ Klucze podstawowe: identyfikatory kontra identyfikatory GUID ”. Dzięki @jfs za odniesienie.
Adam Katz
@jfs Link zmienił się na blog.codinghorror.com/primary-keys-ids-versus-guids
cr0ss

Odpowiedzi:

229

Zalety:

  • Może generować je offline.
  • Sprawia, że ​​replikacja jest trywialna (w przeciwieństwie do int, co czyni ją NAPRAWDĘ trudną)
  • ORM zwykle je lubią
  • Unikalny dla różnych aplikacji. Możemy więc korzystać z PK z naszego CMS (GUID) w naszej aplikacji (również GUID) i wiemy, że NIGDY nie dojdziemy do starcia.

Niedogodności:

  • Większe wykorzystanie miejsca, ale miejsce jest tanie (er)
  • Nie można zamówić według identyfikatora, aby uzyskać zamówienie na wstawienie.
  • Może wyglądać brzydko w adresie URL, ale tak naprawdę, WTF robisz umieszczenie PRAWDZIWEGO klucza DB w adresie URL !? (Ten punkt kwestionowany w komentarzach poniżej)
  • Trudniejsze do ręcznego debugowania, ale nie tak trudne.

Osobiście używam ich do większości PK w dowolnym systemie przyzwoitej wielkości, ale „przeszkoliłem” się w systemie, który był replikowany w każdym miejscu, więc MUSIMY je mieć. YMMV.

Myślę, że zduplikowane dane to śmieci - możesz uzyskać zduplikowane dane, jakkolwiek to robisz. Klucze zastępcze są zwykle niezadowolone z tego, gdzie kiedykolwiek pracowałem. Używamy jednak systemu podobnego do WordPressa:

  • unikalny identyfikator wiersza (GUID / cokolwiek). Nigdy niewidoczne dla użytkownika.
  • identyfikator publiczny jest generowany RAZ z jakiegoś pola (np. tytuł - ustaw go jako tytuł artykułu)

AKTUALIZACJA: Więc ten dostaje bardzo +1 i pomyślałem, że powinienem wskazać duży minus GUID PK: Clustered Indexes.

Jeśli masz dużo rekordów i indeks klastrowy w GUID, wydajność wstawiania SUCK, ponieważ wstawiasz w losowych miejscach na liście elementów (o to chodzi), a nie na końcu (co jest szybkie)

Więc jeśli potrzebujesz wydajności wstawiania, może użyj INT-auto-inc i wygeneruj identyfikator GUID, jeśli chcesz udostępnić go komuś innemu (tj. Pokazać go użytkownikowi w adresie URL)

Nic Wise
źródło
184
[WTF, robisz wstawianie PRAWDZIWEGO klucza DB do adresu URL !?] Nie wiesz, dlaczego ci to przeszkadza. Czego jeszcze byś użył? Spójrz na Przepełnienie stosu ... Ma wartości IDENTYFIKACYJNE w adresie URL w całym miejscu i działa dobrze. Używanie kluczy DB w adresach URL nie uniemożliwia egzekwowania bezpieczeństwa.
Euro Micelli,
20
Nie, nie ma, ale rzeczy takie jak SEO są zwykle lepsze, jeśli nie ma w tym klucza - zwłaszcza coś tak długiego jak GUID. Oczywiście można to łatwo obejść, więc myślę, że to było trochę przesadzające stwierdzenie
Nic Wise,
7
Dobra odpowiedź, byłoby miło, gdybyś dodał także informacje o wadach wydajności korzystania z GUID; np. łączenie, sortowanie i indeksowanie według nich będzie wolniejsze niż przy użyciu liczb całkowitych. Przewodniki są fantastyczne, ale kosztują, co może być uciążliwe, gdy wydajność ma kluczowe znaczenie.
Doktor Jones
26
Pamiętaj, że ludzie często zmieniają strony, pytania i tytuły na forum. W przypadku SEO DOBRE jest mieć coś w rodzaju małego identyfikatora w adresie URL, aby jeśli tytuł się zmienił, nadal wiesz, gdzie przekazywać osoby przychodzące ze starego adresu URL. example.com/35/old-and-bustedwłaśnie się stałem, example.com/35/new-hotnessa aplikacja może po prostu sprawdzić tytuł i przekazać użytkownikowi 301.
Xeoncross
9
Indeksowanie identyfikatora GUID jest kosztowne i powolne, przez co są naprawdę kiepskimi kandydatami na klucze podstawowe.
Matthew James Davis
14

@Matt Sheppard:

Powiedz, że masz tabelę klientów. Na pewno nie chcesz, aby klient pojawił się w tabeli więcej niż jeden raz, w przeciwnym razie w działach sprzedaży i logistyki pojawi się wiele nieporozumień (zwłaszcza jeśli wiele wierszy o kliencie zawiera różne informacje).

Masz więc identyfikator klienta, który jednoznacznie identyfikuje klienta, i upewniasz się, że jest on znany klientowi (na fakturach), dzięki czemu klient i pracownicy obsługi klienta mają wspólne referencje na wypadek potrzeby komunikacji. Aby zagwarantować brak duplikatów rekordów klientów, dodajesz do tabeli ograniczenie unikatowości, albo poprzez klucz podstawowy w identyfikatorze klienta, albo poprzez ograniczenie NOT NULL + UNIKALNE w kolumnie identyfikatora klienta.

Następnie, z jakiegoś powodu (o którym nie mogę myśleć), zostaniesz poproszony o dodanie kolumny GUID do tabeli klientów i uczynienie z niej klucza podstawowego. Jeśli kolumna z identyfikatorem klienta pozostanie bez gwarancji jednoznaczności, poprosisz o przyszłe problemy w całej organizacji, ponieważ identyfikatory GUID zawsze będą unikalne.

Niektórzy „architekci” mogą powiedzieć, że „och, ale radzimy sobie z ograniczeniem prawdziwej wyjątkowości klienta w naszej warstwie aplikacji!”. Dobrze. Moda związana z tymi językami programowania ogólnego przeznaczenia i (szczególnie) platformami warstwy środkowej zmienia się cały czas i generalnie nigdy nie przeżyje twojej bazy danych. I istnieje bardzo duża szansa, że ​​w pewnym momencie będziesz musiał uzyskać dostęp do bazy danych bez przechodzenia przez obecną aplikację. == Kłopoty. (Ale na szczęście ty i „architekt” już dawno minęli, więc nie będziesz tam, aby posprzątać bałagan.) Innymi słowy: utrzymuj oczywiste ograniczenia w bazie danych (i na innych poziomach, jeśli masz czas).

Innymi słowy: mogą istnieć dobre powody, aby dodać kolumny GUID do tabel, ale nie daj się zwieść pokusie obniżenia ambicji spójności w rzeczywistej (== nie GUID) informacji.

Troels Arvin
źródło
1
Usłysz słyszeć! Uwielbiam swoją stronę porównawczą SQL. Niezwykle przydatny. Jedyne, za czym tęsknię, to dziennik zmian.
Henrik Gustafsson
3
Myślę, że ta odpowiedź wymaga pewnych wyjaśnień: zakłada się, że UUID nigdy nie są używane jako klucze podstawowe. Nie wiem, skąd bierze się to założenie, ale jeszcze nie widziałem systemu, który nie pozwala na ich stosowanie jako takiego. Wiem, że to stara odpowiedź. Przypuszczam, że zalety używania UUID w systemach rozproszonych nie były wtedy tak szeroko rozumiane (?).
tne
12

Dlaczego nikt nie wspomina o wydajności? Gdy masz wiele złączeń, wszystkie oparte na tych paskudnych identyfikatorach GUID, wydajność przejdzie przez podłogę, byłem tam :(

Andrei Rînea
źródło
1
Czy możesz rozwinąć tę kwestię tak, jak w sytuacji, gdy muszę wprowadzić UUID (lub podobny), ale martwi mnie użycie ich jako klucza podstawowego.
JoeTidee
1
UUID są tylko 4 razy większe od liczb całkowitych ... (jeśli twoja baza danych ma typ UUID)
Jasen
11

Identyfikatory GUID mogą sprawić ci wiele kłopotów w przyszłości, jeśli będą używane jako „unifikatory”, umożliwiając powielanie danych w twoich tabelach. Jeśli chcesz używać identyfikatorów GUID, rozważ nadal utrzymywanie UNIKALNYCH ograniczeń w innych kolumnach.

Troels Arvin
źródło
11
To jest sedno problemu: wprowadzenie identyfikatora GUID sprawia, że ​​każdy wiersz jest unikalny. Ale nie sztuczne części wierszy mogą nagle zawierać duplikaty (kilka wersji prawdy).
Troels Arvin
8
+1, aby zrekompensować. Rozumiem, co masz na myśli, ale jest źle wyrażone.
Stefano Borini,
11

Główne zalety to to, że możesz tworzyć unikalne identyfikatory bez łączenia się z bazą danych. Identyfikatory są unikalne na całym świecie, dzięki czemu można łatwo łączyć dane z różnych baz danych. Wydaje się, że są to małe zalety, ale zaoszczędziły mi dużo pracy w przeszłości.

Głównymi wadami są nieco więcej pamięci (nie stanowi to problemu w nowoczesnych systemach), a identyfikatory nie są tak naprawdę czytelne dla człowieka. Może to stanowić problem podczas debugowania.

Istnieją pewne problemy z wydajnością, takie jak fragmentacja indeksu. Ale te są łatwe do rozwiązania (grzebienie Jimmy'ego Nillsona: http://www.informit.com/articles/article.aspx?p=25862 )

Edycja połączyła moje dwie odpowiedzi na to pytanie

@Matt Sheppard Myślę, że ma na myśli, że można powielać wiersze z różnymi identyfikatorami GUID jako klucze podstawowe. Jest to problem z dowolnym rodzajem klucza zastępczego, nie tylko GUID. I jak powiedział, można to łatwo rozwiązać, dodając znaczące unikalne ograniczenia do niekluczowych kolumn. Alternatywą jest użycie naturalnego klucza, który ma prawdziwe problemy.

Mendelt
źródło
Wiem o prowadnicach grzebieniowych i tych, które pomagają rozwiązać problem indeksowania (wydajność INSERT). „ główne wady wymagają nieco więcej miejsca ” Czy wpłynie to na wydajność z powodu dużego rozmiaru pliku bazy danych?
Amit Joshi,
8

Jeszcze jeden mały problem do rozważenia przy użyciu GUIDS jako kluczy podstawowych, jeśli również używasz tej kolumny jako indeksu klastrowego (stosunkowo powszechna praktyka). Będziesz miał trafienie na wstawkę ze względu na to, że GUID i tak nie zaczyna się sekwencyjnie, więc podczas wstawiania będą to podziały stron itp. Tylko coś do rozważenia, jeśli system będzie miał wysokie IO ...

WIDBA
źródło
6

primary-keys-ids-versus-guids

Koszt identyfikatorów GUID jako kluczy podstawowych (SQL Server 2000)

Mity, GUID vs. Autoincrement (MySQL 5)

To jest naprawdę to, czego chcesz.

Zalety UID

  • Unikalny dla każdej tabeli, każdej bazy danych, każdego serwera
  • Umożliwia łatwe łączenie rekordów z różnych baz danych
  • Umożliwia łatwą dystrybucję baz danych na wielu serwerach
  • Możesz generować identyfikatory w dowolnym miejscu, bez konieczności przechodzenia do bazy danych
  • Większość scenariuszy replikacji i tak wymaga kolumn GUID

Wady GUID

  • Jest to 4 razy większa niż tradycyjna 4-bajtowa wartość indeksu; może to mieć poważne konsekwencje dla wydajności i przechowywania, jeśli nie będziesz ostrożny
  • Uciążliwe do debugowania (gdzie identyfikator użytkownika = „{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}”)
  • Wygenerowane identyfikatory GUID powinny być częściowo sekwencyjne, aby uzyskać najlepszą wydajność (np. Newsequentialid () w SQL 2005) i umożliwić korzystanie z indeksów klastrowych
wener
źródło
1

Jest jedna rzecz, która tak naprawdę nie została rozwiązana, a mianowicie użycie losowych identyfikatorów (UUIDv4), ponieważ klucze podstawowe mogą zaszkodzić wydajności indeksu kluczy podstawowych . Stanie się tak niezależnie od tego, czy twój stół jest skupiony wokół klucza.

RDBM zazwyczaj zapewniają unikalność kluczy podstawowych i zapewniają wyszukiwanie według klucza w strukturze o nazwie BTree, która jest drzewem wyszukiwania o dużym współczynniku rozgałęzienia (drzewo wyszukiwania binarnego ma współczynnik rozgałęzienia 2). Teraz sekwencyjny identyfikator liczby całkowitej spowodowałby, że wstawki występują tylko po jednej stronie drzewa, pozostawiając większość węzłów liści nietkniętych. Dodanie losowych UUID spowoduje, że wstawki podzielą węzły liści w całym indeksie.

Podobnie, jeśli przechowywane dane są przeważnie tymczasowe, często zdarza się, że dostęp do najnowszych danych wymaga największego dostępu. W przypadku losowych identyfikatorów UUID wzorce nie skorzystają z tego i trafią do większej liczby wierszy indeksu, tym samym potrzebując więcej stron indeksu w pamięci. W przypadku sekwencyjnych identyfikatorów, jeśli najbardziej potrzebne są najnowsze dane, gorące strony indeksu wymagałyby mniej pamięci RAM.

Antti Haapala
źródło