Тип сортировки по умолчанию в SQL Server позволяет индексировать строки без учета регистра, но регистр данных сохраняется. Как это на самом деле работает? Я ищу реальные гайки и болты, биты и байты, или хороший ресурс, который объясняет это подробно.
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) рассказывает, как использовать параметры сортировки в SQL Server . Это не охватывает, как работает сортировка. Меня интересует, как можно эффективно создать / запросить индекс, не заботясь о случае, одновременно сохраняя данные случая.
sql-server
collation
cocogorilla
источник
источник
Ответы:
На самом деле это не специфическое поведение SQL Server, а то, как все это работает в целом.
Итак, данные есть данные. Если говорить об индексе конкретно, данные нужно хранить , как это иначе это потребует просмотровую в основной таблице каждый раз , чтобы получить фактическое значение, и не было бы никакой возможности индекса покрытия (в хотя бы не для строковых типов).
Данные, либо в табличном / кластеризованном индексе, либо в некластеризованном индексе, не содержат никакой информации о сортировке / сортировке. Это просто данные. Параметры сортировки (правила языка и культуры и чувствительность) - это просто метаданные, прикрепленные к столбцу и используемые при вызове операции сортировки (если она не переопределена
COLLATE
пункт), который будет включать в себя создание / перестроение индекса. Правила, определенные недвоичным сопоставлением, используются для генерации ключей сортировки, которые являются двоичными представлениями строки (ключи сортировки не нужны в двоичных сопоставлениях). Эти двоичные представления включают в себя все правила локали / культуры и выбранную чувствительность. Ключи сортировки используются для размещения записей в правильном порядке, но сами не хранятся в индексе или таблице. Они не хранятся (по крайней мере, я не видел эти значения в индексе и мне сказали, что они не хранятся), потому что:Существует два типа сопоставлений: SQL Server и Windows.
SQL Server
Параметры сортировки SQL Server (все имена , начинающиеся с
SQL_
) являются старые, предварительно SQL Server 2000 способ сортировки / сравнения (даже еслиSQL_Latin1_General_CP1_CI_AS
это все еще установки по умолчанию на американском английском операционки, довольно печально). В этой более старой упрощенной модели, не поддерживающей Юникод, каждая комбинация языкового стандарта, кодовой страницы и различной чувствительности получает статическое отображение каждого из символов в этой кодовой странице. Каждому символу присваивается значение (т. Е. Вес сортировки), чтобы обозначить, как он соотносится с остальными. Сравнения в этой модели, по-видимому, выполняют двухпроходную операцию:Единственными значениями чувствительности, которые можно регулировать в этих сопоставлениях, являются: "case" и "accent" ("width", "kana type" и "selection selector" недоступны). Кроме того, ни один из этих параметров сортировки не поддерживает дополнительные символы (что имеет смысл, поскольку они являются специфичными для Unicode, и эти параметры сортировки применяются только к данным, не относящимся к Unicode).
Этот подход применяется только к не-Unicode
VARCHAR
данным. Каждая уникальная комбинация локали, кодовой страницы, чувствительности к регистру и чувствительности к акценту имеет определенный «идентификатор сортировки», который вы можете увидеть в следующем примере:Единственная разница между первыми двумя сопоставлениями - это чувствительность к регистру. Третье сопоставление является сопоставлением Windows и поэтому не имеет таблицы статического сопоставления.
Кроме того, эти сопоставления должны сортироваться и сравниваться быстрее, чем сопоставления Windows, потому что это простой поиск символов для сортировки веса. Тем не менее, эти сопоставления также гораздо менее функциональны и, как правило, их следует избегать, если это вообще возможно.
Windows
Параметры сортировки Windows (имена которых не начинаются с
SQL_
) являются более новым (начиная с SQL Server 2000) способом сортировки / сравнения. В этой новой, сложной модели Unicode каждая комбинация языкового стандарта, кодовой страницы и различной чувствительности не получает статического сопоставления. Во-первых, в этой модели нет кодовых страниц. Эта модель назначает значение сортировки по умолчанию для каждого символа, а затем каждая локаль / культура может переназначать значения сортировки любому количеству символов. Это позволяет нескольким культурам использовать одни и те же символы по-разному. Это дает возможность естественной сортировки нескольких языков с использованием одного и того же сопоставления, если они не используют одни и те же символы (и если одному из них не нужно повторно назначать какие-либо значения и можно просто использовать значения по умолчанию).Значения сортировки в этой модели не являются отдельными значениями. Они представляют собой массив значений, которые присваивают относительные веса базовой букве, любым диакритическим знакам (то есть акцентам), регистру и т. Д. Если параметры сортировки чувствительны к регистру, то используется часть «регистра» этого массива, в противном случае она игнорируется ( следовательно, нечувствителен). Если сортировка чувствительна к акценту, то используется «диакритическая» часть массива, в противном случае она игнорируется (следовательно, нечувствительна).
Сравнения в этой модели являются многопроходной операцией:
Для получения более подробной информации об этой сортировке я в конечном итоге опубликую пост, в котором показаны значения ключей сортировки, как они рассчитываются, различия между SQL Server и Windows-сопоставлениями и т. Д. Но сейчас, пожалуйста, смотрите мой ответ на: Accent Sensitive Sort ( обратите внимание, что другой ответ на этот вопрос является хорошим объяснением официального алгоритма Unicode, но вместо этого SQL Server использует собственный, хотя и схожий алгоритм и даже пользовательскую таблицу весов).
Все параметры чувствительности можно регулировать в следующих сопоставлениях: «case», «accent», «width», «kana type» и «selection selector» (начиная с SQL Server 2017 и только для сопоставлений на японском языке). Кроме того, некоторые из этих параметров сортировки (при использовании с данными Unicode) поддерживают дополнительные символы (начиная с SQL Server 2012). Этот подход применяется как к данным, так
NVARCHAR
и кVARCHAR
данным (даже не к Unicode-данным). Он применяется к данным, не относящимся к UnicodeVARCHAR
, сначала преобразовав значение в Unicode для внутреннего использования, а затем применив правила сортировки / сравнения.Пожалуйста, обратите внимание:
SQL_Latin1_General_CP1_CI_AS
для систем на английском языке в США, поэтому, пожалуйста, проголосуйте за это предложение ). Это можно изменить во время установки. Затем это сопоставление на уровне экземпляра устанавливает сопоставление для[model]
БД, которое является шаблоном, используемым при создании новых БД, но сопоставление можно изменить при выполненииCREATE DATABASE
, указавCOLLATE
предложение. Это сопоставление на уровне базы данных используется для переменных и строковых литералов, а также по умолчанию для новых (и измененных!) Столбцов, когдаCOLLATE
предложение не указано (что имеет место для примера кода в вопросе).источник
Как правило, это реализуется с использованием таблиц сопоставления, которые присваивают определенную оценку каждому персонажу. Процедура сортировки имеет компаратор, который использует соответствующую таблицу, заданную по умолчанию или заданную явно, для сравнения строк, символ за символом, с использованием их показателей сопоставления. Если, например, конкретная таблица сопоставления присваивает оценку от 1 до «а», а от 201 до «А», а более низкая оценка в этой конкретной реализации означает более высокий приоритет, то «а» будет сортироваться перед «А». Другая таблица может назначать обратные оценки: 201 - «a» и 1 - «A», и порядок сортировки будет впоследствии обратным. Еще одна таблица может присваивать равные оценки «a», «A», «Á» и «Å», что приведет к нечувствительному к регистру и акценту сравнению и сортировке.
Точно так же такой компилятор на основе таблицы сопоставления используется при сравнении ключа индекса со значением, указанным в предикате.
источник
SQL_
) при использованииVARCHAR
данных. Это не совсем верно дляNVARCHAR
данных илиVARCHAR
данных при использовании параметров сортировки Windows (имена не начинаются сSQL_
).