Dlaczego usunięcie właściwości Tożsamość w kolumnie nie jest obsługiwane


11

Przeczytałem, że po SQL Server 2000 usunięto możliwość „cofnięcia tożsamości” kolumny tożsamości. I że było to „z założenia” (nie tylko brakująca funkcja).

Oto przykład, który znalazłem na blogu . Polega na aktualizacji tabel systemowych. (I ta zdolność została usunięta po SQL Server 2000.) Rozumiem, że robienie tego za pomocą tabel systemowych nie jest dobrym pomysłem. Zastanawiam się po prostu, dlaczego nie ma funkcji umożliwiającej wykonanie tego w inny sposób.

Obejście tego sprawi mi sporo pracy. (Kopiowanie setek milionów wierszy do nowych tabel w środowisku nietolerującym przestojów).

Pomyślałem więc, że zapytam „dlaczego”.

Co zmieniło się w Sql Server 2005 i późniejszych wersjach, co sprawiło, że było to złe? A może zawsze było źle i po prostu nie było zamknięte?

Jaką „najlepszą praktykę” (lub podobną zasadę) naruszyłoby, czyniąc kolumnę tożsamości normalną kolumną?

-

Zaktualizuj, aby odpowiedzieć na pytanie „dlaczego to robię”:
To jest podsumowanie na bardzo wysokim poziomie: zacznę dodawać partycje do moich tabel. (Aby móc archiwizować / usuwać stare dane.) To wszystko jest łatwe. Ale czasami muszę przenieść rekord na inną partycję, aby nie został usunięty (gdy partycja pojawi się w celu archiwizacji / usunięcia). (Zwiększam kolumnę partycjonowania o 2, aby zawsze było miejsce na przeniesienie wiersza na inną partycję).

Ale jeśli kolumna partycjonowania jest kolumną tożsamości, muszę usunąć i ponownie wstawić wartość (nie ma możliwości zaktualizowania wartości kolumny tożsamości). Co powoduje problemy z replikacją.

Chcę więc użyć sekwencji zamiast kolumny tożsamości. Ale ten przełącznik jest bardzo trudny w dużych bazach danych.

Odpowiedzi:


22

Twoje pytanie jest zasadniczo:

Dlaczego nie mogę już robić tej ryzykownej rzeczy, której nigdy nie powinienem był robić?

Odpowiedź na to pytanie jest w dużej mierze nieistotna (chociaż w tych elementach Connect można zobaczyć komentarze firmy Microsoft dotyczące tej funkcji: # 294193 i # 252226). Dla kompletności moje streszczenie brzmi: Zdolność do usunięcia właściwości tożsamości była niezamierzonym efektem ubocznym posiadania możliwości bałaganu w tabelach systemowych. Nie było to zamierzone do wykorzystania na wiele sposobów, często o bardzo złych konsekwencjach, i dlatego zostało usunięte. To był nieudokumentowany, nieobsługiwany hack na stole systemowym. Możliwość zmiany danych w tabelach systemowych nie została usunięta, ponieważ Microsoft nie chciał już, abyś włamał się z kolumny będącej kolumną tożsamości. Został usunięty, ponieważ przesuwanie tabel systemowych jest bardzo ryzykowne. Samo usunięcie właściwości TOŻSAMOŚCI nie było specjalnie ukierunkowanym usunięciem funkcji i nigdy nie ufałbym temu podejściu nawet w starożytnych czasach, kiedy było to możliwe.

To powiedziawszy, zamiast tego odpowiemy na to pytanie?

Jak usunąć właściwość TOŻSAMOŚĆ kolumny przy minimalnym przestoju lub bez przestoju?

Możesz to zrobić łatwo, używając ALTER TABLE ... SWITCHtechniki, której jestem pewien, że nauczyłem się po raz pierwszy od naszego Paula White'a w obejściach dla Connect # 252226 . Szybki przykład, biorąc pod uwagę tę prostą tabelę:

CREATE TABLE dbo.Original
(
  ID INT IDENTITY(1,1) PRIMARY KEY,
  name SYSNAME
);
GO

INSERT dbo.Original(name) VALUES(N'foo'),(N'bar');
GO

SELECT * FROM dbo.Original;
GO

Wyniki:

ID  name
--  ----
1   foo
2   bar

Teraz utwórzmy tabelę cieni i przejdźmy do niej, następnie upuść starą tabelę, zmień nazwę nowej, a następnie wznów normalną aktywność:

CREATE TABLE dbo.New
(
  ID INT PRIMARY KEY,
  name SYSNAME
);
GO

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
  ALTER TABLE dbo.Original SWITCH TO dbo.New;
  DROP TABLE dbo.Original;
  EXEC sys.sp_rename N'dbo.New', N'Original', 'OBJECT';
COMMIT TRANSACTION;
GO

INSERT dbo.Original(ID,name) VALUES(3,N'splunge');
UPDATE dbo.Original SET ID = 6 WHERE ID = 1;
GO

SELECT * FROM dbo.Original;
GO

Wyniki:

ID  name
--  -------
2   bar
3   splunge
6   foo

Teraz posprzątaj:

DROP TABLE dbo.Original;

Jest to tylko operacja na metadanych, bez przenoszenia danych, i blokuje tylko innych użytkowników podczas aktualizowania metadanych. Ale, co prawda, jest to bardzo uproszczony przykład. Jeśli masz klucze obce lub używasz innych funkcji, takich jak replikacja, przechwytywanie danych, śledzenie zmian itp., Może być konieczne wyłączenie lub usunięcie niektórych z nich przed dokonaniem tej zmiany (nie przetestowałem wszystkich kombinacji). W szczególności dla kluczy obcych zapoznaj się z tą wskazówką, która pokazuje, jak generować skrypty, aby usunąć i odtworzyć wszystkie (lub wybrane) ograniczenia kluczy obcych.

Ponadto musisz zaktualizować kod aplikacji, aby nie oczekiwać, że SQL Server zapełni tę kolumnę, i sprawdź wszelkie instrukcje wstawiania lub wybierania, które mogą być zależne od kolejności kolumn lub kolumn, które należy określić. Ogólnie rzecz biorąc, chciałbym prześledzić całą bazę kodu dla każdej wzmianki o tej tabeli.

Zobacz też ten skrypt Itzika Ben-Gana (źródło: ten starożytny artykuł ), aby zobaczyć inny sposób na poradzenie sobie z tym problemem, ale dotyczy to przenoszenia danych, więc nie spełnia wymogu „braku lub minimalnego przestoju”.


3
Chciałbym zachęcić każdego, kto przyjdzie, by głosować za dwoma połączonymi elementami. Jak trudne może być wdrożenie funkcji ALTER COLUMN, która włącza lub wyłącza wartość logiczną tożsamości ?! Bolesne do obejścia.
usr

Muszę przyznać, z jakiegoś powodu myślałem, że ..SWITCH..działa tylko dla tabel, które mają zdefiniowaną przynajmniej jedną partycję.
RBarryYoung

Chcę tylko dodać, że SWITCHnie wymaga Enterprise Edition, chociaż partycjonowanie tabeli tak.
Dan Guzman,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.