Powody, dla których należy unikać dużych wartości identyfikatora

17

Pracujemy nad aplikacją internetową, która nie jest jeszcze dostępna dla użytkowników. Mój szef zauważył, że nowo utworzone rekordy mają identyfikator ponad 10 000, mimo że w tabeli mamy tylko mniej niż 100 rekordów. Zakłada, że ​​interfejs sieciowy z jakiegoś powodu tworzy ponad 100 razy więcej tymczasowych rekordów niż rzeczywiste (i usuwa je), i że może to doprowadzić nas do wyczerpania zasięgu w ciągu kilku miesięcy od wydania.

Nie sądzę, żeby miała rację co do przyczyny inflacji tożsamości (kolega, który może odpowiedzieć na to, jest na wakacjach, więc nie wiemy tego na pewno), ale załóżmy, że tak. Powiedziała, że ​​nie chciałaby używać kolumny bigint i że chciałaby, abyśmy przestali automatycznie zwiększać kolumnę identyfikatora i napisali kod po stronie serwera, który wybiera pierwszą „nieużywaną” liczbę całkowitą i używa jej jako identyfikatora.

Jestem studentem informatyki z niewielkim praktycznym doświadczeniem, pełniąc rolę młodszego programisty. Ma wieloletnie doświadczenie w zarządzaniu wszystkimi bazami danych naszej organizacji i projektowaniu większości z nich. I pomyśleć , że jest niepoprawna w tym przypadku, że bigint Identyfikator ma się czego bać i że naśladując funkcjonalność DBMS pachnie o antywzorzec projektowy. Ale jeszcze nie ufam mojemu osądowi.

Jakie są argumenty za i przeciw każdej pozycji? Jakie złe rzeczy mogą się zdarzyć, jeśli użyjemy biginta i jakie są niebezpieczeństwa związane z ponownym opracowaniem funkcji automatycznego zwiększania kół ? Czy istnieje trzecie rozwiązanie, które jest lepsze od któregoś z nich? Jakie mogą być jej powody, dla których warto unikać inflacji wartości nominalnych? Chciałbym usłyszeć również o pragmatycznych powodach - może identyfikatory bigint działają teoretycznie, ale powodują bóle głowy w praktyce?

Aplikacja nie powinna obsługiwać bardzo dużych ilości danych. Wątpię, czy w ciągu najbliższych kilku lat osiągnie 10 000 faktycznych rekordów.

Jeśli robi to jakąkolwiek różnicę, korzystamy z serwera Microsoft SQL. Aplikacja jest napisana w języku C # i używa Linq do SQL.

Aktualizacja

Dziękuję, uznałem istniejące odpowiedzi i komentarze za interesujące. Ale obawiam się, że źle zrozumiałeś moje pytanie, więc zawierają one to, co chciałem wiedzieć.

Tak naprawdę nie martwię się prawdziwym powodem wysokich ID. Jeśli sami nie możemy tego znaleźć, mogę zadać inne pytanie. W tym przypadku interesuje mnie zrozumienie procesu decyzyjnego. W tym celu należy założyć, że aplikacja będzie zapisywać 1000 rekordów dziennie, a następnie usunie ich 9999 . Jestem prawie pewien, że tak nie jest, ale tak właśnie uwierzył mój szef, kiedy poprosiła. Więc w tych hipotetycznych okolicznościach, jakie byłyby zalety i wady używania biginta lub pisania własnego kodu, który przypisuje identyfikatory (w sposób, który ponownie wykorzystuje identyfikatory już usuniętych rekordów, aby upewnić się, że nie ma luk)?

Jeśli chodzi o faktyczny powód, mocno podejrzewam, że dzieje się tak, ponieważ kiedyś napisaliśmy kod do importowania danych z innej bazy danych, co jest dowodem na to, że późniejszą migrację można wykonać w pewnym stopniu. Myślę, że mój kolega faktycznie utworzył kilka tysięcy rekordów podczas importu, a później je usunął. Muszę potwierdzić, czy rzeczywiście tak było, ale jeśli tak, to nie ma nawet potrzeby działania.

