Büyük / küçük harfe duyarlı olmayan harmanlama nasıl çalışır?


19

SQL Server'daki varsayılan harmanlama türü, büyük / küçük harf duyarsız dizelere karşı dizin oluşturmaya izin verir, ancak verilerin durumu kalıcıdır. Bu gerçekten nasıl çalışıyor? Gerçek somun ve cıvataları, bitleri ve baytları veya ayrıntılı olarak açıklayan iyi bir kaynağı arıyorum.

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'

Robert Sheldon tarafından sormak için çok utangaç SQL Server harmanlama hakkında sorular Harmanlama nasıl kullanılacağını kapsar. Harmanlamanın nasıl çalıştığını kapsamaz. Ben aynı anda vaka verileri depolarken, bir endeksin nasıl olay hakkında bakım değil verimli bir şekilde oluşturulabilir / sorgulanabilir ilgileniyorum.


1
Büyük / küçük harfe duyarlı bir alana karşı büyük / küçük harfe duyarlı olmayan dizeleri etkin bir şekilde sorgulayabilirsiniz (örn. Dizin araması kullanarak), ancak bu biraz can sıkıcı bir durumdur .
John Eisbrener

cocogorilla: lütfen cevabımın sonuna yeni eklediğim 1 numaralı nota bakın: "varsayılan" harmanlama.
Solomon Rutzky

Yanıtlar:


26

büyük / küçük harf duyarsız dizelere karşı endeksleme, ancak verilerin durumu devam eder. Bu gerçekten nasıl çalışıyor?

Bu aslında SQL Server'a özgü bir davranış değildir, bu şeyler genel olarak nasıl çalışır.

Yani, veriler veridir. Özellikle bir dizin hakkında konuşurken, veri ihtiyacı o başka bir gerçek değeri elde etmek her zaman bir göz-up ana tabloda gerektirecektir ve örten endeksi olasılığı yoktur olacağı gibi de (saklanmasına en azından dize türleri için değil).

Veri ya tablo / kümelenmiş dizin veya olmayan kümelenmiş endekste, yok değil herhangi harmanlama / sıralama bilgisi içerirler. Bu sadece veridir. Harmanlama (yerel ayar / kültür kuralları ve hassasiyetleri) yalnızca sütuna eklenen meta verilerdir ve bir sıralama işlemi çağrıldığında kullanılır (birCOLLATE() maddesi) içerir; bu, bir dizinin oluşturulmasını / yeniden oluşturulmasını içerir. İkili olmayan bir harmanlama ile tanımlanan kurallar, dizenin ikili gösterimleri olan sıralama anahtarları oluşturmak için kullanılır (ikili anahtarlamalarda sıralama anahtarları gereksizdir). Bu ikili gösterimler, tüm yerel ayar / kültür kurallarını ve seçilen hassasiyetleri içerir. Sıralama anahtarları kayıtları uygun sıraya koymak için kullanılır, ancak kendileri dizin veya tabloda depolanmazlar. Saklanmazlar (en azından ben bu değerleri dizinde görmedim ve saklanmadığı söylendi) çünkü:

  1. Tablodaki veya dizindeki satırlarla aynı sırada olacaklarından, sıralama için gerçekten gerekli değildir . Ancak, indeksin fiziksel sırası karşılaştırma değil sadece sıralamadır.
  2. Bunları saklamak karşılaştırmaları daha hızlı yapabilirken, tek bir karakter için minimum boyut 5 bayt olduğu için dizini büyütür ve bu sadece "genel anahtar" (sıralama anahtar yapısının). Çoğu karakter 2 bayt, artı bir aksan varsa 1 bayt, büyük harf ise 1 bayttır. Örneğin, "e" 7 baytlık bir anahtardır, "E" ve "é" nin her ikisi de 8 bayttır ve "É" 9 baytlık bir anahtardır. Bu nedenle, bunları sonunda depolamaya değmez.

İki tür harmanlama vardır: SQL Server ve Windows.

SQL Server

SQL Server alfabe (isimleri ile başlayan olanlar SQL_) karşılaştıran / sıralama daha eski, pre-SQL Server 2000 yoludur (olsa bile SQL_Latin1_General_CP1_CI_ASolduğunu hala oldukça ne yazık ki, ABD İngilizcesi işletim sistemleri üzerinde kurulum varsayılan). Bu eski, basit, Unicode olmayan modelde, her bir yerel ayar, kod sayfası ve çeşitli hassasiyet kombinasyonlarına, bu kod sayfasındaki karakterlerin her birinin statik bir eşlemesi verilir. Her karaktere, diğerleriyle nasıl eşit olduğunu belirtmek için bir değer (yani, sıralama ağırlığı) atanır. Bu modeldeki karşılaştırmalar iki geçişli bir işlem yapıyor gibi görünüyor:

  1. İlk olarak, tüm aksanları kaldırır ("  ü  ", " u " olur   ), " Æ  " gibi karakterleri "  A  " ve "  E  " ye genişletir  , sonra sözcükleri doğal bir düzende (nasıl bunları sözlükte bulmayı bekleyebilirsiniz).
  2. Daha sonra, her karakter için bu temel değerlere dayalı olarak eşitliği belirlemek karakter karakter gider . Bu ikinci kısım mustaccio içinde tarif ettiğidir onun cevabını .

