web-dev-qa-db-ja.com

照合の正確なルールはどこにありますか?

「Finnish_Swedish_CI_AS」など、Windows(SQL Server)の照合順序で定義された正確な並べ替え/等式ルールに関するドキュメントはどこかにありますか?

CI/CS、AI/ASなどについては知っていますが、実際にそれを示すテーブルまたはルールのセットを探しています。 「a」は「b」の前にソートされます。たぶんこのページに似たもの: http://collat​​ion-charts.org/mssql/mssql.040B.1252.Finnish_Swedish_CI_AS.html このページの問題は、私がのいくつかの側面について不明確であるということですそれを読む方法。また、æが「ae」と等しいと見なされているわけではなく、そのような場合や他のルールが示されていないのではないかと思います。

また、Finnish_Swedish_CI_ASとFinnish_Swedish_100_CI_ASの正確な違いを見つけようとしています。

3
Oskar Berggren

残念ながら、そのようなドキュメントは存在しません。これの最も可能性の高い理由は、ルールの実際の複雑さのために、ほとんどの人が認識しているよりも文書化するのがはるかに難しいということです。各文字にはデフォルトの重みがありますが(その重みが0であっても)、その重みの使用方法は、いくつかのルールレイヤーによって決定されます。これらのルールの一部は照合順序に依存し(たとえば、大文字と小文字、アクセント、かな、幅の感度)、一部は単純にハードコーディングされています(たとえば、すべてではありませんが、ほとんどの場合、小文字を大文字の前に並べ替えます)。ただし、これらのタイプのルールは、処理されるルールのタイプのほんの一部です。

はい、æ = aeの単純なマッピングがありますが、文字(それ自体では表示されないが、基本文字の上に重ねられる文字)の結合を含むより複雑なマッピングがあります。例えば:

SELECT NCHAR(252), NCHAR(0x0308), N'u' + NCHAR(0x0308)
-- ü    ̈   ü

IF (NCHAR(252) = N'u' + NCHAR(0x0308)) SELECT 'Same!' ELSE SELECT 'Nope.';
-- Same!

IF (NCHAR(252) = N'u') SELECT 'Same!' ELSE SELECT 'Nope.';
-- Nope.

IF (NCHAR(252) = N'u' COLLATE Latin1_General_100_CI_AI) SELECT 'Same!' ELSE SELECT 'Nope.';
-- Same!

もちろん、一部の「文字」は、基本文字と複数の結合文字で構成されています。

また、一部の重みはコンテキスト(つまり、キャラクターが他のキャラクターとの関係で配置される場所)に依存します。たとえば、ハイフン(つまり、==マイナス記号== -)は、それ自体で文字の前にソートされます。簡単なテストでこの動作が示されます。

SELECT * FROM (VALUES ('a'), ('c'), ('-')) t(c)
ORDER BY t.c COLLATE SQL_Latin1_General_CP1_CI_AS ASC;

SELECT * FROM (VALUES ('a'), ('c'), ('-')) t(c)
ORDER BY t.c COLLATE Latin1_General_CI_AS ASC;

ここでは、両方の照合順序が同じ順序になっています。

-
a
c

次に、いくつかの文字の間にハイフンを配置しましょう。最初に、SQL Server照合順序(古い、より単純な「文字列ソート」を使用)でテストします。

SELECT * FROM (VALUES ('a'), ('c'), ('-'), ('aaa'), ('aca'), ('a-b'), ('a-d')) t(c)
ORDER BY t.c COLLATE SQL_Latin1_General_CP1_CI_AS ASC;

それは戻ります:

-
a
a-b
a-d
aaa
aca
c

ここでは、-がまだ文字の前にあることに違いはありません。そのため、両方のa-行がaa行とac行の両方の前にあります。次に、Windows照合順序を使用します。

SELECT * FROM (VALUES ('a'), ('c'), ('-'), ('aaa'), ('aca'), ('a-b'), ('a-d')) t(c)
ORDER BY t.c COLLATE Latin1_General_CI_AS ASC;

それは戻ります:

-
a
aaa
a-b
aca
a-d
c

ここに表示されているのは、文字の間にあるためにハイフンが無視されることです(もちろん、並べ替え時にのみ無視されます。比較を行うときは無視されません。これは、次のコマンドを実行すると表示されます。SELECT 1 WHERE 'a-b' = 'ab' COLLATE Latin1_General_CI_AS;)。これが、a-baaaacaの間でソートされ、abであると見なされ、a-dacaの後に来る理由です。 adであると見なされるため。

他の2つの複雑な要因は次のとおりです。

  • どのバージョンのUnicode文字データベース(UCD)とCommon Locale Data Repository(CLDR)が使用されていますか。それは1つ(または多く)が望むほど単純ではなく、Unicode標準の古いバージョンはすべての基本情報を持っていないように見えるか、少なくともそれらは確かに簡単に見つけることができません
  • MicrosoftによるUnicode標準の実装はどの程度正確ですか?結局のところ、これは単なる標準であり、ベンダーごとに異なる方法で実装できます。

そうは言っても、Unicode.orgの基本データファイルのいくつかを調べることで、探しているものにかなり近づくことができます。ただし、最初に、確認するロケール固有のカスタマイズファイルを知る必要があります。問題の照合順序のLCIDを取得することで、これを見つけることができます。

SELECT COLLATIONPROPERTY('Finnish_Swedish_CI_AS', 'LCID'),
       CONVERT(VARBINARY(3), COLLATIONPROPERTY('Finnish_Swedish_CI_AS', 'LCID'));
-- 1035       0x00040B

これで、次のページで040Bを探すことができます: LCID構造

0x040Bfi-FIを参照していることがわかります。これは、名前にfi-FIまたは単にfiが含まれているファイルを検索することを意味します。

2
Solomon Rutzky