rumtscho
źródło
Zobacz post SM Ahasana Habiba na codeproject.com/Tips/668042/…
RLF
Możesz wyjaśnić? Czy nowe identyfikatory po prostu otrzymują wartości> 10000? A może nowe identyfikatory mają luki wynoszące 10000? A ile identyfikatorów będzie potrzebnych w przyszłym życiu aplikacji?
user2338816
1
Jeśli chodzi o znalezienie pierwszego nieużywanego identyfikatora, w książce Billa Karwina „SQL Antipatterns” znajduje się rozdział na ten temat. Tak, z pewnością można to uznać za antypattern!
Thomas Padron-McCarthy

Odpowiedzi:

24

Nie widząc kodu, trudno jest jednoznacznie powiedzieć, co się dzieje. Chociaż najprawdopodobniej IDENTITYwartość jest buforowana, co powoduje luki w wartości po ponownym uruchomieniu programu SQL Server. Zobacz /programming/17587094/identity-column-value-suddenly-jumps-to-1001-in-sql-server, aby uzyskać dobre odpowiedzi i informacje na ten temat.

Proste INTpole może zawierać wartości do 2 147 483 647. Możesz faktycznie rozpocząć wartość tożsamości od -2 147 483 648, dając pełne 32 bity wartości. 4 miliardy różnych wartości. Wątpię, czy zabraknie ci wartości do użycia. Zakładając, że aplikacja jest czasochłonne 1000 rzeczywistej wartości dla każdego wiersza dodaje, że trzeba być stworzenie prawie 12.000 wierszy dziennie codziennie zabraknie identyfikatorów w ciągu 6 miesięcy zakładając rozpoczął IDENTITYwartości na 0, i używali wew. Jeśli używałeś BIGINT, musiałbyś poczekać 21 milionów stuleci, zanim zabraknie Ci wartości, jeśli zapisałeś 12 000 wierszy dziennie, zużywając 1000 „wartości” na wiersz.

Powiedziawszy to wszystko, jeśli chcesz użyć BIGINTjako typu danych pola tożsamości, z pewnością nie ma w tym nic złego. Zapewni to nieograniczoną podaż wartości do wszystkich celów i celów. Różnica w wydajności między INT a BIGINT praktycznie nie występuje na nowoczesnym 64-bitowym sprzęcie i jest znacznie lepsza niż na przykład używanie NEWID()do generowania identyfikatorów GUID.

Jeśli chcesz zarządzać własnymi wartościami dla kolumny identyfikatora, możesz utworzyć tabelę kluczy i zapewnić dość kuloodporny sposób, korzystając z jednej z metod przedstawionych w odpowiedziach na to pytanie: Obsługa jednoczesnego dostępu do tabeli kluczy bez zakleszczenia w programie SQL Server

Inną opcją, przy założeniu, że używasz programu SQL Server 2012+, byłoby użycie SEQUENCEobiektu w celu uzyskania wartości identyfikatora dla kolumny. Należy jednak skonfigurować sekwencję, aby nie buforować wartości. Na przykład:

CREATE SEQUENCE dbo.MySequence AS INT START WITH -2147483648 INCREMENT BY 1 NO CACHE;

W odpowiedzi na negatywne postrzeganie przez szefa „wysokich” liczb, powiedziałbym, jaką to robi różnicę? Zakładając, że używasz INTpola, ze związkiem IDENTITY, w rzeczywistości można rozpocząć IDENTITYna 2147483647i „przyrost” przez wartość -1. Nie miałoby to absolutnie żadnej różnicy w zużyciu pamięci, wydajności lub używanym miejscu na dysku, ponieważ liczba 32-bitowa to 4 bajty, bez względu na to, czy jest 0lub 2147483647. 0binarny jest 00000000000000000000000000000000przechowywany w 32-bitowym INTpolu ze znakiem . 2147483647jest01111111111111111111111111111111- obie liczby zajmują dokładnie taką samą ilość miejsca, zarówno w pamięci, jak i na dysku, i obie wymagają dokładnie takiej samej ilości operacji procesora do przetworzenia. O wiele ważniejsze jest prawidłowe zaprojektowanie kodu aplikacji niż obsesja na punkcie faktycznej liczby przechowywanej w polu klucza.

