Jenis pemeriksaan standar dalam SQL Server memungkinkan untuk mengindeks terhadap string tidak sensitif case namun kasus data tetap ada. Bagaimana cara kerjanya? Saya mencari mur dan baut yang sebenarnya, bit dan byte, atau sumber yang bagus yang menjelaskannya secara rinci.
create table casetest (fruitnames nvarchar(50) not null);
create unique index IX_fruitnames on casetest(fruitnames);
insert into casetest values ('apples');
insert into casetest values ('Pears');
-- this insert fails
insert into casetest values ('pears');
-- this yields 'Pears' as a result
select * from casetest (forceseek) where fruitnames = 'PEARS'
update casetest set fruitnames = 'pears' where fruitnames = 'pEArs'
-- this yields 'pears' as a result
select * from casetest (forceseek) where fruitnames = 'PEARS'
Pertanyaan tentang SQL Server Collations Anda terlalu malu untuk bertanya oleh Robert Sheldon mencakup cara menggunakan collation. Itu tidak mencakup cara kerja collation. Saya tertarik pada bagaimana indeks dapat dibuat secara efisien / tanya tidak peduli tentang kasus, sementara secara bersamaan menyimpan data kasus.
sql-server
collation
cocogorilla
sumber
sumber
Jawaban:
Ini sebenarnya bukan perilaku khusus SQL Server, hanya bagaimana hal-hal ini bekerja secara umum.
Jadi, data adalah data. Jika Anda berbicara tentang indeks khusus, data perlu disimpan karena yang lain itu akan membutuhkan tampilan-up di meja utama setiap kali untuk mendapatkan nilai yang sebenarnya, dan tidak akan ada kemungkinan indeks yang meliputi (di paling tidak untuk tipe string).
Data, baik dalam tabel / indeks berkerumun atau indeks non-berkerumun, tidak mengandung informasi collation / sorting. Ini hanyalah data. Kolasi (aturan lokal / budaya dan sensitivitas) hanyalah meta data yang dilampirkan pada kolom dan digunakan saat operasi sortir dipanggil (kecuali diganti oleh
COLLATE
klausa), yang akan mencakup pembuatan / pembangunan kembali indeks. Aturan yang didefinisikan oleh non-binary collation digunakan untuk menghasilkan kunci sortir, yang merupakan representasi biner dari string (kunci sortir tidak diperlukan dalam collations biner). Representasi biner ini menggabungkan semua aturan lokal / budaya dan sensitivitas yang dipilih. Tombol sortir digunakan untuk menempatkan catatan dalam urutan yang tepat, tetapi tidak dengan sendirinya disimpan dalam indeks atau tabel. Mereka tidak disimpan (setidaknya saya belum melihat nilai-nilai ini di indeks dan diberitahu bahwa mereka tidak disimpan) karena:Ada dua jenis kumpulan: SQL Server dan Windows.
SQL Server
SQL Server collations (orang-orang dengan nama dimulai dengan
SQL_
) adalah lebih tua, pra-SQL Server 2000 cara menyortir / membandingkan (meskipunSQL_Latin1_General_CP1_CI_AS
adalah masih default instalasi pada US English OS, cukup sedih). Dalam model yang lebih tua, sederhana, non-Unicode ini, setiap kombinasi lokal, halaman kode, dan berbagai kepekaan diberikan pemetaan statis masing-masing karakter dalam halaman kode itu. Setiap karakter diberi nilai (yaitu mengurutkan bobot) untuk menunjukkan bagaimana persamaannya dengan yang lain. Perbandingan dalam model ini tampaknya melakukan operasi dua lintasan:Satu-satunya sensitivitas yang dapat disesuaikan dalam susunan ini adalah: "huruf" dan "aksen" ("lebar", "tipe kana" dan "pemilih variasi" tidak tersedia). Juga, tak satu pun dari kumpulan ini mendukung Karakter Tambahan (yang masuk akal karena itu adalah Unicode-spesifik dan kumpulan ini hanya berlaku untuk data non-Unicode).
Pendekatan ini hanya berlaku untuk
VARCHAR
data non-Unicode . Setiap kombinasi unik lokal, halaman kode, sensitivitas huruf, dan sensitivitas aksen memiliki "ID sort" yang spesifik, yang dapat Anda lihat dalam contoh berikut:Satu-satunya perbedaan antara dua pemeriksaan pertama adalah sensitivitas huruf. Susunan ketiga adalah susunan Windows dan karenanya tidak memiliki tabel pemetaan statis.
Juga, susunan ini harus mengurutkan dan membandingkan lebih cepat daripada susunan Windows karena pencarian sederhana untuk karakter untuk mengurutkan berat. Namun, susunan ini juga jauh kurang fungsional dan harus dihindari jika memungkinkan.
Windows
Windows collations (yang namanya tidak dimulai dengan
SQL_
) adalah yang lebih baru (dimulai pada SQL Server 2000) cara menyortir / membandingkan. Dalam model Unicode yang lebih baru, kompleks, setiap kombinasi lokal, halaman kode, dan berbagai sensitivitas tidak diberikan pemetaan statis. Untuk satu hal, tidak ada halaman kode dalam model ini. Model ini memberikan nilai sortir default untuk setiap karakter, dan kemudian setiap lokal / budaya dapat menetapkan ulang nilai sortir ke sejumlah karakter. Ini memungkinkan banyak budaya untuk menggunakan karakter yang sama dengan cara yang berbeda. Ini memang memiliki pengaruh memungkinkan beberapa bahasa untuk diurutkan secara alami menggunakan susunan yang sama jika mereka tidak menggunakan karakter yang sama (dan jika salah satu dari mereka tidak perlu menetapkan ulang nilai apa pun dan cukup menggunakan default).Nilai sortir dalam model ini bukan nilai tunggal. Mereka adalah array nilai yang menetapkan bobot relatif ke huruf dasar, diakritik apa pun (yaitu aksen), casing, dll. Jika collation-case-sensitive, maka bagian "case" dari array itu digunakan, jika tidak maka diabaikan ( karenanya, tidak sensitif). Jika collation peka terhadap aksen, maka bagian "diakritik" dari array digunakan, jika tidak maka diabaikan (karenanya, tidak sensitif).
Perbandingan dalam model ini adalah operasi multi-pass:
Untuk detail lebih lanjut tentang penyortiran ini, saya akhirnya akan menerbitkan posting yang menunjukkan nilai-nilai kunci semacam itu, bagaimana mereka dihitung, perbedaan antara SQL Server dan Windows collations, dll. Tetapi untuk sekarang, silakan lihat jawaban saya untuk: Accent Sensitive Sort ( harap dicatat bahwa jawaban lain untuk pertanyaan itu adalah penjelasan yang baik tentang algoritma Unicode resmi, tetapi SQL Server malah menggunakan algoritma kustom, meskipun serupa, dan bahkan tabel bobot kustom).
Semua sensitivitas dapat disesuaikan dalam susunan ini: "huruf", "aksen", "lebar", "tipe kana", dan "pemilih variasi" (mulai pada SQL Server 2017, dan hanya untuk koleksi Jepang). Juga, beberapa kumpulan ini (ketika digunakan dengan data Unicode) mendukung Karakter Tambahan (dimulai pada SQL Server 2012). Pendekatan ini berlaku untuk data
NVARCHAR
danVARCHAR
data (bahkan data non-Unicode). Ini berlaku untukVARCHAR
data non-Unicode dengan terlebih dahulu mengkonversi nilai ke Unicode secara internal, dan kemudian menerapkan aturan sortir / perbandingan.Tolong dicatat:
SQL_Latin1_General_CP1_CI_AS
untuk sistem bahasa Inggris AS, jadi silakan pilih saran ini ). Ini dapat diubah selama instalasi. Susunan tingkat instance ini kemudian menetapkan susunan untuk[model]
DB yang merupakan templat yang digunakan saat membuat DB baru, tetapi susunan tersebut dapat diubah saat mengeksekusiCREATE DATABASE
dengan menentukanCOLLATE
klausa. Kumpulan tingkat database ini digunakan untuk variabel dan string literal, serta default untuk kolom baru (dan diubah!) KetikaCOLLATE
klausa tidak ditentukan (yang merupakan kasus untuk kode contoh dalam pertanyaan).sumber
Biasanya ini diimplementasikan menggunakan tabel collation yang menetapkan skor tertentu untuk setiap karakter. Rutin penyortiran memiliki pembanding yang menggunakan tabel yang sesuai, baik default atau ditentukan secara eksplisit, untuk membandingkan string, karakter dengan karakter, menggunakan skor kolasi mereka. Jika, misalnya, tabel susunan tertentu memberikan skor 1 ke "a" dan 201 ke "A", dan skor yang lebih rendah dalam implementasi khusus ini berarti diutamakan lebih tinggi, maka "a" akan disortir sebelum "A". Tabel lain mungkin menetapkan skor terbalik: 201 ke "a" dan 1 ke "A", dan urutannya akan terbalik. Namun tabel lain mungkin menetapkan skor yang sama untuk "a", "A", "Á", dan "Å", yang akan mengarah pada perbandingan dan penyortiran case-and-accentitive.
Demikian pula, komparator berbasis tabel susunan seperti itu digunakan ketika membandingkan kunci indeks dengan nilai yang diberikan dalam predikat.
sumber
SQL_
) ketika digunakan padaVARCHAR
data. Ini tidak sepenuhnya benar untukNVARCHAR
data atauVARCHAR
data saat menggunakan Windows collation (nama tidak dimulai denganSQL_
).