Generalnie używam identyfikatorów automatycznego przyrostu jako kluczy podstawowych w bazach danych. Próbuję poznać zalety korzystania z GUID. Przeczytałem ten artykuł: https://betterexplained.com/articles/the-quick-guide-to-guids/
Zdaję sobie sprawę, że te identyfikatory GUID są używane do identyfikacji obiektów na poziomie aplikacji. Czy są one również przechowywane jako klucz podstawowy na poziomie bazy danych. Powiedzmy, że miałem następującą klasę:
public class Person
{
public GUID ID;
public string Name;
..
//Person Methods follow
}
Powiedzmy, że chciałem utworzyć nową osobę w pamięci, a następnie wstawić osobę do bazy danych. Czy mogę to po prostu zrobić:
Person p1 = new Person();
p1.ID=GUID.NewGUID();
PersonRepository.Insert(p1);
Powiedzmy, że mam bazę danych zawierającą miliony wierszy z identyfikatorem GUID jako kluczem podstawowym. Czy to zawsze będzie wyjątkowe? Czy w ogóle rozumiem identyfikatory GUID?
Przeczytałem ten artykuł wcześniej: http://enterprisecraftsmanship.com/2014/11/15/cqs-with-database-generated-ids/ . Trochę mnie to myli, ponieważ wydaje się, że polecam szczęśliwe medium między identyfikatorami GUID a liczbami całkowitymi jako kluczami głównymi.
Edytuj 11/06/18
Doszedłem do wniosku, że Przewodniki są bardziej odpowiednie niż ints do moich wymagań. W dzisiejszych czasach używam CQRS, a identyfikatory GUID są ładniejsze.
Zauważam, że niektórzy programiści modelują identyfikatory GUID jako ciągi w modelu domeny, np. Tutaj: https://github.com/dotnet-architecture/eShopOnContainers/blob/dev/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/ Buyer.cs - w tym przypadku: IdentityGuid to identyfikator GUID modelowany jako ciąg. Czy jest jakiś powód, aby to zrobić poza tym, co podano tutaj: Użyć obiektu wartości niestandardowej lub identyfikatora GUID jako identyfikatora jednostki w systemie rozproszonym? . Czy modelowanie identyfikatora GUID jako ciągu jest „normalne”, czy powinienem modelować go jako identyfikator GUID w modelu i bazie danych?
źródło
Odpowiedzi:
Identyfikatory GUID są z definicji „globalnie unikatowymi identyfikatorami”. Istnieje podobna, ale nieco inna koncepcja w Javie o nazwie UUID „Uniwersalnie unikalne identyfikatory”. Nazwy są wymienne dla wszystkich praktycznych zastosowań.
Identyfikatory GUID są kluczowe dla sposobu, w jaki Microsoft przewidział klastrowanie bazy danych do pracy, a jeśli musisz uwzględnić dane z czasami połączonych źródeł, naprawdę pomagają zapobiegać kolizjom danych.
Kilka faktów Pro-GUID:
Niektóre brzydoty z GUID
Identyfikatory GUID zwiększą indeksy, więc koszt miejsca na dysku na indeksowanie kolumny będzie wyższy. Losowe identyfikatory GUID fragmentują twoje indeksy.
Jeśli wiesz, że nie zamierzasz synchronizować danych z różnych sieci, identyfikatory GUID mogą przenosić więcej kosztów ogólnych, niż są warte.
Jeśli musisz pobierać dane od czasami połączonych klientów, mogą one być znacznie bardziej odporne na zapobieganie kolizjom kluczy niż poleganie na ustawianiu zakresów sekwencji dla tych klientów.
źródło
Zawsze? nie, nie zawsze; to skończona sekwencja bitów.
Miliony, prawdopodobnie jesteś bezpieczny. Milion milionów, a prawdopodobieństwo kolizji staje się znaczące. Są jednak dobre wieści: do tego czasu zabrakło już miejsca na dysku.
Możesz; to nie jest całkiem dobry pomysł. Twój model domeny zwykle nie powinien generować liczb losowych; powinny stanowić dane wejściowe do twojego modelu.
Poza tym, gdy masz do czynienia z niewiarygodną siecią, w której możesz otrzymywać zduplikowane wiadomości, deterministycznie wygenerowany UUID ochroni cię przed zduplikowaniem jednostek. Ale jeśli przypiszesz każdemu nowy losowy numer, będziesz mieć więcej pracy do zidentyfikowania duplikacji.
Zobacz opis UUID oparty na nazwie w RFC 4122
Myślę, że to nie ma większego znaczenia. W większości modeli domen jest to identyfikator ; jedynym pytaniem, które o to pytasz, jest to, czy jest takie samo jak jakiś inny identyfikator. Twój model domeny zwykle nie patrzy na reprezentację identyfikatora w pamięci.
Jeśli GUID jest dostępny jako „typ pierwotny” w ustawieniu agnostycznym Twojej domeny, użyłbym go; pozwala kontekstowi pomocniczemu wybrać odpowiednie optymalizacje, które mogą być dostępne.
Należy jednak pamiętać, że reprezentacja identyfikatora, zarówno w pamięci, jak i w pamięci, jest decyzją, którą podejmujesz w swojej implementacji, i dlatego powinieneś podjąć kroki w celu zapewnienia, że odcisk kodu połączony z tym decyzja jest niewielka - patrz Parnas 1972 .
źródło
Identyfikator GUID lub UUID najprawdopodobniej będzie unikalny ze względu na sposób ich generowania i zapewnią bezpieczny sposób zagwarantowania niepowtarzalności bez konieczności komunikowania się z organem centralnym.
Korzyści z GUID jako klucza podstawowego:
W podanym przykładzie:
Określenie identyfikatora GUID przed czasem wstawienia może zaoszczędzić podróż w obie strony do bazy danych podczas wstawiania kolejnych rekordów potomnych i umożliwić ich zatwierdzenie w tej samej transakcji.
Szkodliwe dla GUID jako klucza podstawowego:
Jeśli aplikacja nie wymaga dzielenia ani klastrowania, najlepiej trzymać się mniejszych, prostszych typów danych, takich jak int lub bigint.
Wiele baz danych ma własne implementacje wewnętrzne, które próbują złagodzić problemy z pamięcią masową spowodowane przez GUID, a SQL Server ma nawet funkcję newsequentialid, która pomaga w uporządkowaniu UUID, umożliwiając lepsze wykorzystanie indeksów i ogólnie mają lepszą charakterystykę wydajności.
Ponadto z perspektywy testera, użytkownika lub programisty współpracującego z aplikacją użycie identyfikatora nad identyfikatorem GUID znacznie poprawi komunikację. Wyobraź sobie, że musisz czytać GUID przez telefon.
Ostatecznie, chyba że klastrowanie lub zaciemnianie adresów URL na dużą skalę jest wymogiem, bardziej pragmatyczne jest trzymanie się identyfikatorów z automatyczną inkrementacją.
źródło
Powiedziałbym, że nie, nie używaj identyfikatorów GUID jako kluczy podstawowych. Właściwie mam teraz do czynienia z takim DB i są one jedną z głównych przyczyn problemów z wydajnością.
Dodatkowe 12 bajtów sumuje się szybko; pamiętaj, że większość PK będzie FK w innych tabelach, a tylko trzy FK w tabeli masz teraz 48 bajtów dodatkowych na każdy wiersz. To sumuje się w tabeli i indeksach. Dodaje się także do dysku I / O. Te dodatkowe 12 bajtów należy odczytać i zapisać.
A jeśli nie używasz sekwencyjnych prowadnic, a PK są grupowane (co dzieje się domyślnie), SQL będzie od czasu do czasu musiał przenosić całe strony danych, aby ściśnąć więcej w odpowiednie „miejsce”. W przypadku bazy danych zawierającej transakcje z dużą ilością wstawek, aktualizacji i usunięć, rzeczy szybko się psują.
Jeśli potrzebujesz jakiegoś unikalnego identyfikatora do synchronizacji lub czegoś takiego, dodaj kolumnę Guid. Tylko nie rób tego PK.
źródło
Jest to zdecydowanie najważniejszy powód używania identyfikatorów GUID.
Ogromną zaletą jest fakt, że możesz utworzyć unikalny identyfikator bez wiedzy kodu lub komunikowania się z nim.
Możesz być pewien, że obiekt Osoby, który właśnie wygenerowałeś na swoim serwerze, telefonie PC, laptopie, urządzeniu offline lub czymkolwiek innym, jest unikalny na wszystkich twoich serwerach na całym świecie, bez względu na to, jak rozproszony.
Możesz umieścić go w dowolnym pliku bazy danych rdb lub no-sql, plik, wysłać do dowolnej usługi internetowej lub wyrzucić go natychmiast, gdy nie jest potrzebny
Nie, nigdy nie dojdzie do kolizji.
Tak, płytki mogą być nieco wolniejsze, ponieważ indeks może wymagać zmiany.
Tak, jest większy niż int.
Wiem, że wiele osób jest przekonanych o auto inc ints i jest to kontrowersyjny temat dotyczący DBA
Ale tak naprawdę nie mogę powiedzieć wystarczająco silnego przewodnika. Powinieneś używać prowadnic domyślnie w każdej aplikacji.
auto inc ints ma wiele wad
Korzystasz z rozproszonej bazy danych No-Sql. Po prostu nie możesz rozmawiać ze wszystkimi innymi instancjami, aby dowiedzieć się, jaki jest następny numer.
Korzystasz z systemu kolejki komunikatów. Rzeczy potrzebują identyfikatorów, zanim trafią do bazy danych
Tworzysz kilka elementów i edytujesz je przed zapisaniem. Każdy potrzebuje identyfikatora, zanim trafisz na db
Chcesz usunąć i ponownie wstawić wiersze. Upewnij się, że nie policzysz swoich automatycznych identyfikatorów i zabraknie!
Nie chcesz ujawniać wszystkim zamówieniom, które podjąłeś w tym roku
Chcesz przenosić zanonimizowane dane z produkcji w celu przetestowania i utrzymania nienaruszonych relacji. Ale nie usuwaj wszystkich istniejących danych testowych.
Chcesz scalić produkt z jednym najemcą w bazie danych z wieloma dzierżawcami, ale każdy ma zamówienie 56.
Tworzysz obiekty, które są trwałe, ale efemeryczne. (niekompletne zamówienia) ponownie, nie wykorzystuj wszystkich swoich ints z rzeczami, których już nie ma.
Lista jest nieskończona i wszystkie są prawdziwymi problemami, które przytrafiają się ludziom przez cały czas. w przeciwieństwie do wyczerpania miejsca na dysku z powodu nieco większych plików FK col
Wreszcie ogromnym problemem związanym z ints jest to, że ich zabrakło !!! ok teoretycznie nie, są ładunki. Ale w praktyce robisz tak, ponieważ ludzie nie traktują ich jak liczb losowych bez żadnego znaczenia. robią takie rzeczy
och, nie chcę, żeby klienci myśleli, że jesteśmy nowi. zacznij od 10.000
Musiałem zaimportować ładunek danych, więc po prostu zwiększyłem ziarno do 1 m, abyśmy wiedzieli, co jest importowane
potrzebujemy kategorii danych. każdy okres zaczyna się od następnego miliona, więc możemy użyć pierwszych cyfr jako magicznej liczby
Usunąłem i ponownie zaimportowałem wszystkie dane z nowymi identyfikatorami. Tak, nawet dzienniki kontroli.
użyj tego numeru, który jest kluczem złożonym, jako id tej drugiej rzeczy
źródło
Właśnie tam powinieneś przestać, dokładnie tam i przemyśleć.
Klucz podstawowy bazy danych NIGDY nie powinien mieć znaczenia biznesowego. Z definicji powinien być bez znaczenia.
Dodaj GUID jako klucz biznesowy i normalny klucz podstawowy (zwykle długi int) jako klucz podstawowy bazy danych. Zawsze możesz umieścić unikalny indeks w GUID, aby zapewnić unikalność.
Mówi się oczywiście o teorii baz danych, ale jest to również dobra praktyka. Miałem do czynienia z bazami danych, w których klucze podstawowe miały znaczenie biznesowe (jeden klient pomyślał, aby zaoszczędzić część zasobów bazy danych, wykorzystując je np. Jako numery pracowników, numery klientów itp.) I zawsze prowadzi to do problemów.
źródło
Zawsze używaj generowanych przez bazę danych, automatycznie zwiększających klucze podstawowe (PK).
Dlaczego warto korzystać z automatycznego zwiększania wartości zamiast GUID / UUID?
Ale jak radzić sobie z odłamkami, klastrami itp.?
3-kolumnowa PK dla tabeli klastrowej może być ...
Ale co z...?
Wiele podróży do bazy danych - większość aplikacji nie musi jednoznacznie identyfikować tworzonego rekordu, dopóki nie zostanie on wstawiony do bazy danych, ponieważ ten wątek / sesja / cokolwiek działa tylko na jednym na raz. Jeśli aplikacja naprawdę potrzebuje tej możliwości, użyj wygenerowanej przez aplikację tymczasowej PK, która nie jest wysyłana do bazy danych . Niech baza danych umieści następnie swój własny PK przyrost w wierszu po wstawieniu. Wstawki będą używać tymczasowego PK, podczas gdy aktualizacje i usuwanie będą wykorzystywać stały PK przypisany przez bazę danych.
Wydajność - komputery mogą przetwarzać proste liczby całkowite znacznie szybciej niż cokolwiek innego ze względu na znacznie większą domenę, jeśli to możliwe, wartości na element w identyfikatorze GUID (37) w porównaniu do liczby całkowitej (10). Pamiętaj też, że każdy znak w GUID musi najpierw zostać przekonwertowany na liczbę, aby procesor mógł nim manipulować.
Częste nadużycia kluczy podstawowych PK mają tylko jeden cel ... absolutnie unikalne zidentyfikowanie wiersza w tabeli. Wszystko inne jest zbyt powszechnym niewłaściwym użyciem.
Wykrywanie brakujących danych
Sortowanie
źródło
Jak wszystko inne, ma to swoje zalety i wady:
Dobry:
Twoje klucze są zawsze tej samej długości (bardzo duże bazy danych mogą mieć bardzo duże klucze)
Wyjątkowość jest prawie gwarantowana - nawet jeśli generujesz je z oddzielnego systemu i / lub nie czytasz ostatniego identyfikatora z bazy danych
Źli:
Jak wspomniano dużo powyżej - większe indeksy i magazyn danych.
Nie możesz zamówić według ID, musisz złożyć zamówienie w inny sposób. Więcej indeksów, prawdopodobnie mniej wydajnych.
Są mniej czytelne dla ludzi. Liczby całkowite są na ogół łatwiejsze do analizowania, zapamiętywania i pisania dla ludzi. Używanie identyfikatorów GUID jako identyfikatorów w klauzulach WHERE w wielu połączonych tabelach może spowodować stopienie głowy.
Jak wszystko, używaj ich tam, gdzie jest to właściwe, nie bądź dogmatyczny - w wielu sytuacjach auto-inkrementujące liczby całkowite są lepsze, czasami GUID są świetne.
źródło
Tak, możesz użyć GUID jako klucza podstawowego. Minusem jest rozmiar i szybkie rozdrobnienie indeksu.
O ile nie potrzebujesz wyjątkowości w bazach danych (np. Klastrze), preferowana jest liczba całkowita.
źródło
Oto moje podejście do tego problemu - rozwiązaniem jest pół drogi między wartościami GUID a int, biorąc to, co najlepsze z obu.
Klasa generuje pseudolosową (ale rosnącą z czasem) wartość Id, która jest podobna do identyfikatora GUID Comb .
Kluczową zaletą jest to, że pozwala na generowanie wartości Id na kliencie, zamiast używania wartości automatycznego przyrostu generowanych na serwerze (co wymaga podróży w obie strony) przy prawie zerowym ryzyku duplikacji wartości.
Wygenerowane wartości używają tylko 8 bajtów zamiast 16 dla GUID i nie są zależne od jednego konkretnego porządku sortowania bazy danych (np. Serwer Sql dla GUID ). Wartości można rozszerzyć, aby używały całego dalekiego zasięgu bez znaku, ale spowodowałoby to problemy z dowolną bazą danych lub innym repozytorium danych, które ma tylko podpisane typy całkowite.
źródło