В чем смысл COLLATIONS для столбцов nvarchar (Unicode)?

Я много читал об этом.

Еще несколько вопросов:

Я не говорю о чувствительном к регистру здесь...

  • Если у меня есть символ (например, ש), и он хранится в nvarchar, который может хранить что угодно, зачем мне здесь collation?

  • Если я "FaceBook" и мне нужна возможность хранить all символов из all языков, какова связь между сопоставлением и моими столбцами nvarchar?

Заранее спасибо.


person Royi Namir    schedule 18.03.2012    source источник
comment
Сопоставление [напрямую] не говорит, что можно сохранить. Сопоставление определяет порядок и равенство. Например, некоторые параметры сортировки нечувствительны к регистру или диакритическим знакам, а другие — нет.   -  person    schedule 18.03.2012
comment
@pst, если я сохранил ש и сделал «упорядочить по», поэтому он должен упорядочить по своим символам, включая ש. .....нет ?   -  person Royi Namir    schedule 18.03.2012
comment
@user166390 user166390 Сопоставление [напрямую] не говорит, что можно сохранить. не совсем верно. Это верно только для полей NVARCHAR / NCHAR. Для полей VARCHAR и CHAR сортировка действительно определяет, что может там храниться, поскольку она содержит LCID, который определяет кодовую страницу.   -  person Solomon Rutzky    schedule 30.09.2015


Ответы (3)


Хранение и представление символов — это одно, а умение их сортировать и сравнивать — другое.

Данные Unicode, хранящиеся в типах с префиксом XML и N в SQL Server, могут представлять все символы на всех языках (по большей части, и это его цель) с помощью одного набора символов. Таким образом, для данных NCHAR/NVARCHAR (я опускаю NTEXT, так как его больше не следует использовать, и XML, так как на него не влияют сопоставления), сопоставления не меняют, какие символы могут быть сохранены. Для данных CHAR и VARCHAR параметры сортировки do влияют на то, что может быть сохранено, поскольку каждое сопоставление указывает на конкретную кодовую страницу, которая определяет, что может храниться в значениях 128–255.

Теперь, хотя для всех символов существует порядок сортировки по умолчанию, он не может работать на всех языках и культурах. Есть много языков, которые используют некоторые/многие/все символы, но имеют разные правила их сортировки. Например, буква «C» стоит перед буквой «D» в большинстве алфавитов, в которых используются эти буквы. В американском английском комбинация «C» и «H» (т. е. «CH» как две отдельные буквы) естественным образом стоит перед любой строкой, начинающейся с «D». Но в некоторых языках двухбуквенная комбинация «CH» является специальной и сортируется после «D»:

IF (   N'CH' COLLATE Czech_CI_AI > N'D' COLLATE Czech_CI_AI
   AND N'C'  COLLATE Czech_CI_AI < N'D' COLLATE Czech_CI_AI
   AND N'CI' COLLATE Czech_CI_AI < N'D' COLLATE Czech_CI_AI
   ) PRINT 'Czech_CI_AI';

IF (   N'CH' COLLATE Czech_100_CI_AI > N'D' COLLATE Czech_100_CI_AI
   AND N'C'  COLLATE Czech_100_CI_AI < N'D' COLLATE Czech_100_CI_AI
   AND N'CI' COLLATE Czech_100_CI_AI < N'D' COLLATE Czech_100_CI_AI
   ) PRINT 'Czech_100_CI_AI';

IF (   N'CH' COLLATE Slovak_CI_AI > N'D' COLLATE Slovak_CI_AI
   AND N'C'  COLLATE Slovak_CI_AI < N'D' COLLATE Slovak_CI_AI
   AND N'CI' COLLATE Slovak_CI_AI < N'D' COLLATE Slovak_CI_AI
   ) PRINT 'Slovak_CI_AI';

IF (   N'CH' COLLATE Slovak_CS_AS > N'D' COLLATE Slovak_CS_AS
   AND N'C'  COLLATE Slovak_CS_AS < N'D' COLLATE Slovak_CS_AS
   AND N'CI' COLLATE Slovak_CS_AS < N'D' COLLATE Slovak_CS_AS
   ) PRINT 'Slovak_CS_AS';

IF (   N'CH' COLLATE Latin1_General_100_CI_AS > N'D' COLLATE Latin1_General_100_CI_AS
   AND N'C'  COLLATE Latin1_General_100_CI_AS < N'D' COLLATE Latin1_General_100_CI_AS
   AND N'CI' COLLATE Latin1_General_100_CI_AS < N'D' COLLATE Latin1_General_100_CI_AS
   ) PRINT 'Latin1_General_100_CI_AS'
