Акцент чутливий сортування


19

Чому ці два SELECTтвердження призводять до іншого порядку сортування?

USE tempdb;
CREATE TABLE dbo.OddSort 
(
    id INT IDENTITY(1,1) PRIMARY KEY
    , col1 NVARCHAR(2)
    , col2 NVARCHAR(2)
);
GO
INSERT dbo.OddSort (col1, col2) 
VALUES (N'e', N'eA')
    , (N'é', N'éB')
    , (N'ë', N'ëC')
    , (N'è', N'èD')
    , (N'ê', N'êE')
    , (N'ē', N'ēF');
GO

SELECT * 
FROM dbo.OddSort 
ORDER BY col1 COLLATE Latin1_General_100_CS_AS;
╔════╦══════╦══════╗
║ id ║ col1 ║ col2 ║
╠════╬══════╬══════╣
║ 1 ║ e ║ eA ║
║ 2 ║ é ║ éB ║
║ 4 ║ è ║ èD ║ - має бути id 3?
║ 5 ║ ê ║ êE ║
║ 3 ║ ë ║ ëC ║
║ 6 ║ ē ║ ēF ║
╚════╩══════╩══════╝
SELECT * 
FROM dbo.OddSort 
ORDER BY col2 COLLATE Latin1_General_100_CS_AS;
╔════╦══════╦══════╗
║ id ║ col1 ║ col2 ║
╠════╬══════╬══════╣
║ 1 ║ e ║ eA ║
║ 2 ║ é ║ éB ║
║ 3 ║ ë ║ ëC ║
║ 4 ║ è ║ èD ║
║ 5 ║ ê ║ êE ║
║ 6 ║ ē ║ ēF ║
╚════╩══════╩══════╝

Відповіді:


13

Це питання не так пов’язане з базами даних, але більше про обробку Unicode та правила.

На основі https://docs.microsoft.com/en-us/sql/t-sql/statements/windows-collation-name-transact-sql Latin1_General_100_CS_AS означає: "Для зібрання використовуються загальні правила сортування та карти словника Latin1 та карти на кодову сторінку 1252 "із доданим CS = Чутливий до регістру та AS = Акцентний.

Відображення між кодовою сторінкою Windows 1252 та Unicode ( http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT ) показує однакові значення для всіх символів, з якими ми маємо справу (за винятком e з макроном цього не існує в картографуванні Microsoft, тому немає уявлення про те, що це робиться з цим випадком), тому ми можемо зосередитись на інструментах та термінології Unicode.

По-перше, повідомте нам точно, з чим ми маємо справу, для всіх ваших рядків:

0065  LATIN SMALL LETTER E
0041  LATIN CAPITAL LETTER A
00E9  LATIN SMALL LETTER E WITH ACUTE
0042  LATIN CAPITAL LETTER B
00EB  LATIN SMALL LETTER E WITH DIAERESIS
0043  LATIN CAPITAL LETTER C
00E8  LATIN SMALL LETTER E WITH GRAVE
0044  LATIN CAPITAL LETTER D
00EA  LATIN SMALL LETTER E WITH CIRCUMFLEX
0045  LATIN CAPITAL LETTER E
0113  LATIN SMALL LETTER E WITH MACRON
0046  LATIN CAPITAL LETTER F

Алгоритм зібрання Unicode описаний тут: https://www.unicode.org/reports/tr10/

Погляньте на розділ 1.3 "Контекстна чутливість", який пояснює, що сортування не може залежати лише від одного символу за іншим, оскільки деякі правила залежать від контексту.

Зауважте також ці пункти в 1.8:

Збір не є властивістю рядків. Порядок зіставлення не зберігається під час операцій конкатенації чи підрядки.

За замовчуванням алгоритм використовує три повністю настроювані рівні. Для латинського письма ці рівні приблизно відповідають:

alphabetic ordering
diacritic ordering
case ordering.

Але алгоритм сам по собі трохи щільний. Суть його полягає в: Якщо коротко сказано, алгоритм зібрання Unicode приймає вхідний рядок Unicode та таблицю елементів зібрання, що містять дані зіставлення символів. Він виробляє ключ сортування, який представляє собою масив непідписаних 16-бітних цілих чисел. Два або більше створених ключів сортування потім можуть бути двійковими порівняннями, щоб дати правильне порівняння між рядками, для яких вони були створені.

