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. stackoverflow
Podczas 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:
id
Powinna 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
, long
i String
są 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, space
albo do oszczędzania, time
albo 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:
UUID
mogą wystąpić wszystkie wyżej wymienione problemy, w zależności od tego, którego Version
używasz.
Version 1
uż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 2
wykorzystuje użytkowników UID
lub GID
domian UID
lub GUI
miejsce z tego czasu Version 1
jest tak samo złe jak Version 1
wyciek danych i ryzykuje, że informacje te zostaną wykorzystane w logice biznesowej.
Version 3
jest podobny, ale zastępuje adres MAC i czas MD5
hashem 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 UUID
formularzy 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 5
jest jak, Version 4
ale używa sha1
zamiast md5
.
Klucze domeny i klucze danych transakcyjnych
Moje preferencje dotyczące identyfikatorów obiektów domeny to używanie Version 5
lub, Version 3
jeśli z Version 5
jakiegoś 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ą, UUID
a 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ć UUID
w 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/5
z UUID
was może przejść w Class.getName()
+ String.valueOf(int)
postaci byte[]
i mają nieprzezroczyste klucza odniesienia, który jest recreatable i deterministyczny.