IDENTITY_INSERT ON'a neden bir kerede yalnızca bir tabloda izin verilir?


20

Bu durum bu IDENTITY_INSERT sadece bir defada bir veritabanı tablosundaki AÇIK olarak ayarlandığında, ama neden olabilir? Yana IDENTITYsütunlar genel olarak benzersiz değildir ben (en azından değil, genel olarak KİMLİK INSERT ile fudging daha tehlikeli) aynı anda birden fazla tabloya kimlikleri ekleyerek oluşabilecek her türlü tehlikeli durumun düşünemiyorum.

KİMLİK INSERT nadiren kullanılmalıdır, ancak zor sınırın nedeni nedir?


1
Caydırıcı belki, bu yüzden nadiren kullanılır?
Remus Rusanu

@RemusRusanu ya böyle düşünüyordum ya da yanlışlıkla birden fazla tablo için II'yi açık bırakmadığınızdan emin olmak için.
Ben Brocka

@Ben neden yanlışlıkla bir tablo için yanlışlıkla bir tablo için bırakmak daha kötü birden fazla tablo için bırakıyor? Her ikisi de aynı soruna yol açabilir. Sorunuzu gerçekten merak ediyorum ve cevabın caydırıcı olduğunu düşünmüyorum, yoksa motorda çok daha fazla kısıtlama olurdu. Ama bunu sık sık yapmanız gerektiğini düşünüyorsanız, muhtemelen şüpheli bir şey olduğunu kabul ediyorum.
Aaron Bertrand

@AaronBertrand, Q'da ima ettiğim gibi değil. Caydırıcılıktan da emin değilim, çünkü SQL Server sütunlarınızı ayrılmış anahtar kelimelerle adlandırmak gibi birçok kötü uygulamaya izin veriyor (bazen [] kullanmasanız bile)
Ben Brocka

@Ben doğru değil, bu sizin için değil, soruya rastlayan herhangi bir okuyucu için.
Aaron Bertrand

Yanıtlar:


12

Bence bunu zorlaştırmak. Her zaman açık bırakabilseydiniz, neden bir kimlik alanınız bile var?

Bununla birlikte, aslında birkaç kısıtlama vardır:

  • Sadece bu bağlantıda devam ediyor
  • Bağlantı başına yalnızca bir masaya ayarlanabilir

Bağlantıyla ilgili kısıtlamalara dayanarak, bence esasen yanlışlıkla kazara AÇIK kalmaz.

Birinin tablolarınızdan birinde kimlik eklentisini açtığını ve bunun farkına varamadığınızı ve kimlik alanınızın bütünlüğünü bozan (normalde) geçersiz bir ekleme gerçekleştirildiğini düşünün.

Unutmayın, yerinde herhangi bir kısıtlama veya benzersiz dizin yoksa kimlik alanları yinelenen değerlere sahip olabilir ...


1
+1 Bence kopyalarla ilgili son noktanız çok fazla eksik. Millet, IDENTITYbunu yaparlarsa, benzersiz bir kısıtlama haline geldiğini düşünüyor . Tabii ki, denemek için olsalardı, çürütmek çok kolay.
Aaron Bertrand

@AaronBertrand Ama yine, IDENTITY INSERT açık olan herhangi bir tabloda yinelenen kimlik riski tamamen aynı, neden zor sınır? Sadece bağlantı için devam etmesinin bir önlem olarak çok daha mantıklı olduğunu düşünüyorum.
Ben Brocka

Yinelenen kimlik sorununun zor sınırın bir nedeni olduğunu öne sürmüyordum.
Aaron Bertrand

6

Benim tahminim bu uygulama nedeniyle bir kısıtlama olduğunu. Birden fazla masada bu ayara izin vermek potansiyel bir performans isabeti idi:

Bu bir oturum parametresi olduğundan, ayarın tek bir tabloda etkinleştirilmesine izin vermek, basit bir bayrak olduğu ve tablonun nesne kimliğinin sunucu tarafında oturumda saklanacağı anlamına gelir. Belki de bu sadece tek bir tamsayıdır: IDENTITY_INSERT etkin değilse 0 ve tablo için databaseid + objectid kodlaması.

Parametrenin bir oturumda birden çok tabloya ayarlanmasına izin vermek, sunucunun bu tür nesnelerin dinamik bir listesini depolayacağı ve her ekleme ifadesi için kontrol edeceği anlamına gelir. Bir oturumun bin tablo için parametreyi etkinleştirdiğini düşünün:

  1. Bu, sunucunun oturum değişkenine 1000 öğe ayırdığı anlamına gelir
  2. Bu, sunucunun bu oturumdaki her ekleme ifadesi için 1000 öğenin listesini kontrol etmesi gerektiği anlamına gelir.

Ayrıca set identity_insert üzerinde sunucuda bir performans geniş performans isabet şüpheli. Sybase'de sadece bir kez kaydedilecek bir tablonun kimlik sayacının değerini kaydetmeye izin veren bir " kimlik yazma seti faktörü " vardı (değer bellekte tutulur ve arada bir ve sunucuda diske yazılır kapat ). SQL Server aynı koda dayanmaktadır, bu nedenle muhtemelen bazı karşılaştırılabilir optimizasyona sahiptir, ancak bir tablodaki identity_insert'i etkinleştirmek, sunucuyu her ekleme için kimlik değerini kaydetmek için muhtemelen kısıtlar, çünkü başka bir maksimum boşluk boyutunu garanti edemez. Bir oturum bir tablodaki ekler üzerinde bir performans isabeti yaparsa, bu muhtemelen kabul edilebilir, ancak sunucudaki tüm auto_increment tablolarında perf vuruşunu yapamazsa ..


+1 Muhtemelen burada bazı gerçekler. INSERTBir oturum için aynı anda yalnızca biri devam edebileceğinden boşluk boyutu argümanını almıyorum ve 10 milyon sabit kodlu IDENTITYdeğeri kolayca ekleyebilirim .
Aaron Bertrand

Boşluk boyutu, kilitlenme durumunda olanlarla ilgilidir: sybase'de, sunucu çökerse son kimlik kaybolur (bellekte), bu nedenle bir boşluk bırakarak yeniden başlar (kimlik yazma küme faktörüne bakın)
Olivier S

SQL Server'da, bir kimlik sütunuyla 1.000.000 satır eklerken veya SET IDENTITY_INSERTetkinken 1.000.000 sabit kodlanmış değerle kimlik sütununu geçersiz kılarken motorun çökmesi durumunda farklı bir şey olmasını mı öneriyorsunuz ? Ben sadece boşluk boyutu tek bir tablo etkiler daha farklı birden fazla tablo etkilemez öneririz.
Aaron Bertrand

Benim tahminim - bunun kesinlikle bir kanıtı yok - bir masadaki SET IDENTITY_INSERT 'in her ekleme için otomatik yazma işleminin bir diske yazması gerektiğidir. Mantığı Eklemek değer herhangi bir şey olabilir, çünkü sunucunun dikkate olamaz "Ben diske yazarsanız Tamam, sadece her 1000 satır kez kilitlenme durumunda güvenle son kurtardığım değere 1000 ekleyebilir" olurdu
Olivier S
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.