Ви можете переглянути конкретні правила сортування з латинських країн тут: http://developer.mimer.com/collations/charts/latin.htm або більш безпосередньо та спеціально для MS SQL: http://collation-charts.org/mssql/mssql. 0409.1252.Latin1_General_CS_AS.html

Для eперсонажа він показує:

e E é è è ê ê Ê ë Ë

Це пояснює ваші результати при замовленні, за col1винятком того, що ē не існує на кодовій сторінці 1252, тому я абсолютно не маю уявлень, що з цим робити.

Або якщо ми робимо алгоритм Unicode вручну, використовуючи значення ключів DUCET за адресою http://www.unicode.org/Public/UCA/latest/allkeys.txt :

крок 1: Нормалізація форми D, тому кожен випадок стає:

e => U+0065
é => U+0065 U+0301
ë => U+0065 U+0308
è => U+0065 U+0300
ê => U+0065 U+0302
ē => U+0065 U+0304

крок 2, Створення масивів зіставлення (пошук у файлі allkeys.txt)

e => [.1D10.0020.0002]
é => [.1D10.0020.0002] [.0000.0024.0002]
ë => [.1D10.0020.0002] [.0000.002B.0002]
è => [.1D10.0020.0002] [.0000.0025.0002]
ê => [.1D10.0020.0002] [.0000.0027.0002]
ē => [.1D10.0020.0002] [.0000.0032.0002]

крок 3, Сформуйте клавіші сортування (для кожного рівня, візьміть кожне значення всередині кожного масиву зіставлення, а потім поставте 0000 як роздільник і почніть знову для наступного рівня)

e => 1D10 0000 0020 0000 0002
é => 1D10 0000 0020 0024 0000 0002 0002
ë => 1D10 0000 0020 002B 0000 0002 0002
è => 1D10 0000 0020 0025 0000 0002 0002
ê => 1D10 0000 0020 0027 0000 0002 0002
ē => 1D10 0000 0020 0032 0000 0002 0002

крок 4, Порівняйте клавіші сортування (просте двійкове порівняння кожного значення по одному): Четвертого значення достатньо для сортування їх усіх, тому остаточний порядок стає:

e
é
è
ê
ë
ē

Таким же чином для замовлення на col2:

етап 1: NFD

eA => U+0065 U+0041
éB => U+0065 U+0301 U+0042
ëC => U+0065 U+0308 U+0043
èD => U+0065 U+0300 U+0044
êE => U+0065 U+0302 U+0045
ēF => U+0065 U+0304 U+0046

крок 2: масиви зіставлення

eA => [.1D10.0020.0002] [.1CAD.0020.0008]
éB => [.1D10.0020.0002] [.0000.0024.0002] [.1CC6.0020.0008]
ëC => [.1D10.0020.0002] [.0000.002B.0002] [.1CE0.0020.0008]
èD => [.1D10.0020.0002] [.0000.0025.0002] [.1CF5.0020.0008]
êE => [.1D10.0020.0002] [.0000.0027.0002] [.1D10.0020.0008]
ēF => [.1D10.0020.0002] [.0000.0032.0002] [.1D4B.0020.0008]

крок 3: Формуйте клавіші сортування

eA => 1D10 1CAD 0000 0020 0020 0000 0002 0008
éB => 1D10 1CC6 0000 0020 0024 0020 0000 0002 0002 0008
ëC => 1D10 1CE0 0000 0020 002B 0020 0000 0002 0002 0008
èD => 1D10 1CF5 0000 0020 0025 0020 0000 0002 0002 0008
êE => 1D10 1D10 0000 0020 0027 0020 0000 0002 0002 0008
ēF => 1D10 1D4B 0000 0020 0032 0020 0000 0002 0002 0008

крок 4: Порівняйте клавіші сортування: Другого значення достатньо, щоб сортувати їх усі, і воно насправді вже в порядку зростання, тому остаточний порядок дійсно:

eA
éB
ëC
èD
êE
ēF