Zapytałeś o zalety i wady: (a) używając kolumny identyfikatora o większej pojemności, takiej jak a BIGINT, lub (b) krocząc własnym rozwiązaniem, aby uniknąć luk identyfikacyjnych. Aby odpowiedzieć na te obawy:

  1. BIGINTzamiast INTjako typ danych dla danej kolumny. Użycie a BIGINTwymaga podwójnej ilości pamięci, zarówno na dysku, jak i w pamięci dla samej kolumny. Jeśli kolumna jest indeksem klucza podstawowego dla danej tabeli, każdy indeks nieklastrowy dołączony do tabeli będzie również przechowywać BIGINTwartość, dwukrotnie większą niż INT, zarówno w pamięci, jak i na dysku. SQL Server przechowuje dane na dysku na stronach 8 KB, gdzie liczba „wierszy” na „stronę” zależy od „szerokości” każdego wiersza. Na przykład, jeśli masz tabelę z 10 kolumnami, każda z nich INT, możesz w przybliżeniu przechowywać 160 wierszy na stronie. Jeśli zamiast tych kolumnBIGINTkolumny, możesz przechowywać tylko 80 wierszy na stronie. W przypadku tabeli z bardzo dużą liczbą wierszy oznacza to wyraźnie, że we / wy wymagane do odczytu i zapisu będzie w tym przykładzie podwojone dla dowolnej liczby wierszy. To prawda, jest to dość ekstremalny przykład - jeśli miał wiersz składający się z jednej INTlub BIGINTkolumny i pojedynczej NCHAR(4000)kolumny, byłbyś (upraszczając) uzyskanie pojedynczy wiersz na stronie, czy stosuje się INTlub BIGINT. W tym scenariuszu nie zrobiłoby to znaczącej różnicy.

  2. Opracowanie własnego scenariusza, aby zapobiec lukom w kolumnie identyfikatora. Musisz napisać kod w taki sposób, aby określenie „następnej” wartości identyfikatora do użycia nie kolidowało z innymi działaniami mającymi miejsce w tabeli. SELECT TOP(1) [ID] FROM [schema].[table]Przychodzi mi na myśl coś naiwnego. Co jeśli wielu aktorów próbuje jednocześnie zapisywać nowe wiersze w tabeli? Dwóch aktorów może łatwo uzyskać tę samą wartość, co powoduje konflikt zapisu. Obejście tego problemu wymaga szeregowania dostępu do tabeli, co zmniejsza wydajność. Napisano wiele artykułów na temat tego problemu; Pozostawię czytelnikowi przeprowadzenie wyszukiwania na ten temat.

Wniosek jest następujący: musisz zrozumieć swoje wymagania i odpowiednio oszacować zarówno liczbę wierszy, jak i szerokość wiersza, a także wymagania dotyczące współbieżności aplikacji. Jak zwykle It Depends ™.

