Ya, benar-benar ada konsekuensi negatif untuk menggunakan string, bukan tipe numerik untuk Kunci Utama, dan terlebih lagi jika PK itu Clustered (yang memang dalam kasus Anda). Namun, sejauh mana Anda melihat efek (s) menggunakan bidang string adalah fungsi dari a) berapa banyak baris dalam tabel ini, dan b) berapa banyak baris dalam tabel lain yang Asing Kunci untuk PK ini. Jika Anda hanya memiliki 10k baris di tabel ini dan 100k baris di beberapa tabel lain yang FK ke tabel ini melalui bidang itu, maka mungkin itu tidak akan begitu terlihat. Tetapi efek-efek itu tentu saja menjadi lebih nyata ketika jumlah baris meningkat.
Anda perlu mempertimbangkan bahwa bidang dalam Indeks Clustered dibawa ke Indeks Non-Clustered. Jadi Anda tidak hanya melihat hingga 40 byte per baris, tetapi (40 * some_number) byte. Dan di setiap tabel FK Anda memiliki 40 byte yang sama di baris plus lebih sering daripada tidak akan ada indeks Non-Clustered pada bidang itu seperti yang digunakan dalam GABUNGAN, jadi sekarang benar-benar dua kali lipat dalam setiap tabel yang FK untuk yang ini. Jika seseorang cenderung berpikir bahwa 40 byte * 1 juta baris * 10 salinannya tidak perlu dikhawatirkan, silakan lihat artikel saya Disk Is Cheap! ORLY? yang merinci semua (atau paling tidak sebagian besar) area yang terkena dampak keputusan ini.
Hal lain yang perlu dipertimbangkan adalah bahwa pemfilteran dan pengurutan pada string, terutama ketika tidak menggunakan Kolasi biner (saya berasumsi Anda menggunakan default database yang biasanya case-insensitive) jauh lebih efisien (yaitu membutuhkan waktu lebih lama) daripada ketika menggunakan INT
/ BIGINT
. Ini memengaruhi semua kueri yang memfilter / bergabung / mengurutkan di bidang ini.
Oleh karena itu, menggunakan sesuatu seperti CHAR(5)
mungkin akan baik-baik saja untuk PK Clustered, tetapi kebanyakan jika itu juga didefinisikan dengan COLLATE Latin1_General_100_BIN2
(atau sesuatu seperti itu).
Dan dapatkah nilai [CODE]
berubah? Jika ya maka itu adalah alasan yang lebih besar untuk tidak menggunakannya sebagai PK (bahkan jika Anda mengatur agar FK ON UPDATE CASCADE
). Jika tidak bisa atau tidak akan pernah berubah itu baik-baik saja, tetapi masih ada lebih dari cukup alasan untuk tidak menggunakannya sebagai PK Clustered.
Tentu saja, pertanyaannya mungkin tidak tepat diungkapkan karena tampaknya Anda sudah memiliki bidang ini di PK Anda.
Apapun, pilihan terbaik Anda, sejauh ini, adalah menggunakan [ID_CODE]
sebagai PK Clustered, gunakan bidang itu dalam tabel terkait sebagai FK, dan simpan [CODE]
sebagai UNIQUE INDEX
(yang berarti itu adalah "kunci alternatif").
Perbarui
sedikit lebih banyak info berdasarkan pertanyaan ini di komentar pada jawaban ini:
Apakah [ID_CODE], sebagai PRIMARY KEY, opsi terbaik jika saya menggunakan kolom [KODE] untuk mencari tabel?
Ini semua tergantung pada banyak faktor, beberapa di antaranya telah saya sebutkan tetapi akan menyatakan kembali:
Kunci Utama adalah bagaimana setiap baris diidentifikasi, terlepas apakah itu dirujuk oleh Kunci Asing atau tidak. Bagaimana sistem Anda mengidentifikasi baris secara internal terkait dengan, tetapi tidak harus sama dengan, bagaimana pengguna Anda mengidentifikasi diri / baris itu. Setiap kolom TIDAK NULL dengan data unik dapat berfungsi, tetapi ada masalah kepraktisan yang perlu dipertimbangkan, terutama jika PK, pada kenyataannya, dirujuk oleh setiap FK. Misalnya GUID unik dan beberapa orang sangat suka menggunakannya karena berbagai alasan, tetapi mereka cukup buruk untuk Indeks Clustered ( NEWSEQUENTIALID
lebih baik, tetapi tidak sempurna). Di sisi lain, GUID baik-baik saja sebagai kunci alternatif dan digunakan oleh aplikasi untuk mencari baris, tetapi GABUNGAN masih dilakukan dengan menggunakan INT (atau yang serupa) PK.
Sejauh ini Anda belum memberi tahu kami bagaimana [CODE]
bidang cocok ke sistem dari semua sudut, di luar sekarang menyebutkan bahwa ini adalah bagaimana Anda mencari baris, tetapi apakah itu untuk semua pertanyaan atau hanya beberapa? Karenanya:
Mengenai [CODE]
nilai:
- Bagaimana ini dihasilkan?
- Apakah ini tambahan atau psuedo-acak?
- Apakah panjangnya seragam atau panjangnya bervariasi?
- Karakter apa yang digunakan?
- Jika menggunakan karakter alfabet: apakah case-sensitive atau tidak sensitif?
- Bisakah itu berubah setelah dimasukkan?
Mengenai tabel ini:
- Apakah ada tabel lain yang FK ke tabel ini? Atau apakah bidang ini (
[CODE]
atau [ID_CODE]
) digunakan dalam tabel lain, meskipun tidak secara eksplisit Asing Kunci?
- Jika
[CODE]
satu-satunya bidang yang digunakan untuk mendapatkan baris individual, lalu tujuan apa yang [ID_CODE]
dilayani bidang tersebut? Jika tidak digunakan, mengapa harus di tempat pertama (yang mungkin tergantung pada jawaban untuk "Bisakah [CODE]
bidang berubah?")?
- Berapa banyak baris dalam tabel ini?
- Jika tabel lain merujuk tabel ini, berapa banyak dan berapa baris di masing-masingnya?
- Apa indeks untuk tabel ini?
Keputusan ini tidak dapat dibuat murni berdasarkan pertanyaan "NVARCHAR ya atau tidak?". Saya lagi akan mengatakan bahwa secara umum saya tidak menganggapnya sebagai ide yang baik, tetapi ada kalanya tidak masalah. Mengingat begitu sedikit bidang dalam tabel ini, tidak mungkin ada lebih banyak, atau setidaknya tidak banyak, indeks. Jadi Anda mungkin baik-baik saja untuk memiliki [CODE]
Indeks Clustered. Dan jika tidak ada tabel lain referensi tabel ini maka Anda mungkin juga baik-baik saja menjadikannya PK. Tapi, jika tabel lain merujuk tabel ini maka saya akan memilih [ID_CODE]
bidang sebagai PK, bahkan jika Non-Clustered.