Kolumny tożsamości lub UDF, które jawnie generują unikalny identyfikator?

11

Jestem w trakcie debaty na temat tego, czy lepiej zrobić PRIMARY KEYz Kolumny tożsamości , z UDF, który wyraźnie generuje unikalny identyfikator.

  • Opowiadam się za kolumną tożsamości.
  • Twierdzi, że mój partner opowiada się za ręcznym generowaniem wartości
    • umieszczając UDF na innym stole, na którym możemy mieć UDF
      • zablokuj zasób
      • zwiększ tabelę identyfikacyjną o jedno pole wywoływane ID_Valueprzez1
      • użyj tego jako unikalnego globalnego identyfikatora
    • Lub niech tabela zrobi id+1podczas wstawiania
    • Że łatwiej jest przenosić dane między serwerami i / lub środowiskami nie mającymi ograniczeń identyfikacyjnych; przechodzenie z jednego DB, w którym znajdują się dane, do innego podobnego DB z, powiedzmy, danymi przejściowymi lub danymi zastępczymi. W przypadku testów nieprodukcyjnych możemy chcieć przenieść wszystkie rekordy z wczoraj do etapu testowania.

Która implementacja ma większy sens?

kacalapy
źródło

Odpowiedzi:

21

Twój kolega jest idiotą.

Rozwiązanie nie będzie skalowalne, UDF nie jest współbieżny (z tego samego powodu ). I jak sobie radzić z wstawkami wielorzędowymi: wymagałoby to wywołania UDF na wiersz

A migracja do innych RDBMS nie zdarza się często w prawdziwym życiu ... równie dobrze możesz nie używać SQL Server teraz i używać sekwencji na Oracle i mieć nadzieję, że nie przeprowadzisz migracji.

Edytować:

Twoja aktualizacja mówi, że przenoszenie danych służy do odświeżania nieprodukcyjnych baz danych.

W takim przypadku podczas odświeżania ignorujesz kolumny tożsamości. Nie kompromitujesz swojej implementacji, aby ułatwić ładowanie produktów innych niż produkty. Lub użyj tabel tymczasowych, aby śledzić zmiany wartości tożsamości.

Lub użyj procesów: co wieczór odświeżamy nasz system testowy od produkcji, co całkowicie eliminuje problem. (I zapewnia przywrócenie kopii zapasowej produktu)

gbn
źródło
11

Użyj wartości tożsamości. Generowanie własnej tabeli sekwencji i wartości sekwencji zajmie dużo narzutu i spowoduje wiele blokowania i blokowania podczas próby wygenerowania liczb.

Tożsamość istnieje z jakiegoś powodu, użyj jej.

Kiedy SQL Denali wyjdzie, będzie obsługiwał sekwencje, które będą bardziej wydajne niż tożsamość, ale sam nie możesz stworzyć czegoś bardziej wydajnego.

Jeśli chodzi o przenoszenie rekordów z jednego środowiska do drugiego, włącz IDENTITY_INSERT podczas wykonywania wstawiania lub zaznacz pole w SSIS.

mrdenny
źródło
Jeśli przejdziesz z „produkcji” na „test” i masz pole tożsamości, ryzykujesz nadpisanie lub zderzenie danych. To wszystko co mówię. Tak, to nie powinien być problem w tym kierunku, ale mówię tylko, że tak się może stać.
jcolebrand
To prawda, że ​​będziesz mieć tę samą liczbę dla różnych wartości wierszy w programowaniu, testowaniu, qa, uat i produkcji. Więc co? Jeśli te wartości są ważne (jak w przypadku tabeli odnośników), należy je kodować ręcznie, co nie powinno stanowić problemu, ponieważ nie należy często umieszczać wartości w tych tabelach. Jeśli chcesz kontrolować wartości tożsamości między środowiskami, aby uniknąć kolizji, zresetuj wartości tożsamości między środowiskami podczas przywracania z produkcji.
mrdenny,
5

Kolumna tożsamości brzmi dla mnie dobrze. Nie jestem pewien, czy podążam za logiką, dlaczego trudno jest przenosić dane między serwerami.

Jeśli chcesz, aby każdy wiersz miał globalnie unikalną tożsamość, możesz użyć identyfikatora UUID, ale nie zrobiłbym tego, chyba że masz pewność, że globalna unikalność jest konieczna - zazwyczaj tak nie jest. Używanie identyfikatorów UUID jako identyfikatorów zmniejszy wydajność, zwiększy wymagania dotyczące miejsca na dysku i utrudni debugowanie - ze względu na długość trudno jest zapamiętać identyfikator UUID, przekazać go komuś przez telefon lub zapisać go na papierze bez błędów.

Mark Byers
źródło
4