Max Vernon
źródło
4
+1, ale nie odrzuciłbym wymagań przestrzennych BIGINT. Nie tyle miejsca na dysku, co raczej wejścia / wyjścia i miejsca zmarnowanego w pamięci. Możesz to zrekompensować za pomocą kompresji danych, więc tak naprawdę nie odczuwasz siły typu BIGINT, dopóki nie przekroczysz 2 miliardów. Idealnie byłoby po prostu rozwiązać problem (waham się, czy nazywać to błędem per se) - chociaż ludzie nie powinni przejmować się lukami i chociaż ludzie nie powinni restartować swoich serwerów 15 razy dziennie, mamy oba te scenariusze dość powszechne i często w tandemie.
Aaron Bertrand
3
Bardzo ważne punkty, Aaron, jak zwykle. I tak miałbym tendencję do korzystania z INT, ponieważ BIGINT jest prawie całkowitą nadwyżką, chyba że spodziewają się ogromnej liczby wierszy.
Max Vernon
Typ danych BIGINT dla kolumny identyfikatora nie będzie miał dużego wpływu na pamięć, chyba że masz w pamięci setki tysięcy lub więcej jednocześnie. Nawet wtedy prawdopodobnie będzie to niewielki ułamek całkowitego rozmiaru wiersza.
user2338816
2
@ user2338816 o to właśnie chodzi - jeśli stół się powiększy, będzie dużo pamięci. A ponieważ kolumna tożsamości jest zwykle kluczem do klastrowania, są to dodatkowe 4 bajty dla każdego wiersza w każdym indeksie. Czy będzie to miało znaczenie w każdym przypadku? Nie. Czy należy to zignorować? Absolutnie nie. Wydaje się, że nikt się nie zastanawia nad skalowalnością, dopóki nie będzie za późno.
Aaron Bertrand
3
Choć jeśli zrobić mieć uzasadnione oczekiwanie, że może trzeba bigintbędzie prawdopodobnie podziękować sobie za decyzje, które z wyprzedzeniem zamiast konieczności dodać to do tabeli z miliardów wierszy.
Martin Smith
6

Głównym zadaniem do wykonania jest znalezienie przyczyny, dla której aktualna wartość jest tak wysoka.

Najbardziej rozsądnym wyjaśnieniem dla wersji SQL Server wcześniejszych niż SQL2012 - zakładając, że mówisz o testowej bazie danych - byłby test obciążenia, po którym następuje czyszczenie.

Począwszy od SQL2012 najbardziej prawdopodobnym powodem jest kilka restartów silnika SQL (jak wyjaśniono w pierwszym podanym linku Max).

Jeśli luka jest spowodowana przez scenariusz testowy, z mojego punktu widzenia nie ma powodu do zmartwień. Ale żeby być bezpiecznym, sprawdziłbym wartości tożsamości podczas normalnego użytkowania aplikacji, a także przed i po ponownym uruchomieniu silnika.

„Zabawne” jest to, że MS twierdzi, że obie alternatywy (flaga śledzenia 272 lub nowy obiekt SEQUENCE) mogą wpływać na wydajność.

To może być najlepsze rozwiązanie, aby użyć BIGINT zamiast INT tylko po to, aby być po bezpiecznej stronie, aby objąć MS następnych „ulepszeń” ...

Lmu92
źródło
Prawdopodobnie sformułowałem moje pytanie w niewłaściwy sposób, ale tak naprawdę nie jestem zainteresowany znalezieniem przyczyny. Istnieje duże prawdopodobieństwo, że albo coś się nie pojawi (wyniki testu), albo zła decyzja projektowa w aplikacji, którą można rozwiązać poza bazą danych. Chodziło o to, aby zrozumieć, dlaczego doświadczony DBA uważa, że ​​wysokie identyfikatory są złe lub gorsze niż wprowadzanie własnego zarządzania identyfikatorami.
rumtscho
2

Rumtscho, jeśli tworzysz tylko 1000 wierszy dziennie, nie ma wiele do wyboru - użyj typu danych INT z polem Tożsamość i gotowe. Prosta matematyka mówi, że jeśli dasz swojej aplikacji 30-letni cykl życia (mało prawdopodobne), możesz mieć 200 000 wierszy dziennie i nadal znajdować się w dodatnim zakresie liczbowym typu danych INT.

Używanie BigInt jest w twoim przypadku przesadą, może również powodować problemy, jeśli twoja aplikacja lub dane będą dostępne przez ODBC (takie jak wprowadzone do Excela lub MS Access itp.), Bigint nie tłumaczy dobrze przez większość sterowników ODBC do aplikacji komputerowych.

Jeśli chodzi o GUIDY, oprócz dodatkowego miejsca na dysku i dodatkowego wejścia / wyjścia, istnieje ogromny problem polegający na tym, że z założenia nie są one sekwencyjne, więc jeśli są częścią posortowanego indeksu, możesz zgadywać, że każda wstawka będzie wymagają zastosowania indeksu. - Jim