Оновлення : додавання третього випадку Соломона Руцкого, який складніший через простір, який дозволяє нові правила (я вибрав "неігнорований випадок"):

крок 1, NFD:

è 1 => U+0065 U+0300 U+0020 U+0031
ê 5 => U+0065 U+0302 U+0020 U+0035
e 2 => U+0065 U+0020 U+0032
é 4 => U+0065 U+0301 U+0020 U+0034
ē 3 => U+0065 U+0304 U+0020 U+0033
ë 6 => U+0065 U+0308 U+0020 U+0036

крок 2, Створіть масиви зіставлення:

è 1 => [.1D10.0020.0002] [.0000.0025.0002] [*0209.0020.0002] [.1CA4.0020.0002]
ê 5 => [.1D10.0020.0002] [.0000.0027.0002] [*0209.0020.0002] [.1CA8.0020.0002]
e 2 => [.1D10.0020.0002] [*0209.0020.0002] [.1CA5.0020.0002]
é 4 => [.1D10.0020.0002] [.0000.0024.0002] [*0209.0020.0002] [.1CA7.0020.0002]
ē 3 => [.1D10.0020.0002] [.0000.0032.0002] [*0209.0020.0002] [.1CA6.0020.0002]
ë 6 => [.1D10.0020.0002] [.0000.002B.0002] [*0209.0020.0002] [.1CA9.0020.0002]

крок 3, Формуйте клавіші сортування:

è 1 => 1D10 0209 1CA4 0000 0020 0025 0020 0020 0000 0002 0002 0002 0002
ê 5 => 1D10 0209 1CA8 0000 0020 0027 0020 0020 0000 0002 0002 0002 0002
e 2 => 1D10 0209 1CA5 0000 0020 0020 0020 0000 0002 0002 0002
é 4 => 1D10 0209 1CA7 0000 0020 0024 0020 0020 0000 0002 0002 0002 0002
ē 3 => 1D10 0209 1CA6 0000 0020 0032 0020 0020 0000 0002 0002 0002 0002
ë 6 => 1D10 0209 1CA9 0000 0020 002B 0020 0020 0000 0002 0002 0002 0002

крок 4, порівняйте клавіші сортування:

В основному третє значення визначає порядок, і воно насправді базується лише на останній цифрі, тому порядок повинен бути:

è 1
e 2
ē 3
é 4
ê 5
ë 6

Друге оновлення на основі коментаря Соломона Руцького щодо версій Unicode.

Я використовував allkeys.txtдані про останню версію Unicode в цей час, тобто версію 10.0

Якщо нам потрібно брати до уваги Unicode 5.1 , це буде: http://www.unicode.org/Public/UCA/5.1.0/allkeys.txt

Я щойно перевірив, чи для всіх символів вище вказані масиви порівняння:

e => [.119D.0020.0002.0065]
é => [.119D.0020.0002.0065] [.0000.0032.0002.0301]
ë => [.119D.0020.0002.0065] [.0000.0047.0002.0308]
è => [.119D.0020.0002.0065] [.0000.0035.0002.0300]
ê => [.119D.0020.0002.0065] [.0000.003C.0002.0302]
ē => [.119D.0020.0002.0065] [.0000.005B.0002.0304]

і:

eA => [.119D.0020.0002.0065] [.1141.0020.0008.0041]
éB => [.119D.0020.0002.0065] [.0000.0032.0002.0301] [.1157.0020.0008.0042]
ëC => [.119D.0020.0002.0065] [.0000.0047.0002.0308] [.116F.0020.0008.0043]
èD => [.119D.0020.0002.0065] [.0000.0035.0002.0300] [.1182.0020.0008.0044]
êE => [.119D.0020.0002.0065] [.0000.003C.0002.0302] [.119D.0020.0008.0045]
ēF => [.119D.0020.0002.0065] [.0000.005B.0002.0304] [.11D5.0020.0008.0046]

і:

