ทำไม IDENTITY_INSERT ON อนุญาตให้ทำได้ครั้งละหนึ่งตารางเท่านั้น


20

เป็นกรณีที่IDENTITY_INSERTสามารถตั้งค่าเป็น ON ในตารางฐานข้อมูลครั้งละหนึ่งตารางเท่านั้น แต่เพราะเหตุใด เนื่องจากIDENTITYคอลัมน์นั้นไม่เหมือนกันในระดับโลกฉันจึงไม่สามารถนึกถึงสถานการณ์อันตรายใด ๆ ที่อาจเกิดจากการแทรกข้อมูลระบุตัวตนลงในตารางมากกว่าหนึ่งตารางในเวลาเดียวกัน

IDENTITY INSERT ไม่ควรนำมาใช้ แต่เหตุผลสำหรับขีด จำกัด ยากคืออะไร


1
บางทีการยับยั้งดังนั้นมันจึงไม่ค่อยถูกใช้?
Remus Rusanu

@RemusRusanu นั่นเป็นสิ่งที่ฉันคิดอยู่ไม่ว่าจะเพื่อให้แน่ใจว่าคุณไม่ได้เว้น II ON ไว้สำหรับหลาย ๆ โต๊ะ
Ben Brocka

@Ben ทำไมมันถึงทิ้งไว้โดยไม่ตั้งใจสำหรับหลาย ๆ ตารางที่แย่กว่าการตั้งใจทิ้งไว้โดยไม่ตั้งใจสำหรับหนึ่งตาราง? ทั้งสองอย่างสามารถนำไปสู่ปัญหาประเภทเดียวกัน ฉันอยากรู้จริงๆเกี่ยวกับคำถามของคุณและฉันไม่คิดว่าเครื่องยับยั้งคือคำตอบหรือเรามีข้อ จำกัด มากมายในเครื่องยนต์ แต่ฉันยอมรับว่าหากคุณรู้สึกว่าคุณต้องทำสิ่งนี้บ่อยครั้งอาจมีบางสิ่งที่น่าสงสัย
Aaron Bertrand

@AaronBertrand มันไม่เป็นฉันโดยนัยในการถามไม่แน่ใจเรื่องการยับยั้งทั้งตั้งแต่ SQL Server ช่วยให้จำนวนมากของการปฏิบัติที่ไม่ดีอื่น ๆ เช่นการตั้งชื่อคอลัมน์ของคุณด้วยคำสงวน (บางครั้งแม้ว่าคุณจะไม่ได้ใช้ [])
เบน Brocka

@ ถูกต้องที่ไม่จำเป็นสำหรับคุณ แต่สำหรับผู้อ่านที่เจอคำถาม
Aaron Bertrand

คำตอบ:


12

ฉันคิดว่ามันจะทำให้มันยาก หากคุณสามารถทิ้งมันไว้ได้ตลอดเวลาทำไมถึงต้องมีข้อมูลส่วนตัว?

ที่จริงแล้วมีข้อ จำกัด อยู่บ้างแม้ว่า:

  • มันยังคงอยู่ในการเชื่อมต่อนั้น
  • สามารถตั้งค่าได้เพียงหนึ่งตารางต่อการเชื่อมต่อ

ตามข้อ จำกัด ที่เกี่ยวข้องกับการเชื่อมต่อฉันคิดว่าเป็นหลักดังนั้นจึงไม่เคยเปิดทิ้งไว้โดยไม่ตั้งใจ

ลองนึกภาพถ้ามีคนเปิดใช้การแทรก ID บนโต๊ะใดโต๊ะหนึ่งของคุณคุณก็ไม่ได้ตระหนักถึงและมีการใช้งานการแทรกที่ไม่ถูกต้อง (ปกติ) ที่ทำลายความสมบูรณ์ของเขตข้อมูล ID ของคุณหรือไม่

โปรดจำไว้ว่าเขตข้อมูล ID สามารถมีค่าที่ซ้ำกันหากไม่มีข้อ จำกัด หรือดัชนีที่ไม่ซ้ำในสถานที่ ...


1
+1 ฉันคิดว่าจุดสุดท้ายของคุณเกี่ยวกับรายการที่ซ้ำซ้อนนั้นพลาดไปมาก คนคิดว่าถ้าพวกเขาตั้งIDENTITYมันก็กลายเป็นข้อ จำกัด ที่ไม่ซ้ำกัน หักล้างได้ง่ายแน่นอนถ้าพวกเขาจะลอง
Aaron Bertrand

@AaronBertrand แต่อีกครั้งความเสี่ยงของรหัสที่ซ้ำกันนั้นเหมือนกันในตารางใด ๆ ที่มี IDENTITY INSERT อยู่ทำไมขีด จำกัด ยาก ฉันคิดว่าความจริงที่ว่ามันยังคงมีอยู่เพียงเพื่อการเชื่อมต่อทำให้ความระมัดระวังมากขึ้น
Ben Brocka

ฉันไม่ได้บอกว่าปัญหารหัสซ้ำกันนั้นเป็นสาเหตุของการ จำกัด ฮาร์ด
แอรอนเบอร์ทรานด์ด์

6

ฉันเดาว่านั่นเป็นข้อ จำกัด เนื่องจากการดำเนินการ การอนุญาตให้การตั้งค่านี้ในหลาย ๆ ตารางเป็นสิ่งที่น่าพอใจอย่างมาก:

