Obiekty Domeny jako identyfikatory tworzą pewne złożone / subtelne problemy:
Serializacja / deserializacja
Przechowywanie obiektów jako kluczy spowoduje, że serializacja wykresu obiektów będzie wyjątkowo skomplikowana. stackoverflowPodczas wykonywania naiwnej serializacji do JSON lub XML wystąpią błędy z powodu rekurencji. Będziesz wtedy musiał napisać niestandardowy serializator, który konwertuje rzeczywiste obiekty w celu użycia ich identyfikatorów zamiast serializacji instancji obiektu i utworzenia rekurencji.
Przekaż obiekty dla bezpieczeństwa typu, ale przechowuj tylko identyfikatory, wtedy możesz mieć metodę akcesora, która leniwie ładuje powiązaną jednostkę, gdy zostanie wywołana. Buforowanie drugiego poziomu zajmie się kolejnymi połączeniami.
Subtelne wycieki referencyjne:
Jeśli użyjesz obiektów domeny w konstruktorach takich, jakie masz, utworzysz odwołania cykliczne, które będą bardzo trudne do odzyskania pamięci dla obiektów nieużywanych aktywnie.
Idealna sytuacja:
Nieprzezroczyste identyfikatory vs int / long:
idPowinna być całkowicie nieprzezroczysta identyfikatorem, który niesie żadnej informacji o tym, co go identyfikuje. Ale powinien oferować pewną weryfikację, czy jest to prawidłowy identyfikator w swoim systemie.
Surowe typy łamią to:
int, longi Stringsą najczęściej używanymi typami surowymi dla identyfikatorów w systemie RDBMS. Istnieje długa historia praktycznych powodów, które sięgają dziesięcioleci i wszystkie są kompromisami, które albo pasują do oszczędzania, spacealbo do oszczędzania, timealbo do obu.
Identyfikatory sekwencyjne są najgorszymi przestępcami:
Podczas używania identyfikatora sekwencyjnego domyślnie pakowane są do niego informacje semantyczne. Co nie jest złe, dopóki nie zostanie użyte. Kiedy ludzie zaczynają pisać logikę biznesową, która sortuje lub filtruje semantyczną jakość identyfikatora, tworzą świat bólu dla przyszłych opiekunów.
String pola są problematyczne, ponieważ naiwni projektanci umieszczają informacje w treści, zwykle także w semantyce czasowej.
To sprawia, że niemożliwe jest również stworzenie rozproszonego systemu danych, ponieważ nie12437379123 jest on unikalny na całym świecie. Szanse na to, że inny węzeł w systemie rozproszonym utworzy rekord o tej samej liczbie, są prawie całkowicie zagwarantowane, jeśli dostaniesz wystarczającą ilość danych w systemie.
Potem zaczynają się wokół niego hacki i cała ta rzecz przekształca się w kupę parującego bałaganu.
Ignorowanie ogromnych systemów rozproszonych ( klastrów ) staje się kompletnym koszmarem, gdy zaczniesz próbować udostępniać dane również innym systemom. Zwłaszcza, gdy drugi system nie jest pod twoją kontrolą.
Ostatecznie masz ten sam problem, jak uczynić swój identyfikator globalnym unikalnym.
UUID został utworzony i ustandaryzowany z następującego powodu:
UUIDmogą wystąpić wszystkie wyżej wymienione problemy, w zależności od tego, którego Versionużywasz.
Version 1używa adresu MAC i czasu, aby utworzyć unikalny identyfikator. Jest to złe, ponieważ przenosi semantyczne informacje o lokalizacji i czasie. Sam w sobie nie stanowi to problemu, kiedy naiwni programiści zaczynają polegać na tych informacjach w logice biznesowej. To powoduje także wyciek informacji, które można wykorzystać w próbach włamania.
Version 2wykorzystuje użytkowników UIDlub GIDdomian UIDlub GUImiejsce z tego czasu Version 1jest tak samo złe jak Version 1wyciek danych i ryzykuje, że informacje te zostaną wykorzystane w logice biznesowej.
Version 3jest podobny, ale zastępuje adres MAC i czas MD5hashem o pewnej tablicy byte[]z czegoś, co zdecydowanie ma znaczenie semantyczne. Nie ma wycieków danych, o które byte[]można się martwić, nie można ich odzyskać UUID. Daje to dobry sposób na deterministyczne tworzenie UUIDformularzy instancji i pewnego rodzaju klucza zewnętrznego .
Version 4 opiera się tylko na liczbach losowych, co jest dobrym rozwiązaniem, nie zawiera absolutnie żadnych informacji semantycznych, ale nie jest deterministycznie odtwarzalne.
Version 5jest jak, Version 4ale używa sha1zamiast md5.
Klucze domeny i klucze danych transakcyjnych
Moje preferencje dotyczące identyfikatorów obiektów domeny to używanie Version 5lub, Version 3jeśli z Version 5jakiegoś powodu technicznego jest to ograniczone .
Version 3 doskonale nadaje się do danych transakcyjnych, które mogą być rozłożone na wiele komputerów.
Jeśli nie jesteś ograniczony przestrzenią, użyj UUID:
Gwarantujemy unikalność, zrzucanie danych z jednej bazy danych i ponowne ładowanie do innej, nigdy nie musiałeś się martwić o zduplikowane identyfikatory, które faktycznie odnoszą się do różnych danych domeny.
Version 3,4,5 są całkowicie nieprzejrzyste i właśnie takie powinny być.
Możesz mieć jedną kolumnę jako klucz podstawowy za pomocą, UUIDa następnie możesz mieć złożone unikalne indeksy dla tego, co byłoby naturalnym złożonym kluczem podstawowym.
Pamięć masowa również nie musi CHAR(36). Możesz przechowywać UUIDw natywnym polu bajt / bit / liczba dla danej bazy danych, o ile jest ona nadal indeksowana.
Dziedzictwo
Jeśli masz typy RAW i nie możesz ich zmienić, nadal możesz wyodrębnić je w kodzie.
Używanie Version 3/5z UUIDwas może przejść w Class.getName()+ String.valueOf(int)postaci byte[]i mają nieprzezroczyste klucza odniesienia, który jest recreatable i deterministyczny.