è 1 => [.119D.0020.0002.0065] [.0000.0035.0002.0300] [*0209.0020.0002.0020] [.1138.0020.0002.0031]
ê 5 => [.119D.0020.0002.0065] [.0000.003C.0002.0302] [*0209.0020.0002.0020] [.113C.0020.0002.0035]
e 2 => [.119D.0020.0002.0065] [*0209.0020.0002.0020] [.1139.0020.0002.0032]
é 4 => [.119D.0020.0002.0065] [.0000.0032.0002.0301] [*0209.0020.0002.0020] [.113B.0020.0002.0034]
ē 3 => [.119D.0020.0002.0065] [.0000.005B.0002.0304] [*0209.0020.0002.0020] [.113A.0020.0002.0033]
ë 6 => [.119D.0020.0002.0065] [.0000.0047.0002.0308] [*0209.0020.0002.0020] [.113D.0020.0002.0036]

які потім обчислюють наступні клавіші сортування:

e => 119D 0000 0020 0000 0002 0000 0065
é => 119D 0000 0020 0032 0000 0002 0002 0000 0065 0301
ë => 119D 0000 0020 0047 0000 0002 0002 0000 0065 0308
è => 119D 0000 0020 0035 0000 0002 0002 0000 0065 0300
ê => 119D 0000 0020 003C 0000 0002 0002 0000 0065 0302
ē => 119D 0000 0020 005B 0000 0002 0002 0000 0065 0304

і:

eA => 119D 1141 0000 0020 0020 0000 0002 0008 0000 0065 0041
éB => 119D 1157 0000 0020 0032 0020 0000 0002 0002 0008 0000 0065 0301 0042
ëC => 119D 116F 0000 0020 0047 0020 0000 0002 0002 0008 0000 0065 0308 0043
èD => 119D 1182 0000 0020 0035 0020 0000 0002 0002 0008 0000 0065 0300 0044
êE => 119D 119D 0000 0020 003C 0020 0000 0002 0002 0008 0000 0065 0302 0045
ēF => 119D 11D5 0000 0020 005B 0020 0000 0002 0002 0008 0000 0065 0304 0046

і:

è 1 => 119D 0209 1138 0000 0020 0035 0020 0020 0000 0002 0002 0002 0002 0000 0065 0300 0020 0031
ê 5 => 119D 0209 113C 0000 0020 003C 0020 0020 0000 0002 0002 0002 0002 0000 0065 0302 0020 0035
e 2 => 119D 0209 1139 0000 0020 0020 0020 0000 0002 0002 0002 0000 0065 0020 0032
é 4 => 119D 0209 113B 0000 0020 0032 0020 0020 0000 0002 0002 0002 0002 0000 0065 0301 0020 0034
ē 3 => 119D 0209 113A 0000 0020 005B 0020 0020 0000 0002 0002 0002 0002 0000 0065 0304 0020 0033
ë 6 => 119D 0209 113D 0000 0020 0047 0020 0020 0000 0002 0002 0002 0002 0000 0065 0308 0020 0036

що знову дає ці три сортовані результати:

e
é
è
ê
ë
ē

і

eA
éB
ëC
èD
êE
ēF

і

è 1
e 2
ē 3
é 4
ê 5
ë 6

Привіт Патріку. Дякуємо, що опублікували цю детальну інформацію. Кілька зауважень: 1) Ви можете проігнорувати код сторінки 1252. Це стосується даних VARCHAR(тобто не Unicode), які тут не використовуються. Ось чому ēперсонаж працює просто чудово. 2) Інформація про "графіки порівняння" трохи застаріла. Це для попередньої версії цього зібрання, і вони нічого не публікували з 2009 року. 3) Версія Unicode тут, безумовно, не сама остання (версія 10). _100_Серія Параметри сортування прийшов з SQL 2008, так що це буде Unicode 5,0 або 5,1: unicode.org/standard/versions/#TUS_Earlier_Versions
Соломон Rutzky

Я не думаю, що allKeys.txt зміни між версією Unicode, окрім додавання нових символів, тому вищезазначене повинно залишатись правдивим, але, звичайно, це може бути перероблено з попередніми старими даними, мені просто не вистачає енергії, щоб знову вкласти його на кілька годин. Що стосується CP1252, то він просто виходив із визначення, даного MS-SQL (я сам не використовую цей продукт).
Патрік Мевзек

