Domyślny typ sortowania w SQL Server pozwala na indeksowanie ciągów znaków bez rozróżniania wielkości liter, ale wielkość danych jest zachowywana. Jak to faktycznie działa? Szukam rzeczywistych nakrętek i śrub, bitów i bajtów lub dobrego zasobu, który szczegółowo to wyjaśnia.
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'
Pytania dotyczące zestawień SQL Server Byliście zbyt nieśmiali, by zadać je Robert Sheldon, omawia sposób korzystania z zestawiania. Nie obejmuje działania sortowania. Interesuje mnie, w jaki sposób można efektywnie utworzyć / zapytać o indeks, nie troszcząc się o wielkość liter przy jednoczesnym przechowywaniu danych o wielkości liter.
sql-server
collation
cocogorilla
źródło
źródło
Odpowiedzi:
W rzeczywistości nie jest to zachowanie specyficzne dla SQL Server, to po prostu, jak te rzeczy działają w ogóle.
Dane są więc danymi. Jeśli mówimy konkretnie o indeksie, dane muszą być przechowywane, ponieważ w innym przypadku wymagałoby to każdorazowego sprawdzenia w głównej tabeli, aby uzyskać rzeczywistą wartość, i nie byłoby możliwości zastosowania indeksu obejmującego (w najmniej dla typów ciągów).
Dane, zarówno w indeksie tabel / indeks klastrowy, jak i indeks nieklastrowany, nie zawierają żadnych informacji o sortowaniu / sortowaniu. To po prostu dane. Sortowanie (reguły regionalne / kultura i wrażliwości) to tylko metadane dołączone do kolumny i używane, gdy wywoływana jest operacja sortowania (chyba że zostanie zastąpiona przez
COLLATE
klauzula), która obejmowałaby utworzenie / przebudowę indeksu. Reguły zdefiniowane przez niebinarne zestawienie są używane do generowania kluczy sortowania, które są binarnymi reprezentacjami łańcucha (klucze sortowania nie są potrzebne w zestawieniach binarnych). Te reprezentacje binarne uwzględniają wszystkie reguły regionalne / kulturowe i wybrane wrażliwości. Klawisze sortowania służą do umieszczania rekordów we właściwej kolejności, ale same nie są przechowywane w indeksie lub tabeli. Nie są przechowywane (przynajmniej nie widziałem tych wartości w indeksie i powiedziano mi, że nie są przechowywane), ponieważ:Istnieją dwa rodzaje zestawień: SQL Server i Windows.
SQL Server
SQL_
Sortowania SQL Server (te o nazwach rozpoczynających się od ) są starszym sposobem sortowania / porównywania sprzed SQL Server 2000 (choć niestety nadalSQL_Latin1_General_CP1_CI_AS
jest to domyślna instalacja w amerykańskich systemach operacyjnych w języku angielskim). W tym starszym, uproszczonym modelu nieobsługującym kodu Unicode każda kombinacja ustawień regionalnych, strony kodowej i różnych wrażliwości ma statyczne mapowanie każdego ze znaków na tej stronie kodowej. Każdemu znakowi przypisuje się wartość (tj. Wagę sortowania), aby wskazać, jak jest on równy z innymi. Porównania w tym modelu wydają się wykonywać operację dwuprzebiegową:Jedynymi czułościami, które można regulować w tych zestawieniach, są: „wielkość liter” i „akcent” („szerokość”, „typ kana” i „selektor wariacji” nie są dostępne). Ponadto żadne z tych zestawień nie obsługuje znaków uzupełniających (co ma sens, ponieważ są one specyficzne dla Unicode, a te zestawienia dotyczą tylko danych innych niż Unicode).
To podejście dotyczy tylko danych nieobsługujących kodu Unicode
VARCHAR
. Każda unikalna kombinacja ustawień regionalnych, strony kodowej, rozróżniania wielkości liter i rozróżniania akcentów ma określony „identyfikator sortowania”, który można zobaczyć w następującym przykładzie:Jedyną różnicą między pierwszymi dwoma zestawieniami jest rozróżnianie wielkości liter. Trzecie sortowanie to sortowanie w systemie Windows, a zatem nie ma statycznej tabeli mapowania.
Ponadto te sortowania powinny być sortowane i porównywane szybciej niż sortowania w systemie Windows, ponieważ są prostymi funkcjami wyszukiwania znaków do sortowania według wagi. Jednak te zestawienia są również znacznie mniej funkcjonalne i należy ich unikać, jeśli to w ogóle możliwe.
Windows
Sortowania w systemie Windows (te o nazwach, które nie zaczynają się od
SQL_
) są nowszym (począwszy od SQL Server 2000) sposobem sortowania / porównywania. W tym nowszym, złożonym modelu Unicode każda kombinacja ustawień narodowych, strony kodowej i różnych wrażliwości nie ma przypisania statycznego. Po pierwsze, w tym modelu nie ma stron kodowych. Ten model przypisuje domyślną wartość sortowania do każdego znaku, a następnie każde ustawienie regionalne / kultura może ponownie przypisać wartości sortowania do dowolnej liczby znaków. Pozwala to wielu kulturom używać tych samych znaków na różne sposoby. Ma to wpływ na umożliwienie naturalnego sortowania wielu języków przy użyciu tego samego sortowania, jeśli nie używają one tych samych znaków (i jeśli jeden z nich nie musi ponownie przypisywać żadnych wartości i może po prostu użyć domyślnych).Wartości sortowania w tym modelu nie są pojedynczymi wartościami. Są to tablice wartości, które przypisują względne wagi do litery podstawowej, wszelkich znaków diakrytycznych (tj. Akcentów), obudowy itp. Jeśli w sortowaniu rozróżniana jest wielkość liter, wówczas używana jest część „wielkość liter” w tej tablicy, w przeciwnym razie zostanie zignorowana stąd niewrażliwy). Jeśli zestawienie jest wrażliwe na akcent, wówczas używana jest „diakrytyczna” część tablicy, w przeciwnym razie jest ignorowana (stąd niewrażliwa).
Porównania w tym modelu są operacją wieloprzebiegową:
Aby uzyskać więcej informacji na temat tego sortowania, ostatecznie opublikuję post, który pokazuje kluczowe wartości sortowania, sposób ich obliczania, różnice między SQL Server i zestawieniami Windows itp. Ale na razie zapoznaj się z moją odpowiedzią na: Sortowanie wrażliwe na akcent ( należy pamiętać, że inna odpowiedź na to pytanie jest dobrym wyjaśnieniem oficjalnego algorytmu Unicode, ale zamiast tego SQL Server używa niestandardowego, choć podobnego algorytmu, a nawet niestandardowej tabeli wag).
Wszystkie wrażliwości można dostosować w tych zestawieniach: „wielkość liter”, „akcent”, „szerokość”, „typ kana” i „selektor wariacji” (począwszy od SQL Server 2017 i tylko dla zestawień japońskich). Ponadto niektóre z tych zestawień (gdy są używane z danymi Unicode) obsługują dodatkowe znaki (począwszy od SQL Server 2012). To podejście dotyczy zarówno danych, jak
NVARCHAR
iVARCHAR
danych (nawet danych nieobsługujących kodu Unicode). Ma zastosowanie doVARCHAR
danych nieobsługujących kodu Unicode , najpierw konwertując wewnętrznie wartość na Unicode, a następnie stosując reguły sortowania / porównywania.Proszę zanotować:
SQL_Latin1_General_CP1_CI_AS
dotyczy systemów w języku angielskim w USA, więc proszę głosować na tę sugestię ). Można to zmienić podczas instalacji. To sortowanie na poziomie instancji ustawia następnie sortowanie dla[model]
bazy danych, która jest szablonem używanym podczas tworzenia nowych baz danych, ale sortowanie można zmienić podczas wykonywaniaCREATE DATABASE
, określającCOLLATE
klauzulę. To sortowanie na poziomie bazy danych jest używane w przypadku literałów zmiennych i literałów, a także domyślnych dla nowych (i zmienionych!) Kolumn, gdyCOLLATE
klauzula nie jest określona (tak jest w przypadku przykładowego kodu w pytaniu).źródło
Zazwyczaj jest to realizowane za pomocą tabel sortowania, które przypisują określoną ocenę każdemu znakowi. Procedura sortowania ma komparator, który wykorzystuje odpowiednią tabelę, domyślną lub jawną, do porównywania ciągów znak po znaku za pomocą ich wyników sortowania. Jeśli na przykład konkretna tabela zestawiania przypisuje wynik 1 do „a” i 201 do „A”, a niższy wynik w tej konkretnej implementacji oznacza wyższy priorytet, wówczas „a” będzie sortował przed „A”. Inna tabela może przypisywać wyniki wsteczne: 201 do „a” i 1 do „A”, a kolejność sortowania zostanie następnie odwrócona. Jeszcze inna tabela może przypisywać równe wyniki „a”, „A”, „Á” i „Å”, co prowadziłoby do porównania i sortowania bez rozróżniania wielkości liter i akcentów.
Podobnie, taki komparator oparty na tabeli zestawień stosowany podczas porównywania klucza indeksu z wartością podaną w predykacie.
źródło
SQL_
), gdy są używane wVARCHAR
danych. Nie jest to do końca prawdą w przypadkuNVARCHAR
danych lubVARCHAR
danych podczas korzystania z sortowania w systemie Windows (nazwy nie zaczynające się odSQL_
).