ELSE PRINT 'Nope!';

Возвращает:

Czech_CI_AI
Czech_100_CI_AI
Slovak_CI_AI
Slovak_CS_AS
Nope!

Чтобы увидеть примеры правил сортировки для разных культур, см. таблицы сопоставления.

Кроме того, в некоторых языках определенные буквы или комбинации букв приравниваются к другим буквам, чего нет в большинстве других языков. Например, только в датском языке «å» соответствует «аа». Но «å» не означает только одну «а»:

IF (N'aa' COLLATE Danish_Greenlandic_100_CI_AI =  N'å' COLLATE Danish_Greenlandic_100_CI_AI
AND N'a'  COLLATE Danish_Greenlandic_100_CI_AI <> N'å' COLLATE Danish_Greenlandic_100_CI_AI
   ) PRINT 'Danish_Greenlandic_100_CI_AI';

IF (   N'aa' COLLATE Danish_Norwegian_CI_AI =  N'å' COLLATE Danish_Norwegian_CI_AI
   AND N'a'  COLLATE Danish_Norwegian_CI_AI <> N'å' COLLATE Danish_Norwegian_CI_AI
   ) PRINT 'Danish_Norwegian_CI_AI';

IF (   N'aa' COLLATE Latin1_General_100_CI_AI =  N'å' COLLATE Latin1_General_100_CI_AI
   AND N'a'  COLLATE Latin1_General_100_CI_AI <> N'å' COLLATE Latin1_General_100_CI_AI
   ) PRINT 'Latin1_General_100_CI_AI'
ELSE PRINT 'Nope!';

Возвращает:

Danish_Greenlandic_100_CI_AI
Danish_Norwegian_CI_AI
Nope!

Все это очень сложно, и я даже не упомянул об обработке языков с письмом справа налево (иврит и арабский), китайского, японского, комбинировании символов и т. д.

Если вы хотите получить более глубокое представление о правилах, ознакомьтесь с алгоритмом сопоставления Unicode (UCA). . Приведенные выше примеры основаны на примерах из этой документации, хотя я не думаю, что все правила UCA были реализованы, особенно с учетом того, что сопоставления Windows (сопоставления не начинаются с SQL_) основаны на Unicode. 5.0 или 6.0, в зависимости от используемой ОС и установленной версии .NET Framework (см. SortVersion для получения подробной информации).

Вот что делают сопоставления. Если вы хотите увидеть все доступные сопоставления, просто запустите следующее:

SELECT [name] FROM sys.fn_helpcollations() ORDER BY [name];
person Solomon Rutzky    schedule 30.09.2015

Если у вас один символ, то порядка нет. Но если вы заказываете, например, ИМЕНА ЛЮДЕЙ - разные специальные символы на разных языках упорядочиваются по-разному в зависимости от сортировки.

во-первых, сопоставление может быть чувствительным к регистру — показывать все B перед b — и, во-вторых, специальные символы имеют специальные правила, зависящие от сопоставления.

Документация довольно хороша в этом.

person TomTom    schedule 18.03.2012
comment
Как sql сортировать английский, арабский, иврит вместе? нет общей логики...? пожалуйста, объясни - person Royi Namir; 18.03.2012
comment
Можно, если вы невежественны. И везде используйте, например, английский порядок фортов. К сожалению, это не обязательно правильно. sqlservercentral.com В /blogs/rocks/2012/01/09/ есть один пример (испанский). Вы думаете, MS идиоты? msdn.microsoft.com/en-us/library/ms144250.aspx имеет все сопоставления, и МНОГИЕ из них зависят от языка. Вы думаете, они делают это без причины? Нет, иногда положение специальных символов в порядке сортировки зависит от языка. - person TomTom; 18.03.2012

Я думаю, что оригинальный постер путается между КОДОВЫМИ СТРАНИЦАМИ и СБОРКАМИ.

«n» в nvarchar/nchar позволяет вам хранить текст, используя набор номеров unicode, который достаточно велик, чтобы включать все символы на всех языках (во всяком случае, в принципе) с уникальным номером. Само по себе это не связано с сопоставлениями. nvarchar/nchar не использует КОДОВЫЕ СТРАНИЦЫ для кодирования/декодирования значения каждого кода символа.

Сопоставления определяют порядок сортировки символов и то, какие варианты символов следует рассматривать как идентичные. nvarchar/nchar ИСПОЛЬЗУЕТ COLLATIONS для определения этих различий.

person Chris Walsh    schedule 08.01.2014