1) Можливо, між версіями не спостерігається великих змін, але я впевнений, що виправлення щодо ваги / класифікації, принаймні, є. Але так, я, звичайно, отримую обмеження в часі;) 2) Щодо CP1252, я згадував про це, оскільки концепція Code Pages не існує в Unicode. Unicode - це засіб ніколи не потребувати кодових сторінок. З цього приводу MS doc незрозуміло, але вгорі згадується " Сторінка коду, що використовується для зберігання даних символів, що не стосуються Unicode. " Ви правильні, що одного символу немає в CP1252, але кодові сторінки тут не грають.
Соломон Руцький

Так, я ніколи нічого не говорив про кодову сторінку, пов’язану з Unicode. Саме документація MS SQL говорить, що це ім'я зіставлення працює з "кодовою сторінкою 1252". Це, мабуть, не має сенсу (це не для мене, але, знову ж таки, не для користувача), але це те, що написано в документації цього програмного забезпечення. Що стосується повторної роботи, не соромтеся робити це або просто вкажіть зміни щодо сортування, пов’язаних із персонажами, які тут грають, між Unicode 5 та найновішими, якщо вони є і якщо ви хочете. Я вважаю, що моя відповідь є такою, якою вона є, точною і будує результати на основі вхідних даних, а не іншим способом.
Патрік Мевзек

3) re: речення №1: хоча здебільшого стосується Unicode, це питання є проблемою ОС, оскільки MS впровадила специфікацію і, можливо, не зробила цього всього та / або могла допустити деякі помилки. Я знайшов 2 помилки в .NET щодо того, як він визначає "категорію" або "блок", в якому знаходиться певний персонаж (вони неправильно ідентифікували невеликий сегмент символів). Крім того , це є , принаймні трохи, проблема SQL Server, тільки тому , що SQL Server ефективно знімок кожного розбір по копіям в момент часу (для узгодженості між версіями), щоб вони могли мати то , що тепер SQL Server конкретного поведінки.
Соломон Руцький

16

Поведінка, яку ви бачите тут, обумовлена ​​в загальному сенсі тим, що алгоритм зібрання Unicode (UCA) дозволяє здійснювати складне багаторівневе сортування. Більш конкретно:

  1. Сортування не є порівнянням:

    Визначення того, чи є два рядки однаковими чи різними, є досить прямим вперед (з огляду на певну локаль / мову та набір чутливості). Але визначення порядку 2 і більше рядків може бути дуже складним.

  2. Сортування проводиться в кілька кроків, при цьому кожен крок застосовується до всього рядка, а не символом за символом:

    1. Стандартно: сортувати базові символи (незалежно від наголосу та відмінності у регістрі)
    2. ЯКЩО чутливий до акценту, застосовуйте акценти / діакритичні ваги
    3. ЯКЩО залежно від регістру, застосовуйте ваги корпусу

Коли ви сортуєте за col1(один символ), він спочатку визначає, що всі символи мають однакову вагу, оскільки всі вони є " e ". Далі застосовується акцент / діакритичні ваги. Ніяких різниць оболонок немає, тому третій крок нічого не змінить. Отже, єдині відмінності полягають у кроці 2, і саме тому для цих рядків є кращий порядок col1.

Коли ви сортуєте за col2(два символи), то спочатку визначається, що кожен рядок має різну вагу, оскільки обидва символи використовуються для визначення ваги сортування (наприклад, " ea ", " eb " тощо). Далі застосовується акцент / діакритичні ваги. Ніяких різниць оболонок немає, тому третій крок нічого не змінить. Тож на етапах 1 і 2 на цей раз є відмінності. Але оскільки відмінності на етапі 1 вже застосовані до кожної струни до того, як зважуються етапи 2, ваги з кроку 2 не впливають на впорядкування; вони застосовуватимуться лише в тому випадку, якщо ваги від кроку 1 для двох або більше рядків були однаковими.

Наступна адаптація зразкового коду з питання сподівається, що ілюструє описане вище сортування. Я додав декілька додаткових рядків та додатковий стовпець, щоб допомогти показати вплив Collation на залежність від регістру (оскільки вихідні зразки даних є малі регістри):