เนื่องจากนี่คือพารามิเตอร์เซสชันการอนุญาตให้การตั้งค่าสามารถเปิดใช้งานบนตารางเดียวหมายความว่าเป็นแฟล็กที่เรียบง่ายและรหัสวัตถุของตารางที่จะเก็บไว้ในเซสชันฝั่งเซิร์ฟเวอร์ บางทีนี่อาจเป็นเพียงเลขจำนวนเต็มเดียว: 0 ถ้าไม่มี IDENTITY_INSERT ใช้งานอยู่และการเขียนโค้ดของฐานข้อมูล + + objectid บางส่วนสำหรับตาราง

การอนุญาตให้พารามิเตอร์ถูกตั้งค่าบนหลายตารางภายในเซสชันจะหมายความว่าเซิร์ฟเวอร์จะเก็บรายการแบบไดนามิกของวัตถุดังกล่าวและตรวจสอบทุกคำสั่งแทรก ลองนึกภาพเซสชันเปิดใช้งานพารามิเตอร์สำหรับหนึ่งพันตาราง:

  1. นี่หมายความว่าเซิร์ฟเวอร์ได้จัดสรร 1,000 รายการในตัวแปรเซสชัน
  2. ซึ่งหมายความว่าเซิร์ฟเวอร์จะต้องตรวจสอบรายการ 1,000 รายการสำหรับทุกคำสั่งแทรกในเซสชั่นนี้

นอกจากนี้ฉันสงสัยว่าเปิดใช้งาน identity_insert มีประสิทธิภาพการทำงานทั่วทั้งเซิร์ฟเวอร์ ใน sybase มี " การเผาไหม้ตัวตนตั้งปัจจัย " ซึ่งได้รับอนุญาตให้บันทึกคุณค่าของตัวตนของเคาน์เตอร์จะถูกบันทึกเพียงครั้งเดียวในขณะที่ (ค่าจะถูกเก็บไว้ในหน่วยความจำและเขียนลงบนดิสก์ครั้งหนึ่งและที่เซิร์ฟเวอร์ ปิดตัวลง ). SQL Server ขึ้นอยู่กับรหัสเดียวกันดังนั้นอาจมีการเพิ่มประสิทธิภาพที่เปรียบเทียบได้บางอย่าง แต่การเปิดใช้งาน identity_insert บนตารางอาจบังคับให้เซิร์ฟเวอร์บันทึกค่าตัวตนสำหรับการแทรกทุกครั้งเนื่องจากไม่สามารถรับประกันขนาดช่องว่างสูงสุดได้ ดังนั้นหากหนึ่งเซสชั่นทำให้ประสิทธิภาพการทำงานที่แทรกบนหนึ่งตารางนี้อาจเป็นที่ยอมรับ แต่ไม่ถ้ามันสามารถทำให้ตีสมบูรณ์ในทุกตาราง auto_increment บนเซิร์ฟเวอร์ ..


+1 อาจมีความจริงบางอย่างที่นี่ ฉันไม่ได้ซื้ออาร์กิวเมนต์ขนาดช่องว่างเนื่องจากมีเพียงรายการเดียวเท่านั้นที่INSERTสามารถดำเนินการได้ในแต่ละครั้งสำหรับเซสชันและฉันสามารถแทรกIDENTITYค่าฮาร์ดโค้ด 10 ล้านรายการได้อย่างง่ายดาย
Aaron Bertrand

ขนาดของช่องว่างเกี่ยวข้องกับสิ่งที่เกิดขึ้นในกรณีที่เกิดความผิดพลาด: บน sybase หากเซิร์ฟเวอร์ขัดข้องข้อมูลเฉพาะตัวสุดท้ายจะหายไป (อยู่ในหน่วยความจำ) ดังนั้นจึงรีสตาร์ทช่องว่าง (ดูตัวประกอบการเผาไหม้ข้อมูลประจำตัว)
Olivier S

ดังนั้นใน SQL Server คุณแนะนำว่ามีบางอย่างที่แตกต่างกันเกิดขึ้นถ้าเอ็นจิ้นล้มเหลวขณะที่แทรก 1,000,000 แถวด้วยคอลัมน์ข้อมูลประจำตัวหรือแทนที่คอลัมน์ข้อมูลประจำตัวที่มีค่าฮาร์ดโค้ด 1,000,000 ขณะSET IDENTITY_INSERTเปิดใช้งานหรือไม่ ฉันแค่แนะนำว่าขนาดช่องว่างไม่ได้ส่งผลกระทบต่อหลาย ๆ ตารางที่แตกต่างจากที่มันมีผลกับตารางเดียว
Aaron Bertrand

เดาของฉัน - ฉันไม่มีข้อพิสูจน์อย่างนี้ - คือ SET IDENTITY_INSERT บนโต๊ะบังคับให้เขียนไปยังดิสก์ของ autoincrement ที่แทรกแต่ละ เหตุผลอาจเป็นได้ว่าเนื่องจากค่าที่คุณแทรกสามารถเป็นอะไรก็ได้เซิร์ฟเวอร์ไม่สามารถพิจารณาว่า "โอเคถ้าฉันเขียนลงดิสก์เพียงครั้งเดียวทุก ๆ 1,000 แถวในกรณีที่เกิดข้อผิดพลาดฉันสามารถเพิ่ม 1,000 เป็นค่าสุดท้ายที่บันทึกไว้ได้อย่างปลอดภัย"
Olivier S
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.