it-swarm.asia

Kapan saya harus menggunakan batasan unik alih-alih indeks unik?

Ketika saya ingin kolom memiliki nilai yang berbeda, saya bisa menggunakan batasan

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

atau saya bisa menggunakan indeks unik

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

create unique index I_t2 on t2(code);

Kolom dengan batasan unik tampaknya menjadi kandidat yang baik untuk indeks unik.

Adakah alasan yang diketahui untuk menggunakan batasan unik dan bukan untuk menggunakan indeks unik saja?

210
bernd_k

Di bawah tenda, batasan unik diimplementasikan dengan cara yang sama dengan indeks unik - indeks diperlukan untuk secara efisien memenuhi persyaratan untuk menegakkan batasan. Bahkan jika indeks dibuat sebagai hasil dari batasan UNIK, perencana kueri dapat menggunakannya seperti indeks lain jika melihatnya sebagai cara terbaik untuk mendekati kueri yang diberikan.

Jadi untuk database yang mendukung kedua fitur pilihan yang akan digunakan akan sering turun ke gaya dan konsistensi yang disukai.

Jika Anda berencana untuk menggunakan indeks sebagai indeks (mis. Kode Anda mungkin mengandalkan pencarian/pengurutan/pemfilteran pada bidang itu agar lebih cepat) Saya akan secara eksplisit menggunakan indeks yang unik (dan mengomentari sumbernya) alih-alih kendala untuk membuatnya jelas - dengan cara ini jika persyaratan keunikan diubah dalam revisi nanti dari aplikasi yang Anda (atau coder lain) akan tahu untuk memastikan indeks non-unik diletakkan di tempat yang unik (hanya menghapus kendala unik akan menghapus indeks sepenuhnya). Juga indeks tertentu dapat dinamai dalam petunjuk indeks (mis. DENGAN (INDEX (ix_index_name)), yang menurut saya bukan kasus indeks yang dibuat di belakang layar untuk mengelola keunikan karena Anda tidak mungkin tahu namanya.

Demikian juga jika Anda hanya perlu menegakkan keunikan sebagai aturan bisnis daripada bidang yang perlu dicari atau digunakan untuk menyortir maka saya akan menggunakan kendala, lagi untuk membuat penggunaan yang dimaksudkan lebih jelas ketika orang lain melihat definisi tabel Anda.

Perhatikan bahwa jika Anda menggunakan batasan unik dan indeks unik pada bidang yang sama, basis data tidak akan cukup cerah untuk melihat duplikasi, sehingga Anda akan berakhir dengan dua indeks yang akan menggunakan ruang ekstra dan memperlambat sisipan/pembaruan baris.

165
David Spillett

Selain poin dalam jawaban lain, berikut adalah beberapa perbedaan utama antara keduanya.

Catatan: Pesan kesalahan berasal dari SQL Server 2012.

Kesalahan

Pelanggaran kesalahan pengembalian kendala unik 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.

Pelanggaran kesalahan pengembalian indeks unik 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.

Menonaktifkan

Batasan unik tidak dapat dinonaktifkan.

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.

Tetapi indeks unik di belakang batasan kunci primer atau batasan unik dapat dinonaktifkan, seperti halnya indeks unik apa pun. Hat-tip Brain2000.

ALTER INDEX P1_u ON dbo.P1 DISABLE ;

Perhatikan peringatan biasa bahwa menonaktifkan indeks yang dikelompokkan membuat data tidak dapat diakses.

Pilihan

Batasan unik mendukung opsi pengindeksan seperti FILLFACTOR dan IGNORE_DUP_KEY, meskipun ini tidak berlaku untuk setiap versi SQL Server.

Termasuk Kolom

Indeks nonclustered dapat mencakup kolom yang tidak diindeks (disebut indeks penutup, ini adalah peningkatan kinerja utama). Indeks di balik kendala PRIMARY KEY dan UNIQUE tidak dapat menyertakan kolom. Hat-tip @ypercube.

Penyaringan

Batasan unik tidak dapat difilter.

Indeks unik dapat difilter.

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

Batasan Kunci Asing

Batasan kunci asing tidak dapat referensi indeks unik difilter, meskipun itu dapat referensi indeks unik non-difilter (saya pikir ini ditambahkan dalam SQL Server 2005).

Penamaan

Saat membuat kendala, menentukan nama kendala adalah opsional (untuk semua lima jenis kendala). Jika Anda tidak menentukan nama maka MSSQL akan menghasilkan satu untuk Anda.

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

Saat membuat indeks, Anda harus menentukan nama.

Hat-tip @ i-one.

Tautan

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

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

107

Mengutip MSDN sebagai sumber resmi:

Tidak ada perbedaan yang signifikan antara membuat batasan UNIQUE dan membuat indeks unik yang tidak tergantung pada kendala . Validasi data terjadi dengan cara yang sama, dan pengoptimal kueri tidak membedakan antara indeks unik yang dibuat oleh kendala atau dibuat secara manual. Namun, membuat batasan UNIQUE pada kolom membuat tujuan indeks menjadi jelas ... info lebih lanjut di sini

Dan ...

Mesin Database secara otomatis membuat indeks UNIK untuk menegakkan persyaratan keunikan kendala UNIK. Oleh karena itu, jika upaya untuk memasukkan baris duplikat dibuat, Database Engine mengembalikan pesan kesalahan yang menyatakan kendala UNIQUE telah dilanggar dan tidak menambahkan baris ke tabel. Kecuali jika indeks yang dikelompokkan secara eksplisit ditentukan, indeks yang unik, tidak tercakup dibuat secara default untuk menegakkan batasan UNIK ... info lebih lanjut di sini

Lainnya ke: https://technet.Microsoft.com/en-us/library/aa224827%28v=sql.80%29.aspx

10
user919426

Salah satu perbedaan utama antara batasan unik dan indeks unik adalah bahwa batasan kunci asing pada tabel lain dapat mereferensikan kolom yang membentuk batasan unik. Ini tidak benar untuk indeks unik. Selain itu, batasan unik didefinisikan sebagai bagian dari standar ANSI, sedangkan indeks tidak. Akhirnya, kendala unik di anggap tinggal di ranah desain basis data logis (yang mungkin diimplementasikan secara berbeda oleh mesin DB yang berbeda) sementara indeks adalah aspek fisik. Oleh karena itu, kendala unik lebih bersifat deklaratif. Saya lebih suka kendala unik di hampir semua kasus.

7
Dmitry Frenkel

Dalam Oracle perbedaan utama adalah Anda dapat membuat indeks fungsi-unik, yang tidak dapat dilakukan dengan kendala unik:

Sebagai contoh

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

Jadi fk_xyz hanya unik untuk catatan yang memiliki amount != 0.

1
Amir Pashazadeh