В чем смысл КОЛЛЕКЦИЙ для столбцов nvarchar (Unicode)? - PullRequest
11 голосов
/ 18 марта 2012

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

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

Я не говорю о регистрозависимом здесь ...

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

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

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

Ответы [ 3 ]

12 голосов
/ 30 сентября 2015

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

Данные Unicode, хранящиеся в типах с префиксом XML и N в SQL Server, могут представлять все символы на всех языках (по большей части, и это является его целью) с одним набором символов. Таким образом, для данных XML / NCHAR / NVARCHAR (я опускаю NTEXT, поскольку они больше не должны использоваться), параметры сортировки не изменяют то, какие символы могут быть сохранены. Для данных 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!

Чтобы ознакомиться с примерами правил сортировки по различным культурам, см .: Диаграммы сопоставления .

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

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];
6 голосов
/ 08 января 2014

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

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

Параметры сортировки определяют порядок сортировки символов, а также варианты символов, которые должны рассматриваться как идентичные.nvarchar / nchar использует COLLATIONS для определения этих различий.

6 голосов
/ 18 марта 2012

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

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

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

...