НАСТРОЙКА

USE [tempdb];

-- DROP TABLE dbo.OddSort;
CREATE TABLE dbo.OddSort
(
    id INT IDENTITY(1,1) PRIMARY KEY,
    col1 NVARCHAR(5) COLLATE Latin1_General_100_CS_AS,
    col2 NVARCHAR(5) COLLATE Latin1_General_100_CS_AS,
    col3 NVARCHAR(5) COLLATE Latin1_General_100_CS_AS
);
GO

INSERT dbo.OddSort (col1, col2, col3)
VALUES (N'e', N'eA', N'e A')
     , (N'ê', N'êE', N'ê E')
     , (N'é', N'éH', N'é H')
     , (N'ë', N'ëC', N'ë C')
     , (N'E', N'EG', N'E G')
     , (N'Ë', N'ëh', N'ë h')
     , (N'è', N'èD', N'è D')
     , (N'é', N'éB', N'é B')
     , (N'ë', N'ëH', N'ë H')
     , (N'ē', N'ēF', N'ē F');

ТЕСТ 1

SELECT [id], [col1], UNICODE([col1]) AS [CodePoint]
FROM dbo.OddSort 
ORDER BY col1;

Повернення:

id    col1    CodePoint
1     e       101
5     E       69
8     é       233
3     é       233
7     è       232
2     ê       234
4     ë       235
9     ë       235
6     Ë       203
10    ē       275

