2010-08-14 7 views
5

Pytanie: Kiedy masz GUID .NET do wkładania w bazie danych, to struktura jest tak:lokalnie unikalny identyfikator

60 bits of timestamp, 
48 bits of computer identifier, 
14 bits of uniquifier, and 
6 bits are fixed, 
---- 
128 bits total 

Teraz mam problem z GUID, ponieważ jest to numer 128 bit, a niektóre z używanych DB obsługują tylko 64-bitowe liczby.

Teraz nie chcę rozwiązać dylematu za pomocą wartości bigincementu bigincution, ponieważ chcę móc wykonywać replikację offline.

Więc wpadłem na pomysł stworzenia lokalnie unikatowej klasy identyfikatorów, która jest w zasadzie GUID zmniejszona do wartości 64-bitowej.

wymyśliłem to:

day 9 bit (12*31=372 d) 
year 8 bit (2266-2010 = 256 y) 
seconds 17 bit (24*60*60=86400 s) 
hostname 12 bit (2^12=4096) 
random 18 bit (2^18=262144) 
------------------------ 
      64 bits total 

Moje pytanie brzmi: Znacznik czasu jest prawie ustalona na 34 bitach, pozostawiając mnie z 64-34 = 30 bitów dla hosta + liczbą losową.

Teraz moje pytanie: 1) Czy wolisz zwiększyć wartość bitową nazwy hosta i zmniejszyć losowy rozmiar bitu, lub zwiększyć losowy rozmiar i zmniejszyć wartość bitową nazwy hosta.

2) Czy istnieje algorytm skrótu, który redukuje każdy ciąg do n-bitów? n jest idealnie = 12 lub tak blisko jak to możliwe.

Odpowiedz

3

Faktycznie, identyfikatory GUID wygenerowane przez .NET to 6 stałych bitów i 122 bitów losowości.

Można rozważyć użycie tylko 64 bitów losowości, przy zwiększonej szansie kolizji z powodu mniejszej długości bitu. To działałoby lepiej niż hasz.

+0

Istnieją różne podejścia; Podoba mi się również pomysł "identyfikatora węzła" ze znacznikiem czasu (brak losowości). Możesz łatwo utworzyć identyfikator węzła z dowolną liczbą bitów poprzez XOR-owanie kryptograficznego skrótu (np. SHA1). Im mniej bitów, tym większa szansa na zderzenie identyfikatora węzła. "Unikalny", o którym wspomniałeś, jest faktycznie używany przez inne algorytmy Guida do obsługi zegarów systemowych cofających się, aby zachować unikatowe sygnatury czasowe na identyfikator węzła. Ale pod koniec dnia będzie ci ciężko znaleźć rozwiązanie, które zagwarantuje mniej kolizji niż czysta przypadkowość. Pamiętaj, to wszystko. NET Guids mają ... –

+0

Chociaż prawdopodobieństwo 1/2^64 jest wciąż bardzo małą liczbą, nie podoba mi się myśl o czystej losowej liczbie. Ale pomyślałem, że pominąłem skrót nazwy hosta i po prostu zwiększ liczbę losową do 30 bitów. Ale to nie jest dobry pomysł, ponieważ dla n klientów offline może to spowodować kolizję na poziomie 2^30 * n. Dla 100 klientów to tylko około jednej na 10 milionów. Przy dużym nieszczęściu można trafić w dziesiątkę ... –

+0

1/2^64 == jedna na 18 septillion (jedna septillion == jeden bilion jednego tryliona, czyli milion milionów milionów). Jeśli pójdziesz w całkowicie losowy sposób ... –

2

Jeśli przestrzeń nie jest problemem, to dlaczego nie wystarczy użyć dwóch kolumn o szerokości 64 bitów, a następnie podzielić identyfikator na pół za pomocą 8 bajtów dla każdego, a następnie przekonwertować je na swoje 64-bitowe liczby i zapisać w 2 kolumny, a następnie, jeśli kiedykolwiek będziesz musiał rozbudować system do innego, nadal będziesz wyjątkowy, musisz tylko wziąć pod uwagę ponowne łączenie dwóch kolumn.

+0

Potem będę musiał porównać dwie liczby dla każdego sprzężenia. Czy to nie obniża wydajności za dużo? –

+0

Cóż, włączysz dodatkową kolumnę w kluczu [im zakładam, że guid jest kluczem], więc będziesz miał niewielką zmianę, ale w ten sposób nie stracisz Guida na systemach, które mogą go wspierać i masz obejście dla tych, którzy tego nie robią. –

0

Po co pisać własne? Dlaczego po prostu nie wygenerować równomiernie losowej liczby? Wykona to ładnie. Po prostu weź pierwsze X cyfry, gdzie X ma żądany rozmiar ... powiedzmy 64-bity.

Zobacz here Informacje o RAND() vs. NEWID() w SQL Server, który jest naprawdę tylko oskarżeniem GUID vs generatorów liczb losowych. Zobacz także here, jeśli potrzebujesz czegoś bardziej losowego niż System.Random.

+0

Całkowicie przypadkowe liczby nie są dobrym pomysłem, IMHO. Nie chcę martwić się duplikatami i dziwnymi błędami, ponieważ baza danych staje się coraz większa. Przynajmniej znacznik czasu musi być w jakiś sposób zintegrowany. Chociaż myślenie o tym, może być mądrzejszy zostawić sekundy na zewnątrz i po prostu zwiększyć losową liczbę całkowitą. W ten sposób mogę mieć dość długą nazwę hosta i dość dużą liczbę losową. –