jimo3
źródło
Dobra uwaga na temat GUID, chyba że użyjesz NEWSEQUENTIALID () - nadal się zgadzam, nie ma żadnego powodu, aby używać ich widocznych w tym pytaniu.
Max Vernon,
1

Czy jest różnica między zastosowanymi wartościami? Czy wartości początkowe wynoszą 10.000 i od tego czasu wszyscy dodają 1? Czasami, jeśli liczba zostanie podana klientom, początkowa liczba jest większa od zera, powiedzmy na przykład 1500, więc klient nie zdaje sobie sprawy, że system jest „nowy”.

Wadą używania biginta zamiast smallinta jest to, że ponieważ bigint wykorzystuje „więcej miejsca na dysku”, podczas odczytu dysku odczytujesz mniej bloków dysku dla każdego dysku. Jeśli przestrzeń wierszy jest niewielka, może to być wadą, jeśli nie, nie ma to większego znaczenia. Również nie ma większego znaczenia, jeśli nie pytasz o wiele zasobów jednocześnie i masz odpowiednie indeksy.

I jak powiedziano w innej odpowiedzi, jeśli martwisz się wyczerpaniem indeksów, nie powinieneś się martwić, smallint poradzi sobie, chyba że masz firmę milionera. Opracowanie mechanizmu „odzyskiwania identyfikatorów” jest kosztowne i dodaje oprogramowaniu punkty awarii i złożoność.

pozdrowienia

Ctutte
źródło
2
OP widzi luki w ponownym uruchomieniu usługi. Wynika to z tego problemu . Nie uważam też, by smallint stanowił dobry kompromis w krótkim okresie, ponieważ będzie musiał to naprawić później.
Aaron Bertrand
@AaronBertrand, obawiam się, że inni źle to zrozumieli, kiedy zasugerowali taką możliwość. Jestem pewien, że nie jest to przyczyną dużej liczby, ale nawet gdyby tak było, nie próbowałem znaleźć przyczyny, ale dowiedzieć się, jakie mogą być argumenty za i przeciw proponowanym rozwiązaniom. Zobacz szczegóły mojej aktualizacji.
rumtscho
@rumtscho w rzeczywistości ta odpowiedź podkreśla słuszność, nawet jeśli nie odnosi się bezpośrednio do twojego pytania: „Opracowanie mechanizmu„ odzyskiwania identyfikatorów ”jest kosztowne i dodaje punkty awarii i złożoności oprogramowania”.
Doktor J
@DoktorJ Zgadzam się z tobą. Byłem osobą, która głosowała za odpowiedzią :) Chciałem tylko wyjaśnić nieporozumienie, dlatego zostawiłem swój pierwszy komentarz.
rumtscho
1

Gdybym był twoim szefem I byłoby być najbardziej zainteresowani powodów dla nieoczekiwanie wysokich wartościach Id ... tak jak ja to widzę, dla każdego z dwóch scenariuszy nakreślonych Państwo:

  1. JEŻELI wcześniejsze testy wykazały podwyższone wartości tożsamości - wtedy twoje inne komentarze na temat oczekiwanej liczby rekordów również zmusiłyby mnie do zasugerowania mniejszego typu klucza. Szczerze mówiąc, zastanowiłbym się również, czy można zresetować sekwencję i przenumerować istniejące rekordy, jeśli test nie jest charakterystyczny dla bieżącego zamierzonego użycia tabeli (większość uważa, że ​​to przesada - „to zależy”).

  2. JEŻELI większość rekordów zapisanych w tabeli zostanie usunięta wkrótce po tym, skłaniam się do rozważenia użycia dwóch tabel; tymczasowa tabela, w której rekordy nie są przechowywane długoterminowo, a druga, w której przechowywane są tylko rekordy, które utworzymy na stałe. Ponownie, twoje oczekiwania dotyczące liczby rekordów długoterminowych sugerują mi użycie mniejszego typu w kluczowej kolumnie, a kilka rekordów dziennie nie spowoduje, że problem z wydajnością spowoduje przeniesienie rekordu z jednej tabeli do drugiej podobnie jeden. Podejrzewam, że to nie jest twój scenariusz, ale wyobraź sobie, że witryna zakupów może preferować utrzymywanie elementu Basket / BasketItem, a kiedy zamówienie zostanie faktycznie złożone, dane zostaną przeniesione do zestawu Order / OrderItem.

