Wiem, że tego typu pytania często się pojawiają, ale jeszcze nie przeczytałem żadnych przekonujących argumentów, które pomogłyby mi w podjęciu tej decyzji. Proszę o wyrozumiałość!
Mam ogromną bazę danych - rośnie o około 10 000 000 rekordów dziennie. Dane są relacyjne i ze względu na wydajność ładuję tabelę BULK COPY. Z tego powodu muszę wygenerować klucze do wierszy i nie mogę polegać na kolumnie TOŻSAMOŚCI.
64-bitowa liczba całkowita - bigint - jest na tyle szeroka, że mogę jej używać, ale aby zagwarantować wyjątkowość, potrzebuję scentralizowanego generatora, który utworzy dla mnie moje identyfikatory. Obecnie mam taką usługę generatora, która pozwala usłudze rezerwować numery sekwencyjne X i gwarantuje brak kolizji. Jednak konsekwencją tego jest to, że wszystkie usługi, które mam, zależą od tego jednego scentralizowanego generatora, więc jestem ograniczony w sposobie dystrybucji mojego systemu i nie jestem zadowolony z innych nałożonych zależności (takich jak wymaganie dostępu do sieci) według tego projektu. Czasami był to problem.
Zastanawiam się teraz nad użyciem sekwencyjnych identyfikatorów GUID jako moich kluczy podstawowych (generowanych zewnętrznie w języku SQL). O ile udało mi się ustalić na podstawie własnych testów, jedyną wadą jest narzut miejsca na dysku w szerszym typie danych (co pogarsza ich użycie w indeksach). Nie widziałem żadnego zauważalnego spowolnienia wydajności zapytań w porównaniu do alternatywy Bigint. Ładowanie do stołu BULK COPY jest nieco wolniejsze, ale niewiele. Moje indeksy oparte na GUID nie ulegają fragmentacji dzięki mojej sekwencyjnej implementacji GUID.
Zasadniczo chcę wiedzieć, czy są jakieś inne względy, które mogłem przeoczyć. W tej chwili jestem skłonny zrobić skok i zacząć korzystać z GUID. W żadnym wypadku nie jestem ekspertem od baz danych, więc naprawdę doceniłbym wszelkie wskazówki.
źródło
Odpowiedzi:
Jestem w podobnej sytuacji. Obecnie używam sekwencyjnego podejścia GUID i nie mam fragmentacji i łatwego generowania klucza.
Zauważyłem dwie wady, które spowodowały, że zacząłem migrować do bigint:
(2) Był dla mnie zabójcą.
Teraz wygeneruję moje klucze w następujący sposób:
Będę używał wiodącej daty plus godziny, a potem będę miał sekwencję . To pozwala mi przesyłać zapytania o dane według daty bez żadnego indeksu dodawania. To dla mnie niezły bonus.
Wygeneruję sekwencyjną część biginta przy użyciu algorytmu HiLo , który dobrze nadaje się do dystrybucji .
Mam nadzieję, że niektóre z tych przeniesień do twojej sytuacji. Zdecydowanie polecam użycie biginta.
źródło
Przy typie
INT
, zaczynając od 1, otrzymujesz ponad 2 miliardy możliwych wierszy - powinno to być więcej niż wystarczające w zdecydowanej większości przypadków. DziękiBIGINT
, można uzyskać w przybliżeniu 922 biliardów (922 z 15 zerami - 922'000 miliardów) - wystarczy dla ciebie ??Jeśli użyjesz wartości
INT IDENTITY
początkowej od 1 i wstawisz wiersz co sekundę, potrzebujesz 66,5 lat, zanim osiągniesz limit 2 miliardów ...Jeśli użyjesz wartości
BIGINT IDENTITY
początkowej od 1 i wstawisz tysiąc wierszy co sekundę, potrzebujesz zadziwiającego 292 milionów lat, zanim osiągniesz limit 922 biliardów ...Używając 10 milionów wierszy dziennie, to zajmie ci wystarczającą liczbę danych na około 1'844'674'407'370 dni ( 1844 miliardów dni lub tyknięcie ponad 5 miliardów lat ) danych - czy to wystarczy dla twoich potrzeb ?
Przeczytaj więcej na ten temat (ze wszystkimi dostępnymi opcjami) w MSDN Books Online .
źródło
BIGINT
tak szybko zasięgu ...BIGINT IDENTITY
?Zalecam użycie SEQUENCE typu danych BIGINT w SQL 2012. Jest to o wiele bardziej elastyczne niż TOŻSAMOŚĆ z opcjami takimi jak cache / nocache, możesz także przypisać zakres sekwencji dla operacji wsadowej jako sp_sequence_get_range.
źródło
Czy nie możesz użyć TOŻSAMOŚCI, ponieważ istnieją już relacje kluczy obcych między ładowanymi oddzielnymi tabelami? I czy nie ma innego naturalnego klucza, aby móc połączyć je w operacji z obszaru przejściowego do obszaru produkcyjnego? Z tego powodu chciałbym dowiedzieć się nieco więcej o tym, jak są one obecnie „połączone” w systemie źródłowym, zanim zaczniesz kopiować zbiorczo? Czy wiele systemów źródłowych po prostu używa własnych sekwencji i ma możliwość wystąpienia sprzecznych sekwencji po wprowadzeniu do wspólnej bazy danych?
Znana mi jest technika COMB ID / sekwencyjny GUID i jest ona wykonalna za każdym razem, gdy efektywnie potrzebujesz globalnej unikalności przypisanej poza bazą danych - jest to faktycznie użyteczna tożsamość wiersza zarówno w bazie danych, jak i poza nią. Z tego powodu w wysoce rozproszonych środowiskach lub rozłączonych scenariuszach jest to dobry wybór
Z wyjątkiem sytuacji, gdy naprawdę tego nie potrzebujesz, ponieważ ta dodatkowa różnica szerokości jest znacząca, gdy rośnie rozmiar danych, a klucze te znajdują się w każdym indeksie i zestawach roboczych dla wielu zapytań.
Ponadto przy rozproszonym generowaniu, jeśli wiersze nie są w rzeczywistości w kolejności w kolumnie GUID, problemy z używaniem tego dla klastrowanego klucza indeksu (wąski, statyczny, rosnący) potencjalnie powoduje pewną fragmentację w porównaniu do klastrowania na TOŻSAMOŚCI pozostawać.
źródło
Ogólnie można użyć
OUTPUT
klauzuliINSERT
polecenia, aby wstawić dane do obu tabel i powiązane z polem tożsamości.Identyfikatora opartego na znaczniku czasu nie należy uważać za niezawodny - zależy to od zegara systemowego, który z kolei zależy od wielu rzeczy - od zegara sprzętowego po usługi synchronizacji czasu.
źródło