GUIDs tampaknya menjadi pilihan alami untuk kunci utama Anda - dan jika Anda benar-benar harus melakukannya, Anda mungkin bisa berdebat untuk menggunakannya untuk KUNCI UTAMA tabel. Apa yang saya sangat menyarankan untuk tidak lakukan adalah menggunakan kolom GUID sebagai kunci pengelompokan , yang SQL Server lakukan secara default, kecuali jika Anda secara khusus mengatakannya untuk tidak melakukannya.
Anda benar-benar harus memisahkan dua masalah:
yang kunci utama adalah membangun logis - salah satu kunci kandidat yang unik dan terpercaya mengidentifikasi setiap baris dalam tabel Anda. Ini bisa apa saja, benar-benar - sebuah INT
, sebuah GUID
, string - pilih apa yang paling masuk akal untuk skenario Anda.
yang kunci pengelompokan (kolom atau kolom yang mendefinisikan "indeks berkerumun" di atas meja) - ini adalah fisik hal penyimpanan-terkait, dan di sini, sebuah, stabil, terus meningkat tipe data kecil adalah memilih yang terbaik Anda - INT
atau BIGINT
sebagai Anda pilihan standar.
Secara default, kunci utama pada tabel SQL Server juga digunakan sebagai kunci pengelompokan - tetapi itu tidak harus seperti itu! Saya pribadi telah melihat keuntungan kinerja besar ketika memecah Primer / Clustered Key berbasis GUID sebelumnya menjadi dua kunci terpisah - kunci primer (logis) pada GUID, dan kunci pengelompokan (pemesanan) pada INT IDENTITY(1,1)
kolom terpisah .
Karena Kimberly Tripp - Ratu Pengindeksan - dan yang lainnya telah menyatakan berkali-kali - a GUID
karena kunci pengelompokan tidak optimal, karena karena keacakannya, itu akan menyebabkan fragmentasi halaman dan indeks yang masif dan pada umumnya kinerja yang buruk.
Ya, saya tahu - ada newsequentialid()
di SQL Server 2005 dan lebih tinggi - tetapi bahkan itu tidak benar-benar dan sepenuhnya berurutan dan dengan demikian juga menderita masalah yang sama dengan GUID
- hanya sedikit kurang begitu mencolok.
Lalu ada masalah lain yang perlu dipertimbangkan: kunci pengelompokan pada tabel akan ditambahkan ke masing-masing dan setiap entri pada masing-masing dan setiap indeks yang tidak berkerumun di meja Anda juga - sehingga Anda benar-benar ingin memastikan itu sekecil mungkin. Biasanya, sebuah INT
dengan 2+ miliar baris harus cukup untuk sebagian besar tabel - dan dibandingkan dengan GUID
sebagai kunci pengelompokan, Anda dapat menghemat ratusan megabyte penyimpanan pada disk dan memori server.
Penghitungan cepat - menggunakan INT
vs. GUID
sebagai Primer dan Kunci Clustering:
- Tabel Dasar dengan 1'000'000 baris (3,8 MB vs. 15,26 MB)
- 6 indeks nonclustered (22,89 MB vs 91,55 MB)
JUMLAH: 25 MB vs. 106 MB - dan itu hanya satu tabel!
Beberapa lebih banyak makanan untuk dipikirkan - hal-hal yang sangat baik oleh Kimberly Tripp - baca, baca lagi, cerna! Ini adalah pengindeksan SQL Server, sungguh.
PS: tentu saja, jika Anda berurusan dengan hanya beberapa ratus atau beberapa ribu baris - sebagian besar argumen ini tidak akan benar-benar berdampak pada Anda. Namun: jika Anda masuk ke dalam puluhan atau ratusan ribu baris, atau Anda mulai menghitung dalam jutaan - maka poin-poin itu menjadi sangat penting dan sangat penting untuk dipahami.
Pembaruan: jika Anda ingin PKGUID
menjadikan kolom Anda sebagai kunci utama (tetapi bukan kunci pengelompokan Anda), dan kolom lain MYINT
( INT IDENTITY
) sebagai kunci pengelompokan Anda - gunakan ini:
CREATE TABLE dbo.MyTable
(PKGUID UNIQUEIDENTIFIER NOT NULL,
MyINT INT IDENTITY(1,1) NOT NULL,
.... add more columns as needed ...... )
ALTER TABLE dbo.MyTable
ADD CONSTRAINT PK_MyTable
PRIMARY KEY NONCLUSTERED (PKGUID)
CREATE UNIQUE CLUSTERED INDEX CIX_MyTable ON dbo.MyTable(MyINT)
Pada dasarnya: Anda hanya perlu memberi tahu kendala secara eksplisitPRIMARY KEY
bahwa itu NONCLUSTERED
(jika tidak dibuat sebagai indeks berkerumun Anda, secara default) - dan kemudian Anda membuat indeks kedua yang didefinisikan sebagaiCLUSTERED
Ini akan berfungsi - dan ini opsi yang valid jika Anda memiliki sistem yang sudah ada yang perlu "direkayasa ulang" untuk kinerja. Untuk sistem baru, jika Anda mulai dari awal, dan Anda tidak berada dalam skenario replikasi, maka saya akan selalu memilih ID INT IDENTITY(1,1)
sebagai kunci utama saya yang terkelompok - jauh lebih efisien daripada yang lainnya!