Podsumować; Moim zdaniem BIGINTÓW nie należy się obawiać, ale szczerze mówiąc, są one niepotrzebnie duże w wielu scenariuszach. Jeśli tabela nigdy się nie powiększy, nigdy nie uświadomisz sobie, że wybór rodzaju był nadmierny ... ale jeśli masz tabele z milionami wierszy i wieloma kolumnami FK, które są DUŻE, gdy mogłyby być mniejsze - możesz życzyć sobie typy zostały wybrane bardziej zachowawczo (rozważ nie tylko kolumny klucza, ale wszystkie kolumny klucza z przodu i wszystkie kopie zapasowe, które przechowujesz itd.). Miejsce na dysku nie zawsze jest tanie (rozważ dysk SAN w zarządzanych lokalizacjach - tzn. Miejsce na dysku jest wynajmowane).

Zasadniczo opowiadam się za uważnym rozważeniem wyboru rodzaju danych zawsze, a nie czasem . Nie zawsze będziesz poprawnie przewidywał wzorce użytkowania, ale myślę, że podejmiesz lepsze decyzje z reguły, niż zawsze zakładając, że „większe jest lepsze”. Zasadniczo wybieram najmniejszy typ, który może zawierać wymagany i rozsądny zakres wartości i z przyjemnością rozważę INT, SMALLINT, a nawet TINYINT, jeśli uważam, że wartość będzie pasować do tego typu w dającej się przewidzieć przyszłości. Mniejsze typy raczej nie będą używane z kolumnami TOŻSAMOŚĆ, ale mogą z powodzeniem być używane z tabelami odnośników, w których wartości kluczowe są ustawiane ręcznie.

Wreszcie technologie, z których korzystają ludzie, mogą znacząco wpłynąć na ich oczekiwania i odpowiedzi. Niektóre narzędzia częściej powodują luki w zakresach, np. Przez wcześniejsze rezerwowanie zakresów tożsamości na proces. Natomiast @DocSalvager sugeruje dokładną sekwencję podlegającą kontroli, która wydaje się odzwierciedlać punkt widzenia szefa; Osobiście nigdy nie wymagałem takiego poziomu władzy - chociaż ogólna zasada, że ​​tożsamości są sekwencyjne i ogólnie bez luk, często była dla mnie niezwykle przydatna w sytuacjach wsparcia i analizie problemów.

Nij
źródło
1

jakie byłyby zalety i wady korzystania z biginta lub pisania własnego kodu, który przypisuje identyfikatory (w sposób, który ponownie wykorzystuje identyfikatory już usuniętych rekordów, aby upewnić się, że nie ma luk)?

Używanie bigintjako tożsamości i życie z lukami:

  • to wszystko wbudowana funkcjonalność
  • możesz być pewien, że zadziała po wyjęciu z pudełka
  • marnuje miejsce, ponieważ intnadal zapewniałoby dane z około 2 milionów dni; więcej stron będzie musiało zostać przeczytanych i napisanych; indeksy mogą być głębsze. (W tych tomach nie jest to jednak istotny problem).
  • kolumna klucza zastępczego ma być bez znaczenia, więc luki są w porządku. Jeśli jest to pokazywane użytkownikom, a luki są interpretowane jako znaczące, oznacza to, że robisz to źle.

