เมื่อใดที่ฉันควรใช้ข้อ จำกัด ที่ไม่ซ้ำกันแทนที่จะเป็นดัชนีที่ไม่ซ้ำกัน


194

เมื่อฉันต้องการให้คอลัมน์มีค่าที่แตกต่างฉันสามารถใช้ข้อ จำกัด ได้

create table t1(
id int primary key,
code varchar(10) unique NULL
);
go

หรือฉันสามารถใช้ดัชนีเฉพาะ

create table t2(
id int primary key,
code varchar(10) NULL
);
go

create unique index I_t2 on t2(code);

คอลัมน์ที่มีข้อ จำกัด เฉพาะดูเหมือนจะเป็นตัวเลือกที่ดีสำหรับดัชนีเฉพาะ

มีเหตุผลใดบ้างที่ทราบว่าใช้ข้อ จำกัด ที่เป็นเอกลักษณ์และไม่ใช้ดัชนีที่ไม่ซ้ำกันแทน


9
พวกเขาต่างกันจริงหรือ ฉันคิดว่าในบางฐานข้อมูลเช่น postgresql ข้อ จำกัด ที่ไม่เหมือนใครเพียงแค่สร้างดัชนีที่ไม่ซ้ำใคร ฉันไม่ตอบเพราะไม่รู้อะไรเกี่ยวกับเซิร์ฟเวอร์ sql
xenoterracide

6
ใน postgresql คุณสามารถใช้นิพจน์ในดัชนีที่ไม่ซ้ำกัน แต่ไม่อยู่ในข้อ จำกัด ที่ไม่ซ้ำกัน
Neil McGuigan

1
บน MS SQL พวกเขากำลังดำเนินการเหมือนกัน ลองสร้างตารางสองตารางด้วยข้อมูลเดียวกันหนึ่งรายการมีข้อ จำกัด ที่ไม่ซ้ำใครและอีกรายการหนึ่งมีดัชนีที่ไม่ซ้ำกัน พวกเขาจะใช้พื้นที่ดัชนีในปริมาณเท่ากันและทั้งคู่จะสามารถค้นหากับดัชนีที่ไม่ซ้ำกันซึ่งสร้างขึ้นในทางใดทางหนึ่ง
จอนแห่งการค้าขายทุก

คำตอบ:


153

ภายใต้ประทุนมีการใช้ข้อ จำกัด ที่ไม่เหมือนใครเช่นเดียวกับดัชนีที่ไม่ซ้ำใครดัชนีจำเป็นต้องมีเพื่อตอบสนองความต้องการได้อย่างมีประสิทธิภาพ แม้ว่าดัชนีจะถูกสร้างขึ้นอันเป็นผลมาจากข้อ จำกัด UNIQUE ผู้วางแผนคิวรีสามารถใช้มันเหมือนกับดัชนีอื่น ๆ หากเห็นว่าเป็นวิธีที่ดีที่สุดในการเข้าถึงคิวรีที่กำหนด

ดังนั้นสำหรับฐานข้อมูลที่สนับสนุนคุณสมบัติทั้งสองตัวเลือกที่จะใช้มักจะลงมาในรูปแบบและความสอดคล้องที่ต้องการ