Що ми можемо побачити в результатах вище:

  1. Точка коду не визначає порядок сортування
  2. Символи, що не мають наголосів, сортуються перед наголошеними символами (у межах однієї букви: f все-таки з'явиться після всіх цих). Зрозуміло, що акцентні ваги застосовуються перед вагами корпусу.
  3. Сортування в нижньому регістрі перед великим регістром у межах одного і того ж наголошеного (або без наголосу) символу (тобто e, тоді E , і ë, потім Ë ). Це пошиття використовується більшістю колекцій Windows, тоді як більшість зібрань SQL Server спочатку сортують великі регістри.

ТЕСТ 2

SELECT [id], [col2]
FROM dbo.OddSort 
ORDER BY col2;

Повернення:

id    col2
1     eA
8     éB
4     ëC
7     èD
2     êE
10    ēF
5     EG
3     éH
6     ëh
9     ëH

Що ми можемо побачити в результатах вище:

  1. Сортування першого рівня справді є базовими символами. Якби це наголоси / діакритики, то рядки ëC (id = 4), ēF (id = 10) та EG (id = 5) не були б там, де вони є. Якби кожух, тоді рядок EG (id = 5) не був би там, де він є.
  2. Сортування другого рівня справді - це наголоси / діакритики. Це пояснює, чому останні три ряди - еH -> ëh -> ëH замість ëh -> éH -> ëH (тобто ідентифікатори 3 -> 6 -> 9 замість 6 -> 3 -> 9).
  3. Сортування третього рівня справді є корпусом. Ось чому останні 2 ряди є ëh -> ëH , оскільки перші сортуються з малих літер .

ТЕСТ 3

SELECT [id], [col3]
FROM dbo.OddSort 
ORDER BY col3;

Повернення:

id    col3
1     e A
8     é B
4     ë C
7     è D
2     ê E
10    ē F
5     E G
3     é H
6     ë h
9     ë H

Що ми можемо побачити в результатах вище:

  1. Порядок сортування точно такий же, як у тесті 2. Єдина відмінність тестових значень тут полягає в тому, що між кожним символом є пробіл, виключаючи можливість контекстуальних правил. Отже, ми знаємо, що причина різниці в порядку сортування col2у питанні знову ж таки пов’язана з "багаторівневим порівнянням", а не "контекстною чутливістю".

Додаткові нотатки:

  1. Що стосується отримання точних правил, це не так просто, як це має бути. Проблема з отриманням конкретних пояснень цих правил полягає в тому, що правила сортування Unicode, хоча вони напевно документально підтверджені, є рекомендацією. Виконавці цих рекомендацій залежать від виробників, таких як Microsoft. Microsoft не виконала рекомендації так, як зазначено в документації на Unicode, тому там є відключення (подібно тому, як специфікації HTML або CSS не реалізуються повністю, ані навіть однаково, у постачальників). Потім існують різні версії Windows Collations (ви використовуєте версію, 100яка вийшла із SQL Server 2008), і вона прив’язана до версії Unicode, яка набагато старша за поточну версію Unicode або демо-версію ICU Collationвикористовує. Наприклад, розділ Що нового в SQL Server 2008 Collations у документації "Підтримка зібрання та Unicode" для SQL Server 2008 містить 2 дуже цікавих моменти щодо того, що є "новим" для _100_серії Collations:

    1. Таблиця випадків Unicode 5.0.

      Unicode 5.0 був опублікований у липні 2006 р. (Ну тоді тоді була випущена база даних персонажів, а повна специфікація - наприкінці 2006 року) Поточна версія 10.0, яка була опублікована в червні 2017 року. Враховуючи схему випуску останніх 4 років, цілком ймовірно, що версія 11.0 вийде десь в середині 2018 року.

    2. До попередньо не зважених символів було додано зважування, яке було б порівняно однаково.

      Ці ваги були більш ніж ймовірно визначені в стандарті Unicode, тільки не в цій його реалізації.

     
    Проте документація UCA, зв'язана вище, є гарним місцем для початку.

  2. Клавіші сортування, використовувані Windows / .NET / SQL Server, не зовсім такі, як показано в стандарті Unicode (див. @ Відповідь Патріка) або реалізовані в ICU . Щоб побачити, що використовує Windows / .NET / SQL Server, ви можете спробувати метод CompareInfo.GetSortKey . Я створив UDF SQLCLR для передачі цих значень і отримання ключа сортування. Зверніть увагу, що я використовую SQL Server 2017 у Windows 10 із встановленою .NET Framework 4.5 - 4.6.1, тому .NET повинен використовувати Unicode 6.0.0. Також Level4 не використовується для цих рядків.

    CHAR    L1     L2     L3     L4
    e      0E21
    E      0E21           12
    ë      0E21    13
    Ë      0E21    13     12

    Переглядаючи ці клавіші сортування для Тесту 1 і розуміючи, що рівні відсортовані як декілька стовпців у межах ORDER BYпункту (L3 відсортовано за одними і тими ж значеннями L2, які відсортовані в межах однакових значень L1), слід проілюструвати, що причина поведінки зазначається у питанні - це насправді багаторівнева можливість сортування Unicode. Аналогічно:

    CHAR       L1         L2       L3       L4
    EG      0E210E25              1212
    éH      0E210E2C      0E      0212
    ëh      0E210E2C      13
    ëH      0E210E2C      13      0212

    Переглядаючи деякі клавіші сортування для Тесту 2, ми можемо побачити, що базові символи спочатку сортуються (L1), потім сортуються акценти (L2), а потім сортуються корпуси (L3).

  3. Оскільки тип даних є NVARCHAR, ми стосуємося лише кодових точок Unicode та алгоритмів сортування, отже, використання UNICODE()функції в TEST 1. Хоча сторінки коду визначаються більшістю зібрань, вони стосуються лише VARCHARданих. Значення, в той час як Код сторінки 1252 визначений Latin1_General*серією Порівнень, які тут можна ігнорувати.

  4. Ваги, описані в таблиці елементів елемента зіставлення Unicode за замовчуванням (DUCET) ( версія 5.0.0, яка повинна відображатись у зіставленні _100_рядів), підходять для англійської США, але не для інших мов / мов. Інші мови потрібно починати з DUCET, а потім застосовувати специфічні для локальних правил переопределення, як визначено проектом загального локального сховища даних (CLDR). Як я можу сказати, версії 1.4 / 1.4.1 були випущені в 2006 році. Щоб отримати ці переоцінки, завантажте CLDR 1.4 "основний" файл за допомогою http://unicode.org/Public/cldr/1.4.0/core.zip , потім у цьому поштовому файлі перейдіть до папки зіставлення та знайдіть файл XML, що відповідає локалі, що використовується. Ці файли містять лише переопрацювання та не є повними наборами правил зіставлення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.