Neden desteklenmeyen bir sütundaki Kimlik özelliğini kaldırma


11

SQL Server 2000'den sonra, "bir kimlik sütunu" un-kimlik "yeteneği kaldırıldı okudum. Ve bu "Tasarım gereği" (sadece eksik bir özellik değil).

İşte bir blogda bulduğum bir örnek . Sistem tablolarının güncellenmesini içerir. (Ve bu yetenek SQL Server 2000'den sonra kaldırıldı.) Bunu sistem tabloları üzerinden yapmak iyi bir fikir değil. Sadece bunu başka bir yolla yapmak için bir özelliğin neden etrafta olmadığını merak ediyorum.

Bu konuda çalışmak bana hatırı sayılır miktarda çalışmama neden olacak. (Yüz milyonlarca satırı, kesinti zamanı toleranssız bir ortamda yeni tablolara kopyalamak.)

Bu yüzden "Neden" diye soracağımı düşündüm.

Sql Server 2005 ve sonraki sürümlerinde bunu kötü yapan ne değişti? Yoksa her zaman kötü müydü ve kilitli değil miydi?

Kimlik sütununu tekrar normal bir sütun haline getirerek hangi "En İyi Uygulama" (veya benzer bir ilke) ihlal edilir?

-

"Bunu neden yapıyorum" isteğine yanıt vermek için güncelleştirme:
Bu çok yüksek bir özettir: Tablolarıma bölümler eklemeye başlayacağım. (Böylece eski verileri arşivleyebilir / temizleyebilirim.) Hepsi bu kadar kolay. Ancak bazen bir kaydı farklı bir bölüme taşımam gerekiyor, böylece kaldırılmıyor (bir bölüm arşiv / silme için geldiğinde). (Satırı farklı bir bölüme taşımak için her zaman yer olması için bölümleme sütunumu 2 oranında artırıyorum.)

Ancak bölümleme sütunu bir kimlik sütunu ise, değeri silmem ve yeniden eklemem gerekir (kimlik sütununun değerini güncellemenin bir yolu yoktur). Hangi çoğaltma ile ilgili sorunlara neden olur.

Bu yüzden bir kimlik sütunu yerine bir dizi kullanmak istiyorum. Ancak bu anahtar büyük veritabanlarında çok zor.

Yanıtlar:


22

Sorunuz aslında:

Neden asla ilk başta yapmama izin verilmemesi gereken bu riskli şeyi yapamıyorum?

Bu sorunun cevabı büyük ölçüde alakasız (bu Connect öğelerinde bu işlevselliği isteyen bazı Microsoft yorumlarını görebilirsiniz: # 294193 ve # 252226). Tamlık açısından özetim şudur: Identity özelliğini kaldırma yeteneği, ilk etapta sistem tablolarını bozma yeteneğine sahip olmanın istenmeyen bir yan etkisiydi. Bunun, çoğu zaman çok kötü sonuçları olan birçok şekilde kullanılması amaçlanmamıştır ve bu nedenle kaldırılmıştır. Belgelenmemiş, desteklenmeyen bir sistem tablosu kesmekti. Microsoft artık bir kimlik sütunu olan bir sütundan kurtulmanızı istemediği için sistem tablolarındaki verileri değiştirme yeteneği kaldırılmadı, sistem tablolarıyla mucking işlemi çok riskli olduğu için kaldırıldı. IDENTITY özelliğinin kaldırılması özel olarak hedeflenen bir özellik kaldırma değildi ve bu yaklaşıma mümkün olduğu eski günlerde bile asla tam olarak güvenemezdim.

Bununla birlikte, bu soruyu cevaplamaya ne dersin?

Minimum veya kesinti süresi olmayan bir sütunun IDENTITY özelliğini nasıl kaldırabilirim?

Bu kullandığınız, kolayca yapabilirsiniz ALTER TABLE ... SWITCH, ben ilk kendi öğrenilen eminim bir teknik Paul Beyaz içinde Connect'in # 252226 için geçici çözümler . Bu basit tablo göz önüne alındığında hızlı bir örnek:

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

Sonuçlar:

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

Şimdi bir gölge tablosu oluşturalım ve bu tabloya geçelim, ardından eski tabloyu bırakalım, yeni tabloyu yeniden adlandırıp normal aktiviteye devam edelim:

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

Sonuçlar:

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

Şimdi temizleyin:

DROP TABLE dbo.Original;

Bu yalnızca veri hareketi olmayan bir meta veri işlemidir ve diğer veriler yalnızca meta veriler güncellenirken engellenir. Ancak, kuşkusuz, çok basit bir örnek. Yabancı anahtarlarınız varsa veya çoğaltma, Veri Yakalamayı Değiştirme, İzlemeyi Değiştirme vb. Gibi başka özellikler kullanıyorsanız, bu değişikliği yapmadan önce bazılarını devre dışı bırakmanız veya kaldırmanız gerekebilir (Tüm kombinasyonları test etmedim). Özellikle yabancı anahtarlar için, tüm (veya seçilen) yabancı anahtar kısıtlamalarını düşürmek ve yeniden oluşturmak için komut dosyalarının nasıl oluşturulacağını gösteren bu ipucuna bakın .

Ayrıca, SQL Server'ın bu sütunu doldurmasını beklememek için uygulama kodunuzu güncellemeniz ve sütunların sırasına veya belirtmeleri gereken sütunlara bağlı olabilecek ekleme veya seçme ifadelerini kontrol etmeniz gerekir. Genellikle, bu tablonun herhangi bir söz için tüm kod tabanı grep.

Ayrıca bunu ele almak için başka bir yol için Itzik Ben-Gan (kaynak: bu eski makale ) bu komut dosyası bakın , ama burada yer alan veri hareketi var, bu yüzden "hayır veya minimum kesinti" gereksinimi teslim etmez.


3
Gelen herkesi iki bağlantı maddesini oylamaya teşvik etmek istiyorum. Kimlik booleanını açan veya kapatan bir ALTER COLUMN özelliği uygulamak ne kadar zor olabilir ?! Etrafında çalışmak acı verici.
usr

İtiraf etmeliyim ki, bir nedenden ötürü ..SWITCH..sadece en az bir bölüm tanımlanmış tablolar için çalıştığını düşündüm .
RBarryYoung

SWITCHTablo bölümleme gerektirse de Enterprise Edition gerektirmeyen eklemek istiyorum .
Dan Guzman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.