Ответ 1
Несколько вещей о Collations:
-
SQL_
Коллации были устаревшими с SQL Server 2000 (да, 2000). Если вы можете избежать их использования, вы должны (но это не значит, что вы меняете кучу вещей, если нет насущной необходимости!).Проблема с
SQL_
Collations действительно связана только с даннымиVARCHAR
(т.е. не Unicode), поскольку данныеNVARCHAR
(т.е. Unicode) используют правила из ОС. Но правила сортировки и сравнения данныхVARCHAR
, к сожалению, используют простое сопоставление и не включают более сложные лингвистические правила. Вот почемуss
иß
не приравниваются при сохранении какVARCHAR
с использованием того жеSQL_Latin1_General_CP1_CI_AS
Collation. Эти устаревшие коллажи также не могут дать более низкий вес тире при использовании в середине слова. НеSQL_
Collations (то есть Windows Collations) используют те же правила дляVARCHAR
иNVARCHAR
, поэтому обработкаVARCHAR
более надежная, более согласованная сNVARCHAR
. -
_BIN
Коллации были устаревшими с SQL Server 2005. Если вы можете избежать их использования, вы должны (но это не значит, что вы меняете кучу вещей, если нет насущной необходимости!).Проблема с
_BIN
Collations довольно тонкая, так как она влияет только на сортировку. Сравнение одинаково между_BIN
и_BIN2
. Сопоставления, связанные с ними, сравниваются на уровне байтов (следовательно, нет языковых правил). НО, из-за того, что SQL Server (и Windows/ПК) является маленьким Endian, объекты сохраняются в порядке обратного байта. Это становится очевидным при работе с двухбайтовыми "символами", что составляетNVARCHAR
данных: UTF-16 Little Endian. Это означает, что Unicode Code Point U + 1216 имеет шестнадцатеричное/двоичное представление 0x1216 в системах Big Endian, но хранится как 0x1612 в системах Little Endian. Чтобы пройти полный круг, чтобы важность этой последней точки (надеюсь) стала очевидной:_BIN
Collations сравнивает байты по байтам (после первого символа) и, следовательно, видит U + 1216 как 0x16, а затем 0x12, тогда как_BIN2
Коллаборации будут сравнивать кодовую точку по кодовой точке и, следовательно, видеть U + 1216 как 0x12, а затем 0x16. -
Этот столбец столбца
NVARCHAR
(aVARCHAR
, использующийSQL_Latin1_General_CP1_CI_AS
, не будет приравниватьss
иß
), и поэтому только для этого столбца нет разницы междуSQL_Latin1_General_CP437_BIN2
иSQL_Latin1_General_CP850_BIN2
из-за того, что Unicode является единым универсальным набором символов. -
Для данных
VARCHAR
будет разница, так как они являются разными кодовыми страницами (437 и 850), и оба они отличаются от тех, которые вы используете сейчас (CP1
== code page 1252). -
При использовании двоичной сортировки часто бывает излишним, в этом случае это может быть необходимо, учитывая, что существует только одна локаль/культура, которая не приравнивает
ß
кss
: венгерский. Использование венгерской сортировки может иметь некоторые лингвистические правила, которые вы не хотите (или, по крайней мере, не ожидаете), поэтому бинарный сортировка, по-видимому, является лучшим выбором здесь (просто ни один из 4, о котором вы спрашиваете:-), Просто имейте в виду, что, используя двоичную сортировку, вы не только отказываетесь от всех лингвистических правил, но также теряете способность приравнивать разные версии одного и того же символа, такие какA
(Latin Capital Letter A U + 0041) иA
(Fullwidth Latin Capital Letter A U + FF21).Используйте следующий запрос, чтобы увидеть, какие колликации не являются двоичными и не приравнивают эти символы:
DECLARE @SQL NVARCHAR(MAX) = N'DECLARE @Counter INT = 1;'; SELECT @SQL += REPLACE(N' IF(N''ß'' COLLATE {Name} = N''ss'' COLLATE {Name}) BEGIN RAISERROR(N''%4d. {Name}'', 10, 1, @Counter) WITH NOWAIT; SET @Counter += 1; END; ', N'{Name}', col.[name]) + NCHAR(13) + NCHAR(10) FROM sys.fn_helpcollations() col WHERE col.[name] NOT LIKE N'SQL[_]%' AND col.[name] NOT LIKE N'%[_]BIN%' ORDER BY col.[name] --PRINT @SQL; EXEC (@SQL);
Итак:
- Если вы собираетесь использовать двоичную сортировку, используйте что-то вроде
Latin1_General_100_BIN2
. - Вам не нужно изменять Collation всей БД и всех ее таблиц. Это большая работа, и единственный "встроенный" механизм для этого не документирован (т.е. Не поддерживается).
- Если вы хотите изменить стандартную сортировку базы данных, которая влияет на разрешение имен объектов с областью базы данных, таких как таблицы, столбцы, индексы, функции, хранимые процедуры и т.д. Значение: вам нужно будет отменить 100% приложения, которое касается базы данных, а также всех заданий агента SQL Server и т.д., которые касаются этой базы данных.
-
Если для большинства/всех запросов, которые используют этот столбец, нужно
ß
сss
восприниматься как разные, а затем перейдите к столбцу, чтобы использоватьLatin1_General_100_BIN2
. Для этого, вероятно, потребуется отбросить следующие зависимые объекты, а затем воссоздать послеALTER TABLE
:- Индексы
- Уникальные ограничения
- Ограничения внешнего ключа
СОВЕТ: Обязательно проверьте текущую настройку NULL/NOT NULL столбца и укажите это в инструкции
ALTER TABLE ... ALTER COLUMN ...
, чтобы она не менялась. - Если только некоторые запросы нуждаются в этом другом поведении, переопределите только те операции сравнения с предложением
COLLATE
на основе каждого условия (например,WHERE tab.[ThisColumn] LIKE N'%ss%' COLLATE Latin1_General_100_BIN2
). Ключевое словоCOLLATE
должно быть необходимо только с одной стороны (оператора), поскольку приоритет сортировки будет применяться к другой стороне.