หากคุณวางแผนที่จะใช้ดัชนีเป็นดัชนี (เช่นรหัสของคุณอาจขึ้นอยู่กับการค้นหา / การเรียงลำดับ / การกรองในเขตข้อมูลนั้นเพื่อให้รวดเร็ว) ฉันจะใช้ดัชนีที่ไม่ซ้ำกัน (และแสดงความคิดเห็นแหล่งที่มา) อย่างชัดเจนมากกว่าข้อ จำกัด ชัดเจน - ด้วยวิธีนี้หากมีการเปลี่ยนแปลงข้อกำหนดเฉพาะในแอปพลิเคชั่นที่คุณ (หรือ coder อื่น ๆ ) จะทราบเพื่อให้แน่ใจว่ามีการใส่ดัชนีที่ไม่ซ้ำกันในตำแหน่งที่ไม่ซ้ำกัน ดัชนีสมบูรณ์) นอกจากนี้ดัชนีเฉพาะสามารถตั้งชื่อได้ในดัชนีคำใบ้ (เช่น WITH (INDEX (ix_index_name)) ซึ่งฉันไม่คิดว่าเป็นกรณีของดัชนีที่สร้างขึ้นหลังฉากเพื่อจัดการเอกลักษณ์เนื่องจากคุณไม่รู้จักชื่อของมัน

ในทำนองเดียวกันถ้าคุณต้องการบังคับให้มีลักษณะเฉพาะเป็นกฎธุรกิจแทนที่จะต้องค้นหาหรือใช้ในการเรียงลำดับฉันจะใช้ข้อ จำกัด อีกครั้งเพื่อทำให้การใช้งานมีความชัดเจนยิ่งขึ้นเมื่อมีคนอื่นดูคำนิยามตารางของคุณ

โปรดทราบว่าหากคุณใช้ทั้งข้อ จำกัด ที่ไม่ซ้ำกันและดัชนีที่ไม่ซ้ำกันในเขตข้อมูลเดียวกันฐานข้อมูลจะไม่สว่างพอที่จะเห็นการทำซ้ำดังนั้นคุณจะจบลงด้วยดัชนีสองตัวที่จะใช้พื้นที่เพิ่มและชะลอการแทรก / ปรับปรุงแถว


1
ฉันสงสัยเกี่ยวกับ "ฐานข้อมูลจะไม่สว่างพอ"? นั่นเป็นความจริงสำหรับ RDBMS ทั้งหมดหรือไม่ มันได้รับคำสั่งจาก SQL-Standard หรือไม่? และแม้ว่ามันจะเป็น (และฉันสงสัยว่าทำไมมันควรจะเป็น), การใช้งานทั้งหมดใช้มันอย่างนั้นหรือไม่? หรือ: ทำไม DB ไม่สามารถ "สว่าง" ได้เพียงพอ?
Jürgen A. Erhard

4
@ jae: DBMS อาจสว่างเพียงพอ แต่คุณต้องตรวจสอบกับแต่ละ DBMS เพื่อดูว่าเป็นเช่นนั้นหรือไม่ หากคุณขอให้ MSSQL สร้างดัชนีที่เหมือนกันสองรายการมันจะสร้างสองดัชนีแทนที่จะอ้างถึงสองชื่อ (อย่างน้อยก็เป็นกรณีนี้ในครั้งสุดท้ายที่ฉันเห็นสถานการณ์เช่นนั้น (เนื่องจากข้อผิดพลาดการคัดลอก + วางในส่วนของฉัน)) ดังนั้นฉันคิดว่าเป็นกรณีเดียวกันหากมีดัชนีใดอันหนึ่งอยู่เนื่องจากข้อ จำกัด
David Spillett

3
+1 @David Spillett ฉันคิดว่าโดยทั่วไปแล้ว DBMS จะถือว่าคุณรู้ว่าคุณกำลังทำอะไรอยู่ หากคุณรู้สึกอยากสร้างดัชนีเดียวกันสองครั้งก็ไม่ได้ถามคุณในเรื่องนั้น
Andrew Barber

2
ลึกซึ้งมาก คุณรู้หรือไม่ว่าพฤติกรรมนี้อยู่ใน MySQL และ Apache Derby เช่นกัน?
corsiKa

5
คุณสามารถตั้งชื่อข้อ จำกัด และใช้ในคำใบ้ดัชนี CREATE TABLE #T(X INT CONSTRAINT PK PRIMARY KEY NONCLUSTERED);SELECT * FROM #T WITH(INDEX(PK)) WHERE X = 1. ดัชนีสามารถมีความยืดหยุ่นมากขึ้น แต่ในข้อ จำกัด นั้นไม่สนับสนุนตัวเลือกดัชนีทั้งหมดเช่นINCLUDEคอลัมน์ d หรือดัชนีที่กรอง
Martin Smith

101

นอกเหนือจากคะแนนในคำตอบอื่น ๆ นี่คือความแตกต่างที่สำคัญระหว่างสองข้อนี้

หมายเหตุ: ข้อความผิดพลาดมาจาก SQL Server 2012

ข้อผิดพลาด

การละเมิดข้อ จำกัด ที่ไม่ซ้ำกันจะส่งกลับข้อผิดพลาด 2627

Msg 2627, Level 14, State 1, Line 1
Violation of UNIQUE KEY constraint 'P1U_pk'. Cannot insert duplicate key in object 'dbo.P1U'. The duplicate key value is (1).
The statement has been terminated.

การละเมิดดัชนีที่ไม่ซ้ำกันส่งกลับข้อผิดพลาด 2601

Msg 2601, Level 14, State 1, Line 1
Cannot insert duplicate key row in object 'dbo.P1' with unique index 'P1_u'. The duplicate key value is (1).
The statement has been terminated.

ปิดการใช้งาน

ไม่สามารถปิดใช้งานข้อ จำกัด ที่ไม่ซ้ำกันได้

Msg 11415, Level 16, State 1, Line 1
Object 'P1U_pk' cannot be disabled or enabled. This action applies only to foreign key and check constraints.
Msg 4916, Level 16, State 0, Line 1
Could not enable or disable the constraint. See previous errors.

แต่ดัชนีที่ไม่ซ้ำกันที่อยู่เบื้องหลังข้อ จำกัด คีย์หลักหรือข้อ จำกัด ที่ไม่ซ้ำกันสามารถปิดใช้งานเช่นเดียวกับดัชนีที่ไม่ซ้ำกัน Hat-tip Brain2000

ALTER INDEX P1_u ON dbo.P1 DISABLE ;

สังเกตคำเตือนตามปกติว่าการปิดใช้งานดัชนีแบบคลัสเตอร์จะทำให้ข้อมูลไม่สามารถเข้าถึงได้

ตัวเลือก

ข้อ จำกัด ที่ไม่ซ้ำกันรองรับตัวเลือกการจัดทำดัชนีเช่นFILLFACTORและIGNORE_DUP_KEYแม้ว่านี่จะไม่ใช่กรณีของ SQL Server ทุกรุ่น

รวมคอลัมน์

ดัชนีที่ไม่ได้เป็นคลัสเตอร์สามารถรวมคอลัมน์ที่ไม่ได้จัดทำดัชนี (เรียกว่าดัชนีครอบคลุมนี่คือการปรับปรุงประสิทธิภาพหลัก) ดัชนีที่อยู่เบื้องหลังข้อ จำกัด หลัก KEY และ UNIQUE ไม่สามารถรวมคอลัมน์ได้ Hat-tip @ypercube

กรอง

ไม่สามารถกรองข้อ จำกัด ที่ไม่ซ้ำได้

สามารถกรองดัชนีที่ไม่ซ้ำใครได้

CREATE UNIQUE NONCLUSTERED INDEX Students6_DrivesLicence_u 
ON dbo.Students6( DriversLicenceNo ) WHERE DriversLicenceNo is not null ;

ข้อ จำกัด ของกุญแจต่างประเทศ

ข้อ จำกัด ของ Foreign Key ไม่สามารถอ้างอิงดัชนีเฉพาะที่กรองได้ แต่สามารถอ้างอิงดัชนีเฉพาะที่ไม่ผ่านการกรองได้ (ฉันคิดว่าสิ่งนี้ถูกเพิ่มเข้ามาใน SQL Server 2005)

การตั้งชื่อ

เมื่อสร้างข้อ จำกัด การระบุชื่อข้อ จำกัด เป็นทางเลือก (สำหรับข้อ จำกัด ทั้งห้าประเภท) หากคุณไม่ระบุชื่อ MSSQL จะสร้างชื่อให้คุณ

CREATE TABLE dbo.T1 (
    TID int not null PRIMARY KEY
) ;
GO
CREATE TABLE dbo.T2 (
    TID int not null CONSTRAINT T2_pk PRIMARY KEY
) ;

เมื่อสร้างดัชนีคุณต้องระบุชื่อ

Hat-tip @ i-one

การเชื่อมโยง

http://technet.microsoft.com/en-us/library/aa224827(v=SQL.80).aspx

http://technet.microsoft.com/en-us/library/ms177456.aspx


ข้อ จำกัด ที่ไม่ซ้ำกันสามารถปิดใช้งานและเปิดใช้งานผ่านวิธีการเดียวกันกับดัชนี: ALTER INDEX tbl ON uconstraint DISABLE, ALTER INDEX tbl ON uconstraint REBUILD
Brain2000

ขอบคุณ @ Brain2000 บังเอิญฉันสอนส่วนหนึ่งเกี่ยวกับการปิดใช้งานดัชนีเมื่อเช้าก่อนที่ฉันจะอ่านความคิดเห็นนี้
Greenstone Walker

10

ในการอ้างอิง MSDN เป็นแหล่งข้อมูลที่เชื่อถือได้:

ไม่มีแตกต่างที่สำคัญระหว่างการสร้างข้อ จำกัด ที่ไม่ซ้ำกันและการสร้างดัชนีที่ไม่ซ้ำที่เป็นอิสระจากข้อ จำกัด การตรวจสอบข้อมูลเกิดขึ้นในลักษณะเดียวกันและตัวเพิ่มประสิทธิภาพการสืบค้นไม่ได้แยกความแตกต่างระหว่างดัชนีเฉพาะที่สร้างโดยข้อ จำกัด หรือสร้างขึ้นเอง อย่างไรก็ตามการสร้างข้อ จำกัด UNIQUE ในคอลัมน์ทำให้วัตถุประสงค์ของดัชนีชัดเจน ... ข้อมูลเพิ่มเติมที่นี่

และ...

โปรแกรมฐานข้อมูลสร้างดัชนี UNIQUE โดยอัตโนมัติเพื่อบังคับใช้ข้อกำหนดเฉพาะของข้อ จำกัด UNIQUE ดังนั้นหากมีการพยายามแทรกแถวที่ซ้ำกัน Engine Engine จะส่งคืนข้อความแสดงข้อผิดพลาดที่ระบุว่าข้อ จำกัด UNIQUE ถูกละเมิดและไม่เพิ่มแถวลงในตาราง ยกเว้นว่ามีการระบุดัชนีคลัสเตอร์อย่างชัดเจนจะมีการสร้างดัชนีที่ไม่ซ้ำกันและไม่เป็นคลัสเตอร์โดยค่าเริ่มต้นเพื่อบังคับใช้ข้อ จำกัด UNIQUE ... รายละเอียดเพิ่มเติมที่นี่

อื่น ๆ ใน: https://technet.microsoft.com/en-us/library/aa224827%28v=sql.80%29.aspx


6

หนึ่งในความแตกต่างที่สำคัญระหว่างข้อ จำกัด ที่ไม่ซ้ำใครและดัชนีที่ไม่ซ้ำกันคือข้อ จำกัด ที่สำคัญต่างประเทศในตารางอื่นสามารถอ้างอิงคอลัมน์ที่ประกอบขึ้นเป็นข้อ จำกัด ที่ไม่ซ้ำกัน สิ่งนี้ไม่เป็นความจริงสำหรับดัชนีเฉพาะ นอกจากนี้ข้อ จำกัด ที่ไม่ซ้ำกันถูกกำหนดเป็นส่วนหนึ่งของมาตรฐาน ANSI ในขณะที่ดัชนีไม่ได้ ในที่สุดข้อ จำกัด ที่ไม่เหมือนใครในการพิจารณาว่าอาศัยอยู่ในขอบเขตของการออกแบบฐานข้อมูลเชิงตรรกะ (ซึ่งอาจนำไปใช้แตกต่างกันโดยเอ็นจิน DB ที่แตกต่างกัน) ในขณะที่ดัชนีเป็นลักษณะทางกายภาพ ดังนั้นข้อ จำกัด ที่ไม่เหมือนใครจึงเป็นสิ่งที่เปิดเผยได้มากกว่า ฉันต้องการข้อ จำกัด ที่ไม่เหมือนใครในเกือบทุกกรณี


8
-1 ใน SQL Server ต่อไปนี้ไม่ถูกต้อง: "ข้อ จำกัด foreign key ในตารางอื่นสามารถอ้างอิงคอลัมน์ที่ประกอบขึ้นเป็นข้อ จำกัด ที่ไม่ซ้ำกันซึ่งไม่เป็นความจริงสำหรับดัชนีที่ไม่ซ้ำ" ใน SQL Server เราสามารถอ้างถึงข้อ จำกัด FK กับดัชนีที่ไม่ซ้ำกัน
AK

4
ความสามารถในการ จำกัด คีย์ต่างประเทศในการอ้างอิงดัชนีเฉพาะคือฉันคิดว่าเพิ่มใน SQL Server 2005 หลายแหล่งรวมถึงบางหน้าใน BOL ไม่ได้รับการอัพเดตเพื่อสะท้อนการเปลี่ยนแปลงดังนั้นฉันจึงไม่คิดว่าคำตอบของ Dmitry สมควรได้รับ downvotes ส่วนที่เหลือของคำตอบของเขาคือจุดที่ - ข้อ จำกัด เป็นมาตรฐาน ANSI ดัชนีไม่ได้
Greenstone Walker

แม้จะมีคำตอบที่ฉันโปรดปราน
miracle173

มาตรฐานมีความสำคัญ หากมาตรฐาน Ansi คือการใช้ข้อ จำกัด ที่ไม่ซ้ำกันแล้วเราควรใช้ข้อ จำกัด ที่ไม่ซ้ำกัน
Rhyous

1

ใน Oracle ความแตกต่างที่สำคัญคือคุณสามารถสร้างดัชนีฟังก์ชั่นที่ไม่ซ้ำซึ่งไม่สามารถทำได้ด้วยข้อ จำกัด ที่ไม่ซ้ำกัน:

ตัวอย่างเช่น

create unique index ux_test on my_table (case when amount != 0 then fk_xyz end);

ดังนั้นเป็นเพียงที่ไม่ซ้ำกันสำหรับบันทึกที่มีfk_xyzamount != 0


7
ใน SQL Server (แท็กของคำถาม) ดัชนีสามารถกรองด้วยWHEREประโยค CREATE UNIQUE NONCLUSTERED INDEX P4_U ON DBO.P4 ( PID ) WHERE TXT = 'qwert' ;
Greenstone Walker

-3

ข้อ จำกัด UNIQUE เป็นที่ต้องการมากกว่าดัชนี UNIQUE เมื่อข้อ จำกัด ไม่ซ้ำกันคุณจำเป็นต้องใช้ดัชนีปกติหรือไม่ซ้ำกัน ข้อ จำกัด เป็นดัชนีประเภทอื่น ดัชนีใช้สำหรับการเข้าถึงที่รวดเร็วขึ้น

ดัชนีที่ไม่ซ้ำกันสามารถมีตำแหน่งได้ ตัวอย่างเช่นคุณสามารถสร้างดัชนีสำหรับทุก ๆ ปีตามคอลัมน์วันที่

WHERE Sale_Date BETWEEN '2012-01-01' AND '2012-12-31'

ดีที่จะเห็นประโยชน์ของข้อที่กล่าวถึง
crokusek

3
"ข้อ จำกัด เป็นดัชนีประเภทอื่นเช่นกัน" ไม่มันไม่ใช่ ข้อ จำกัด บางประการ (PK, UQ, FK) สามารถทำได้และมักถูกบังคับใช้โดยการใช้ดัชนี ไม่จำเป็นว่าจะเป็นและไม่ใช่ตามค่าเริ่มต้นใน DBMS ทั้งหมด
ypercubeᵀᴹ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.