W przypadku prostych identyfikatorów numerycznych wystarczy wybrać tożsamość i zapomnieć o wszystkich problemach związanych z ich ręcznym generowaniem.

Zawsze możesz utworzyć „super tabelę”, która używa tożsamości jako PK i ma kolumnę typu oraz wszelkie inne informacje. Kiedy potrzebujesz nowego identyfikatora (zakładając, że masz na myśli unikalny IDS w różnych tabelach), po prostu wstaw do tej tabeli i chwyć, SCOPE_IDENTITY()a następnie wstaw do rzeczywistej tabeli, której potrzebujesz.

Zasadniczo tworzysz tabelę: MasterID z identyfikatorem PK, kiedy musisz wstawić wiersz do tabeli 1 INSERT INTO MasterIDsi uzyskać tożsamość wygenerowaną przez ten wiersz za pomocą, SCOPE_IDENTITY()a następnie wstawić do tabeli 1, używając tej wartości jako PK.

Tabela 1 będzie zawierała brak tożsamości int PK. Zrobiłbyś ten sam proces, aby wstawić do Table2 itp. Pozwól SQL Serverowi zarządzać wartościami tożsamości w tabeli MasterIDs , których możesz następnie użyć w innych tabelach. Identyfikatory główne mogą zawierać inne tabele, takie jak typ (abyś wiedział, która tabela, Tabela 1 lub Tabela 2 itp.) Używa tej wartości tożsamości.

Paul White 9
źródło
3

Tak długo, jak prawidłowo używasz ograniczeń klucza obcego (kaskadowanie, aktualizowanie itp.), Nic ci się nie stanie, używając pola tożsamości. Naprawdę nie widzę przewagi nad innym rozwiązaniem w tym przypadku.

Joe Phillips
źródło
2

Tożsamość została dopasowana do twojego scenariusza. Masz narzędzia takie jak replikacja do wymiany danych serwer / środowisko, które utrzymują to wszystko razem.


źródło
1

Właśnie skończyłem pracę, w której sam zastąpiłem identitykolumnę SQL Server normalnym intpolem i sam kontrolowałem przydział identyfikatorów.

Widziałem całkiem imponujący wzrost wydajności. W przeciwieństwie do OP, nie mam UDF do wygenerowania identyfikatora. Ale zasada jest prawie taka sama: istnieje część oprogramowania, która utrzymuje pulę identyfikatorów. Kiedy skończą się, pobiera kolejną partię, wysyłając zapytanie do bazy danych o następną Niską wartość i inkrementuje ją do następnej Niski .

To pozwala nam generować identyfikatory i odnosić wszystkie podmioty poza transakcją w naszym ORM, zanim prześlemy partie do bazy danych, a także prześlemy większe partie bez dodatkowych objazdów, aby uzyskać właśnie wstawioną tożsamość (wymagane przez kolumny tożsamości).

W tabeli identyfikatorów mamy więcej niż jeden wiersz, co pozwala nam używać określonych zakresów, jeśli chcemy. tj. do ponownego użycia usuniętych bloków i negatywnych identyfikatorów.

znak
źródło
0

Używam tożsamości od lat i poważnie zastanawiam się nad zastąpieniem numeru identyfikacyjnego UNIQUEIDENTIFIER. Koszmar, gdy trzeba zmienić typ danych, jeśli ktoś zaprojektował go jako kompaktową bazę danych, i koszmar, jeśli trzeba dodać tożsamość do kolumny, nie można też zaktualizować kolumny tożsamości. Wyobraź sobie, że umieściłeś int, a Twoja baza danych przekracza 2 miliardy rekordów, ponownie koszmar do zmiany (rozważ FK)! Zmiana czegokolwiek za pomocą tożsamości jest koszmarem i nie jest przyjazna dla skali, chyba że wprowadzisz bigint! UNIQUEIDENTIFIER vs Identity = wygoda i solidność kontra być może zauważalna poprawa wydajności (nie zrobiliśmy testu porównawczego).

Aktualizacja: Po tym, jak to zobaczyłem , zdecydowanie skłaniam się ku UNIQUEIDENTIFIER. Nie pokazuje to żadnej realnej korzyści z tożsamości bigint i szereg korzyści dla UNIQUEIDENTIFIER! Różne wersje SQL Server mogą mieć inny wynik. Piękno jest mieć unikalny identyfikator we wszystkich bazach danych i systemach (solidność)! Przenoś, kopiuj i przekształcaj dane, jak chcesz! https://www.mssqltips.com/sqlservertip/5105/sql-server-performance-comparison-int-versus-guid/

Hrvoje Batrnek
źródło
64-bitowa int będzie trwać długo ...
Vérace