İLK
Muhtemelen her üç sütun gerekmez: old_id
, external_id
, new_id
. Bir olan new_id
sütun, IDENTITY
eklediğinizde bile her satır için yeni bir değere sahip olacaktır external_id
. Ancak, old_id
ve arasında external_id
, bunlar birbirini tamamen dışlar: ya zaten bir old_id
değer var ya da mevcut kavramada, bu sütun sadece veya NULL
kullanıldığında olacak . Halihazırda var olan (yani değeri olan bir satır) yeni bir "harici" kimlik eklemeyeceğiniz ve herhangi bir yeni değer gelmeyeceği için , kullanılan bir sütun olabilir her iki amaç için.external_id
new_id
old_id
old_id
Bu nedenle, external_id
sütundan kurtulun ve old_id
benzer bir şey olarak yeniden adlandırın old_or_external_id
. Bu, hiçbir şeyde gerçek bir değişiklik gerektirmemeli, ancak bazı komplikasyonları azaltmalıdır. Eklemek için external_id
uygulama kodu zaten yazıldıysa, en fazla "eski" değerler içeriyor olsa bile sütunu aramanız gerekebilir external_id
.
Bu, yeni yapıyı sadece:
PkId AS AS COALESCE(old_or_external_id, new_id, -1) PERSISTED NOT NULL,
old_or_external_id INT NULL, -- values from existing record OR passed in from app
new_id INT IDENTITY(2000000, 1) NOT NULL
Artık 12 bayt yerine satır başına yalnızca 8 bayt eklediniz ( SPARSE
seçeneği veya Veri Sıkıştırma'yı kullanmadığınız varsayılarak ). Ve herhangi bir kodu, T-SQL veya Uygulama kodunu değiştirmeniz gerekmez.
İKİNCİ
Bu sadeleştirme yolunda devam ederek, geriye ne bıraktığımıza bakalım:
old_or_external_id
Kolon ya da zaten değerlere sahiptir, ya da uygulama yeni bir değer verilecek veya bırakılacaktır NULL
.
- Her
new_id
zaman yeni bir değer oluşturulur, ancak bu değer yalnızca old_or_external_id
sütun ise kullanılır NULL
.
Hem old_or_external_id
ve hem de değerlere ihtiyaç duyacağınız bir zaman asla olmaz new_id
. Her iki sütun nedeniyle değerlere sahip olduğunda Evet, bazı zamanlar olacaktır new_id
bir varlık IDENTITY
, ancak bu new_id
değerler dikkate alınmaz. Yine, bu iki alan birbirini dışlar. Peki şimdi ne olacak?
Şimdi neden external_id
ilk başta ihtiyacımız olduğuna bakabiliriz . IDENTITY
Kullanarak bir sütuna eklenmenin mümkün olduğunu göz önünde bulundurarak, SET IDENTITY_INSERT {table_name} ON;
hiçbir şema değişikliği yapmadan kurtulabilir ve uygulama kodunuzu yalnızca INSERT
ifadeleri / işlemleri SET IDENTITY_INSERT {table_name} ON;
ve SET IDENTITY_INSERT {table_name} OFF;
ifadeleri sarmak için değiştirebilirsiniz . Daha sonra, IDENTITY
sütunu (yeni oluşturulan değerler için) sıfırlamak için hangi başlangıç aralığını belirlemeniz gerekir, çünkü daha yüksek bir değer eklemek sonraki otomatik oluşturulan değerin geçerli MAX değerinden büyük olmalıdır. Ancak her zaman IDENT_CURRENT değerinin altında bir değer ekleyebilirsiniz .
old_or_external_id
Ve new_id
sütunlarını birleştirmek, otomatik olarak oluşturulan değerler ile uygulama tarafından oluşturulan değerler arasında üst üste binen bir değer durumuna geçme şansını da artırmaz, çünkü 2 veya hatta 3 sütuna sahip olma amacı, bunları Birincil Anahtar değerinde birleştirmektir. ve bunlar her zaman benzersiz değerlerdir.
Bu yaklaşımda, yapmanız gerekenler:
Tabloları şu şekilde bırakın:
PkId INT IDENTITY(1,1) PRIMARY KEY
Bu, her satıra 8 veya 12 yerine 0 bayt ekler.
- Uygulama tarafından oluşturulan değerler için başlangıç aralığını belirleyin. Bunlar, her bir tablodaki geçerli MAX değerinden daha büyük olacak, ancak otomatik olarak oluşturulan değerler için minimum değerden daha düşük olacaktır.
- Otomatik olarak oluşturulan aralığın hangi değerden başlaması gerektiğini belirleyin. Geçerli MAX değer arasındaki sürü oda var olmalıdır ve üst sınırda bilerek büyümeye oda bol biraz üzerinde 2140000000 olduğunu. Daha sonra bu yeni minimum tohum değerini DBCC CHECKIDENT aracılığıyla ayarlayabilirsiniz .
- Uygulama kodu INSERT'leri
SET IDENTITY_INSERT {table_name} ON;
ve SET IDENTITY_INSERT {table_name} OFF;
ifadeleri sarın .
İKİNCİ, Bölüm B
Doğrudan yukarıda belirtilen yaklaşımın bir varyasyonu, App kodu değerlerin -1 ile başlayıp oradan aşağıya inmesi olacaktır . Bu IDENTITY
değerleri yükselen değerler olarak bırakır . Buradaki fayda, yalnızca şemayı karmaşıklaştırmakla kalmaz, aynı zamanda çakışan kimliklere girme konusunda da endişelenmenize gerek yoktur (uygulama tarafından oluşturulan değerler yeni otomatik oluşturulan aralığa girerse). Bu, yalnızca zaten negatif kimlik değerleri kullanmıyorsanız bir seçenektir (ve insanların otomatik olarak oluşturulan sütunlarda negatif değerler kullanması oldukça nadir görünüyor, bu nedenle çoğu durumda olası bir olasılık olmalıdır).
Bu yaklaşımda, yapmanız gerekenler:
Tabloları şu şekilde bırakın:
PkId INT IDENTITY(1,1) PRIMARY KEY
Bu, her satıra 8 veya 12 yerine 0 bayt ekler.
- Uygulama tarafından oluşturulan değerler için başlangıç aralığı olacaktır
-1
.
- Uygulama kodu INSERT'leri
SET IDENTITY_INSERT {table_name} ON;
ve SET IDENTITY_INSERT {table_name} OFF;
ifadeleri sarın .
Burada yine de yapmanız gerekir IDENTITY_INSERT
, ancak: yeni sütun eklemezsiniz, hiçbir IDENTITY
sütunu "yeniden düzenlemenize" gerek yoktur ve gelecekteki çakışma riski yoktur.
İKİNCİ, Bölüm 3
Bu yaklaşımın son bir varyasyonu muhtemelen IDENTITY
sütunları değiştirmek ve bunun yerine Dizileri kullanmak olacaktır . Bu yaklaşımı benimsemenin nedeni, uygulama kodu değerlerini şu şekilde girebilmektir: pozitif, otomatik oluşturulan aralığın üstünde (aşağıda değil) ve gerek yoktur SET IDENTITY_INSERT ON / OFF
.
Bu yaklaşımda, yapmanız gerekenler:
- CREATE SEQUENCE kullanarak Dizi Oluşturma
IDENTITY
Sütunu, IDENTITY
özelliği olmayan ancak NEXT VALUE FOR işlevini DEFAULT
kullanarak bir Kısıtlama içeren yeni bir sütuna kopyalayın :
PkId INT PRIMARY KEY CONSTRAINT [DF_TableName_NextID] DEFAULT (NEXT VALUE FOR...)
Bu, her satıra 8 veya 12 yerine 0 bayt ekler.
- Uygulama tarafından oluşturulan değerlerin başlangıç aralığı, otomatik olarak oluşturulan değerlerin yaklaşacağını düşündüğünüz değerin çok üzerinde olacaktır.
- Uygulama kodu INSERT'leri
SET IDENTITY_INSERT {table_name} ON;
ve SET IDENTITY_INSERT {table_name} OFF;
ifadeleri sarın .
Ancak , ya kodlardan biri ile ya SCOPE_IDENTITY()
da @@IDENTITY
hala düzgün bir şekilde çalışması gerektiği için, Sekanslara geçiş şu anda bir seçenek değildir, çünkü Sekanslar için bu fonksiyonların eşdeğeri olmadığı anlaşılmaktadır :-(. Sad!