Bu harmanlamalarda ayarlanabilen hassasiyetler şunlardır: "durum" ve "vurgu" ("genişlik", "kana tipi" ve "varyasyon seçici" mevcut değildir). Ayrıca, bu harmanlamaların hiçbiri Tamamlayıcı Karakterleri desteklemez (bu Unicode'a özgü oldukları için anlamlıdır ve bu harmanlamalar sadece Unicode olmayan veriler için geçerlidir).

Bu yaklaşım yalnızca Unicode olmayan VARCHARveriler için geçerlidir . Her bir yerel ayar, kod sayfası, büyük / küçük harf duyarlılığı ve aksan duyarlılığı kombinasyonunun, aşağıdaki örnekte görebileceğiniz belirli bir "sıralama kimliği" vardır:

SELECT COLLATIONPROPERTY(N'SQL_Latin1_General_CP1_CI_AS', 'SortID'), -- 52
       COLLATIONPROPERTY(N'SQL_Latin1_General_CP1_CS_AS', 'SortID'), -- 51
       COLLATIONPROPERTY(N'Latin1_General_100_CI_AS',     'SortID'); --  0

İlk iki harmanlama arasındaki tek fark büyük / küçük harfe duyarlılıktır. Üçüncü harmanlama bir Windows harmanlamasıdır ve bu nedenle statik eşleme tablosu yoktur.

Ayrıca, karakterlerin ağırlığı sıralaması için basit aramalar olması nedeniyle, bu harmanlamalar Windows harmanlamalarından daha hızlı sıralanmalı ve karşılaştırılmalıdır. Bununla birlikte, bu harmanlamalar da çok daha az işlevseldir ve mümkünse genellikle kaçınılmalıdır.

pencereler

, Windows alfabe (isimlerle olanlar değil başlayarak SQL_) yeni / sıralama karşılaştırılması yoluyla (SQL Server 2000'de başlayarak) bulunmaktadır. Bu yeni, karmaşık Unicode modelinde, yerel ayar, kod sayfasının her kombinasyonu ve çeşitli hassasiyetler vardır değil statik bir eşleme verilen. Birincisi, bu modelde kod sayfası yok. Bu model, her karaktere varsayılan bir sıralama değeri atar ve ardından her yerel ayar / kültür, herhangi bir sayıda karaktere sıralama değerleri atayabilir. Bu, birden fazla kültürün aynı karakterleri farklı şekillerde kullanmasına izin verir. Bu, aynı karakterleri kullanmazlarsa (ve bunlardan birinin herhangi bir değeri yeniden ataması gerekmiyorsa ve varsayılanları kullanabiliyorsa), aynı harmanlamayı kullanarak birden çok dilin doğal olarak sıralanmasına izin verme etkisi vardır.

Bu modeldeki sıralama değerleri tek değerler değildir. Bunlar temel harfe, aksanlara (aksanlara), kasalara vb. Göreli ağırlıklar atayan bir değerler dizisidir. Harmanlama büyük / küçük harfe duyarlıysa, o dizinin "büyük / küçük harf" kısmı kullanılır, aksi takdirde yoksayılır ( dolayısıyla, duyarsız). Harmanlama aksan duyarlıysa, dizinin "aksanik" kısmı kullanılır, aksi takdirde yok sayılır (dolayısıyla duyarsız).

Bu modeldeki karşılaştırmalar çok geçişli bir işlemdir:

  1. İlk olarak, dize normalleştirilir, böylece aynı karakteri temsil etmenin çeşitli yolları eşitlenir. Örneğin, " ü " tek bir karakter / kod noktası olabilir (U + 00FC). Ayrıca olmayan bir aksanlı "birleştirmek olabilir u bir araya getiren Tını" ile "(U + 0075) ̈ elde etmek için" (0308 U +): " ü ", sadece görünüyor ki aynı işlenmiş zaman (bir sorun ile olmadıkça yazı tipiniz), ancak ikili bir harmanlama (karakterler yerine baytları karşılaştıran) kullanılmadıkça tek karakterli sürümle (U + 00FC) aynı kabul edilir. Normalleştirme, tek karakteri " Æ  " gibi karakterlerin genişletmelerini içeren çeşitli parçalara  ayırır (yukarıda SQL Server harmanlamalarında belirtildiği gibi).
  2. Bu modeldeki karşılaştırma işlemi her duyarlılık için karakter karakter ilerler . Dizeler için sıralama tuşları, duyarlılıkların "hassas" olduğu temelde, her karakter harmanlama değer dizisinin uygun öğelerinin uygulanmasıyla belirlenir. Sıralama anahtarı değerleri, her karakterin tüm birincil duyarlılıklarına (temel karakter), ardından tüm ikincil duyarlılıklara (aksan ağırlığı), ardından her karakterin durum ağırlığına, vb. Göre düzenlenir.
  3. Sıralama hesaplanan sıralama tuşlarına göre yapılır. Her duyarlılık birlikte gruplandırıldığında, birden çok karakterin dizeleri karşılaştırılırken eşdeğer bir SQL Server harmanlamasıyla olduğundan farklı bir sıralama düzeni elde edebilirsiniz ve aksanlar da dahil edilir ve harmanlama hassastır (ve harmanlama ayrıca büyük / küçük harfe duyarlıdır).

Bu sıralama hakkında daha fazla ayrıntı için, sonunda sıralama anahtar değerlerini, nasıl hesaplandıklarını, SQL Server ve Windows harmanlamaları arasındaki farkları vb. Gösteren bir yazı yayınlayacağım. Ancak şimdilik, lütfen cevabımı görün: Accent Sensitive Sort ( bu sorunun diğer cevabının resmi Unicode algoritmasının iyi bir açıklaması olduğunu lütfen unutmayın, ancak SQL Server bunun yerine özel, algoritma ve hatta özel bir ağırlık tablosu kullanır).

Tüm duyarlılıklar şu harmanlamalarda ayarlanabilir: "vaka", "aksan", "genişlik", "kana tipi" ve "varyasyon seçici" (SQL Server 2017'den başlayarak ve yalnızca Japonca harmanlamalar için). Ayrıca, bu harmanlamalardan bazıları (Unicode verileriyle kullanıldığında) Tamamlayıcı Karakterleri (SQL Server 2012'den başlayarak) destekler. Bu yaklaşım için de geçerlidir NVARCHAR ve VARCHAR veriler (hatta Unicode verileri). VARCHARÖnce değeri Unicode'a dönüştürüp ardından sıralama / karşılaştırma kurallarını uygulayarak Unicode olmayan veriler için geçerlidir .


Lütfen aklınızda bulundurun:

  1. SQL Server için evrensel varsayılan harmanlama yoktur. Kurulum sırasında işletim sisteminin geçerli yerel ayarına / dil ayarına bağlı olarak değişen bir yükleme varsayılanı vardır (maalesef SQL_Latin1_General_CP1_CI_ASABD İngilizcesi sistemleri içindir, bu nedenle lütfen bu öneriyi oylayın ). Bu kurulum sırasında değiştirilebilir. Bu örnek düzeyi harmanlama daha sonra [model]yeni DB'ler oluşturulurken kullanılan şablon olan DB'nin harmanlamasını ayarlar , ancak harmanlama CREATE DATABASE, COLLATEcümle belirtilerek yürütülürken değiştirilebilir . Bu veritabanı düzeyi harmanlama, değişken ve dize değişmez değerleri için ve COLLATEyan tümce belirtilmediğinde yeni (ve değiştirilmiş!) Sütunlar için varsayılan olarak kullanılır (bu, sorudaki örnek kod için geçerlidir).
  2. Harmanlama / kodlama / Unicode hakkında daha fazla bilgi için lütfen şu adresi ziyaret edin: Harmanlama Bilgisi

5

Genellikle bu, her karaktere belirli bir puan atayan harmanlama tabloları kullanılarak uygulanır. Sıralama rutini, harmanlama puanlarını kullanarak dizeleri, karakter karakter karakterleri karşılaştırmak için varsayılan veya açıkça belirtilmiş uygun bir tablo kullanan bir karşılaştırıcıya sahiptir. Örneğin, belirli bir harmanlama tablosu 1'den "a" a ve 201'den "A" a atarsa ​​ve bu özel uygulamadaki daha düşük bir puan daha yüksek öncelik anlamına gelirse, "a", "A" dan önce sıralayıcı olacaktır. Başka bir tablo ters puan atayabilir: 201'den "a" ya da 1'den "A" ya ve sıralama sırası daha sonra tersine çevrilir. Yine başka bir tablo "a", "A", "Á" ve "Å" ye eşit puanlar atayabilir, bu da büyük / küçük harf duyarlı olmayan bir karşılaştırma ve sıralama sağlar.

Benzer şekilde, böyle bir karşılaştırma tablosu tabanlı karşılaştırıcı, bir indeks anahtarı yüklemde verilen değerle karşılaştırılırken kullanılır.


1
Sadece FYI: Bu bilgi yalnızca veriler SQL_üzerinde kullanıldığında SQL Server harmanlamalarını (isimleri ile başlayanlar ) kullanma açısından doğrudur VARCHAR. Bu için tam olarak doğru değildir NVARCHARveri veya VARCHARWindows harmanlama (isimleri kullanırken veri değil başlayarak SQL_).
Solomon Rutzky
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.