SQL Server สามารถสร้างการชนในชื่อข้อ จำกัด ที่ระบบสร้างได้หรือไม่?
ขึ้นอยู่กับประเภทของข้อ จำกัด และรุ่นของ SQL Server
CREATE TABLE T1
(
A INT PRIMARY KEY CHECK (A > 0),
B INT DEFAULT -1 REFERENCES T1,
C INT UNIQUE,
CHECK (C > A)
)
SELECT name,
object_id,
CAST(object_id AS binary(4)) as object_id_hex,
CAST(CASE WHEN object_id >= 16000057 THEN object_id -16000057 ELSE object_id +2131483591 END AS BINARY(4)) AS object_id_offset_hex
FROM sys.objects
WHERE parent_object_id = OBJECT_ID('T1')
ORDER BY name;
drop table T1
ตัวอย่างผลลัพธ์ปี 2008
+--------------------------+-----------+---------------+----------------------+
| name | object_id | object_id_hex | object_id_offset_hex |
+--------------------------+-----------+---------------+----------------------+
| CK__T1__1D498357 | 491357015 | 0x1D498357 | 0x1C555F1E |
| CK__T1__A__1A6D16AC | 443356844 | 0x1A6D16AC | 0x1978F273 |
| DF__T1__B__1B613AE5 | 459356901 | 0x1B613AE5 | 0x1A6D16AC |
| FK__T1__B__1C555F1E | 475356958 | 0x1C555F1E | 0x1B613AE5 |
| PK__T1__3BD019AE15A8618F | 379356616 | 0x169C85C8 | 0x15A8618F |
| UQ__T1__3BD019A91884CE3A | 427356787 | 0x1978F273 | 0x1884CE3A |
+--------------------------+-----------+---------------+----------------------+
ตัวอย่างผลลัพธ์ 2017
+--------------------------+------------+---------------+----------------------+
| name | object_id | object_id_hex | object_id_offset_hex |
+--------------------------+------------+---------------+----------------------+
| CK__T1__59FA5E80 | 1509580416 | 0x59FA5E80 | 0x59063A47 |
| CK__T1__A__571DF1D5 | 1461580245 | 0x571DF1D5 | 0x5629CD9C |
| DF__T1__B__5812160E | 1477580302 | 0x5812160E | 0x571DF1D5 |
| FK__T1__B__59063A47 | 1493580359 | 0x59063A47 | 0x5812160E |
| PK__T1__3BD019AE0A4A6932 | 1429580131 | 0x5535A963 | 0x5441852A |
| UQ__T1__3BD019A981F522E0 | 1445580188 | 0x5629CD9C | 0x5535A963 |
+--------------------------+------------+---------------+----------------------+
สำหรับข้อ จำกัด เริ่มต้นให้ตรวจสอบข้อ จำกัด และข้อ จำกัด คีย์ต่างประเทศ 4 ไบต์สุดท้ายของชื่อที่สร้างขึ้นอัตโนมัติเป็นเวอร์ชันเลขฐานสิบหกของ objectid ของข้อ จำกัด ขณะที่objectid
มีการรับประกันที่ไม่ซ้ำกันชื่อยังต้องไม่ซ้ำกัน ใน Sybase เกินไปการใช้งานเหล่านี้tabname_colname_objectid
สำหรับข้อ จำกัด ที่ไม่ซ้ำกันและข้อ จำกัด คีย์หลักที่ Sybase ใช้
tabname_colname_tabindid โดยที่ tabindid คือการต่อสตริงของ ID ตารางและ ID ดัชนี
สิ่งนี้จะรับประกันความเป็นเอกลักษณ์ด้วยเช่นกัน
SQL Server ไม่ได้ใช้รูปแบบนี้
ในทั้ง SQL Server 2008 และ 2017 จะใช้สตริง 8 ไบต์ที่ส่วนท้ายของระบบที่สร้างชื่ออย่างไรก็ตามอัลกอริทึมมีการเปลี่ยนแปลงเป็นวิธี 4 ไบต์สุดท้ายของที่ถูกสร้างขึ้น
ในปี 2008 ที่ผ่านมา 4 ไบต์แทนเคาน์เตอร์จำนวนเต็มลงนามที่จะชดเชยจากobject_id
โดย-16000057
มีการตัดค่าใด ๆ ในเชิงลบไปรอบ ๆ เพื่อ int ลงนามสูงสุด (ความสำคัญของ16000057
คือว่านี่คือการเพิ่มขึ้นนำไปใช้ระหว่างสร้างขึ้นอย่างต่อเนื่องobject_id
) สิ่งนี้ยังรับประกันความเป็นเอกลักษณ์
ในปี 2012 ขึ้นไปฉันไม่เห็นรูปแบบใด ๆ เลยระหว่าง object_id ของข้อ จำกัด และจำนวนเต็มที่ได้รับจากการใช้อักขระ 8 ตัวสุดท้ายของชื่อเป็นการแสดงเลขฐานสิบหกของ int ที่ลงนามแล้ว
ชื่อฟังก์ชั่นใน call stack ในปี 2017 แสดงให้เห็นว่าตอนนี้สร้าง GUID ซึ่งเป็นส่วนหนึ่งของกระบวนการสร้างชื่อ (ในปี 2008 ฉันไม่เห็นพูดถึงMDConstraintNameGenerator
) ฉันเดาว่านี่คือการให้แหล่งที่มาของการสุ่ม เห็นได้ชัดว่ามันไม่ได้ใช้ทั้ง 16 ไบต์จาก GUID ใน 4 ไบต์ที่เปลี่ยนไประหว่างข้อ จำกัด
ฉันคิดว่าอัลกอริธึมใหม่ได้ถูกทำขึ้นด้วยเหตุผลบางประการอย่างมีประสิทธิภาพโดยเสียค่าใช้จ่ายในการเพิ่มความเป็นไปได้ของการชนในกรณีที่รุนแรงเช่นคุณ
นี่เป็นกรณีทางพยาธิวิทยาเนื่องจากต้องการคำนำหน้าชื่อตารางและชื่อคอลัมน์ของ PK (ตราบเท่าที่นี้มีผลต่ออักขระ 8 ตัวก่อน 8 สุดท้าย) จะเหมือนกันสำหรับหมื่นตารางก่อนที่จะกลายเป็นจริง แต่สามารถทำซ้ำได้ค่อนข้างมาก ได้อย่างง่ายดายด้วยด้านล่าง
CREATE OR ALTER PROC #P
AS
SET NOCOUNT ON;
DECLARE @I INT = 0;
WHILE 1 = 1
BEGIN
EXEC ('CREATE TABLE abcdefghijklmnopqrstuvwxyz' + @I + '(C INT PRIMARY KEY)');
SET @I +=1;
END
GO
EXEC #P
ตัวอย่างการรันบน SQL Server 2017 กับฐานข้อมูลที่สร้างขึ้นใหม่ล้มเหลวในเวลาไม่เกินหนึ่งนาที (หลังจากสร้างตาราง 50,931)
เกี่ยวกับข่าวสาร 2714 ระดับ 16 สถานะ 30 บรรทัด 15 มีวัตถุชื่อ 'PK__abcdefgh__3BD019A8175067CE' ในฐานข้อมูลแล้ว เกี่ยวกับข้อความ 1750, ระดับ 16, สถานะ 1, บรรทัด 15 ไม่สามารถสร้างข้อ จำกัด หรือดัชนี ดูข้อผิดพลาดก่อนหน้า