Używanie identyfikatorów UUID w Mongo jest z pewnością możliwe i dość dobrze obsługiwane. Na przykład dokumenty Mongo wymieniają UUID jako jedną z typowych opcji dla _id
pole.
Rozważania
- Wydajność – Jak wspominają inne odpowiedzi, testy porównawcze pokazują, że identyfikatory UUID powodują spadek wydajności w przypadku wstawek. W najgorszym zmierzonym przypadku (od 10 mln do 20 mln dokumentów w kolekcji) są one około 2-3 razy wolniejsze – różnica między wstawianiem 2000 (UUID) i 7500 (ObjectID) dokumentów na sekundę. To duża różnica, ale jej znaczenie zależy wyłącznie od przypadku użycia. Czy będziesz wstawiać wsadowo miliony dokumentów naraz? W przypadku większości aplikacji, które zbudowałem, powszechnym przypadkiem jest wstawianie pojedynczych dokumentów. Te same testy porównawcze pokazują, że dla tego wzorca użytkowania różnica jest dużo mniejszy (6250 w porównaniu z 7500; ~20%). Nie bez znaczenia… ale też nie wstrząsające ziemią.
- Przenośność – Wiele innych platform DB ma dobrą obsługę UUID, więc przenośność zostałaby poprawiona. Alternatywnie, ponieważ identyfikatory UUID są większe (więcej bitów), możliwe jest przepakowanie identyfikatora ObjectID w „kształt” identyfikatora UUID. To podejście nie jest tak przyjemne, jak bezpośrednia przenośność, ale umożliwia „mapowanie” między istniejącymi identyfikatorami ObjectID i UUID.
- Decentralizacja – Jednym z największych atutów UUID jest to, że są one uniwersalne i niepowtarzalne. To sprawia, że praktyczne jest ich generowanie w dowolnym miejscu, w sposób zdecentralizowany (w przeciwieństwie do na przykład wartości autoinkrementacji, która wymaga scentralizowanego źródła prawdy w celu określenia „następnej” wartości). Oczywiście identyfikatory obiektów Mongo również świadczą o tej korzyści. Różnica polega na tym, że identyfikatory UUID są oparte na ponad 15-letnim standardzie i są obsługiwane na (prawie?) wszystkich platformach, językach itp. To czyni je bardzo przydatnymi, jeśli kiedykolwiek będziesz musiał tworzyć encje (a konkretnie zestawy powiązanych podmiotów) w rozłącznych systemach, bez interakcji z bazą danych. Możesz utworzyć zestaw danych z identyfikatorami i kluczami obcymi, a następnie zapisać cały wykres w bazie danych w pewnym momencie w przyszłości bez konfliktów. Chociaż jest to również możliwe w przypadku identyfikatorów Mongo ObjectID, znalezienie kodu do ich wygenerowania/pracy z formatem będzie często trudniejsze.
Poprawki
W przeciwieństwie do niektórych innych odpowiedzi:
- UUID mają natywną obsługę Mongo – Możesz użyć
UUID()
funkcji w Mongo Shell dokładnie w taki sam sposób, w jaki używaszObjectID()
; przekonwertować ciąg znaków UUID na równoważny obiekt BSON. - UUID nie są szczególnie duże – W przypadku zakodowania przy użyciu binarnego podtypu
0x04
są 128 bitów, w porównaniu do 96 bitów dla ObjectIDs. (Jeśli zostaną zakodowane jako ciągi, będą) być dość marnotrawnym, zajmując około 288 bitów). - UUID mogą zawierać znacznik czasu – W szczególności UUIDv1 koduje znacznik czasu z 60-bitową precyzją, w porównaniu z 32-bitowymi identyfikatorami ObjectID. To o ponad 6 rzędów wielkości większa precyzja, czyli nanosekundy zamiast sekund. W rzeczywistości może to być przyzwoity sposób przechowywania znaczników czasu tworzenia z większą dokładnością niż obsługa obiektów daty Mongo/JS, jednak...
- Wbudowanie w
UUID()
funkcja generuje tylko identyfikatory UUID v4 (losowe), więc aby to wykorzystać, powinieneś oprzeć się na swojej aplikacji lub sterowniku Mongo do tworzenia identyfikatorów. - W przeciwieństwie do identyfikatorów ObjectID, ze względu na sposób, w jaki identyfikatory UUID są podzielone, znacznik czasu nie zapewnia naturalnej kolejności. Może to być dobre lub złe, w zależności od przypadku użycia. (Nowe standardy mogą to zmienić; zobacz aktualizację 2021 poniżej).
- Dołączanie sygnatur czasowych do identyfikatorów jest czasem złym pomysłem. W końcu wyciekasz z utworzonego czasu dokumentów w dowolnym miejscu, w którym ujawniany jest identyfikator. (Oczywiście identyfikatory ObjectID również kodują znacznik czasu, więc jest to częściowo prawdziwe dla nich).
- Jeśli robisz to za pomocą (zgodnych ze specyfikacją) UUID v1, kodujesz również część adresu MAC serwera, który może potencjalnie być używane do identyfikacji maszyny. Prawdopodobnie nie jest to problem dla większości systemów, ale też nie jest idealny. (Nowe standardy mogą to zmienić; zobacz aktualizację 2021 poniżej).
- Wbudowanie w
Wniosek
Jeśli myślisz o swoim Mongo DB w izolacji, ObjectIDs są oczywistym wyborem. Działają dobrze po wyjęciu z pudełka i są doskonale sprawne domyślnie. Używanie identyfikatorów UUID zamiast tak dodaj trochę tarcia, zarówno podczas pracy z wartościami (konieczność konwersji na typy binarne itp.), Jak i pod względem wydajności. To, czy ta niewielka niedogodność jest warta posiadania znormalizowanego formatu identyfikatora, naprawdę zależy od wagi, jaką przywiązujesz do przenośności i wyborów architektonicznych.
Czy będziesz synchronizować dane między różnymi platformami baz danych? Czy w przyszłości przeniesiesz swoje dane na inną platformę? Czy musisz generować identyfikatory na zewnątrz w bazie danych, w innych systemach lub w przeglądarce? Jeśli nie teraz, w przyszłości? UUID mogą być warte zachodu.
Aktualizacja z sierpnia 2021
IEFT niedawno opublikował projekt aktualizacji specyfikacji UUID, która wprowadziłaby kilka nowych wersji formatu.
W szczególności UUIDv6 i UUIDv7 są oparte na UUIDv1, ale odwracają fragmenty sygnatury czasowej, aby bity były ułożone od najbardziej znaczącego do najmniej znaczącego. Daje to wartościom wynikowym naturalny porządek, który (mniej więcej) odzwierciedla porządek, w jakim zostały utworzone. Nowe wersje wykluczają również dane pochodzące z adresu MAC serwera, odpowiadając na długotrwałą krytykę identyfikatorów UUID v1.
Przejście tych zmian do wdrożeń zajmie trochę czasu, ale (IMHO) znacząco unowocześniają i ulepszają format.