Skręć swój własny:

  • Twój zespół programistów będzie cały czas pracował nad rozwojem i naprawianiem błędów.
  • czy chcesz po prostu wypełnić luki na ogonie czy też w środku? Decyzje projektowe do sporu.
  • każdy zapis będzie wymagał silnych blokad, aby uniemożliwić jednoczesnym procesom uzyskanie tego samego nowego identyfikatora lub rozwiązać konflikty post facto .
  • w najgorszym przypadku będziesz musiał zaktualizować każdy wiersz w tabeli, aby zamknąć luki, jeśli rowid = 1 zostanie usunięty. Utrudni to współbieżność i wydajność, co przy wszystkich kaskadowych aktualizacjach klucza obcego itp.
  • leniwy czy chętny do wypełniania luk? Co dzieje się z współbieżnością, gdy tak się dzieje?
  • będziesz musiał przeczytać nowy identyfikator, zanim jakikolwiek zapis = dodatkowe ładowanie.
  • indeks będzie potrzebny w kolumnie id do skutecznego znajdowania przerw.
Michael Green
źródło
0

Jeśli naprawdę zależy ci na przekroczeniu górnego progu INT dla swoich PK, rozważ użycie GUID. Tak, wiem, że to 16 bajtów vs 4 bajty, ale dysk jest tani.

Oto dobry opis zalet i wad.

Tim Goyer
źródło
4
+1, ponieważ jest to rozwiązanie, ale zobacz komentarz Aarona do odpowiedzi Maxa z powodu, dlaczego „dysk jest tani” nie jest powodem do używania GUID bez dokładnego rozważenia opcji.
Jack Douglas
1
Oto lepszy zapis od eksperta ds. Indeksów
Aaron Bertrand
Aha, i oczywiście uważaj na podziały stron NEWID ()
Max Vernon
1
Mój szef zdaje się sprzeciwić wysokim wartościom tylko dlatego, że wyglądają wysoko. Mam nadzieję, że to pytanie pokaże mi więcej możliwych zastrzeżeń, ale jeśli jest to jeden z jej głównych argumentów, prawdopodobnie zareagowałaby jeszcze bardziej negatywnie na GUID.
rumtscho
1
@rumtscho Powiedz swojemu szefowi, że liczba zastępcza jest po prostu liczbą bez znaczenia („rozmiar” liczby jest nieistotny) i że przerwy w sekwencji są naturalne i w dużej mierze nieuniknione.
Aaron Bertrand
0

Klucze podstawowe RDBMS (kolumna zwykle nazywana „ID”)
Luki nie można uniknąć w kolumnach (polach) autoinkrementacji RDBMS. Są one przede wszystkim przeznaczone do tworzenia unikalnych PK. W celu zwiększenia wydajności główne produkty dzielą je na partie, więc automatyczne mechanizmy odzyskiwania dla różnych usterek normalnej pracy mogą spowodować, że liczby pozostaną nieużywane. To normalne.

Nieprzerwane sekwencje
Gdy potrzebujesz nieprzerwanego numeru sekwencji, takiego, jakiego często oczekują użytkownicy, powinna to być osobna kolumna, która jest przypisana programowo i nie powinna być PK. Zatem te 1000 rekordów może mieć tę samą liczbę w tej kolumnie.

Dlaczego użytkownicy chcą nieprzerwanych sekwencji?
Brakujące numery sekwencyjne są najbardziej podstawowym znakiem błędu wykrytym podczas każdego rodzaju audytu. Ta zasada „Księgowości-101” jest wszechobecna. Jednak to, co działa w przypadku niewielkiej liczby rekordów prowadzonych ręcznie, ma poważny problem, gdy stosuje się je do bardzo dużej liczby rekordów w bazach danych ...

Ponowne użycie kluczowych wartości dla niepowiązanych rekordów unieważnia bazę danych.
Użycie „pierwszej nieużywanej liczby całkowitej” wprowadza prawdopodobieństwo, że w pewnym momencie w przyszłości liczba zostanie ponownie użyta dla rekordów niezwiązanych z oryginałem. To sprawia, że ​​baza danych jest niewiarygodna jako dokładne przedstawienie faktów. Jest to główny powód, dla którego mechanizmy autoinkrementacji są zaprojektowane tak, aby nigdy nie wykorzystywać ponownie wartości.

DocSalvager
źródło