SQL Server v.Next では「140」と「_VSS」という照合順序が追加されています。
# Variation selector Sensitive の略でしょうかね。
照合順序と Unicode のサポート を見ていたところ、VSS について記載が追加されていました。
バリエーションの選択を区別する (_VSS)
SQL Server vNext から導入された日本語の照合順序 Japanese_Bushu_Kakusu_140 と Japanese_XJIS_140 で多様な表意文字のバリエーションの選択を区別します。 バリエーションのシーケンスは、基本文字と追加のバリエーションの選択で構成されます。 この _VSS オプションが選択されていない場合、照合順序はバリエーションの選択が区別されず、バリエーションの選択は比較で考慮されません。 つまり、SQL Server では、並べ替えが同じになるように、バリエーションの選択が異なる同じ基本文字に基づいて構築された文字を考慮しています。 「Unicode Ideographic Variation Database」 (Unicode 表意文字のバリエーション データベース) も参照してください。
異体字セレクターを区別する (_VSS) 照合順序は、全文検索インデックスではサポートされていません。 全文検索インデックスでは、アクセントを区別する (_AS)、かなを区別する (_KS)、文字幅を区別する (_WS) オプションのみがサポートされます。 SQL Server XML と CLR のエンジンでは、(_VSS) 異体字セレクターはサポートされていません。
異体字セレクターの 基本文字 + 追加のバリエーションの文字が考慮されるとのことですので少し試してみました。
異体字セレクターについては、以下を見るとよさそうです。
https://msdn.microsoft.com/ja-jp/library/ms143726.aspx
http://unicode.org/ivd/
http://www.mirai-ii.co.jp/moji/ivs.html
今回はテストデータに以下を使用しています。
DROP TABLE IF EXISTS CollateTest GO CREATE TABLE CollateTest( No int, C1 nvarchar(100) COLLATE Japanese_XJIS_100_CI_AS, C2 nvarchar(100) COLLATE Japanese_XJIS_140_CI_AS, C3 nvarchar(100) COLLATE Japanese_XJIS_140_CI_AS_VSS ) INSERT INTO CollateTest VALUES(1,N'小澤真之', N'小澤真之', N'小澤真之') -- 真 : U+771F INSERT INTO CollateTest VALUES(2,N'小澤真之', N'小澤真之', N'小澤真之') -- 真 : U+771F + U+E0100 INSERT INTO CollateTest VALUES(3,N'小澤真之', N'小澤真之', N'小澤真之') -- 真 : U+771F + U+E0101
- C1 : SQL Server 2016 でサポートしている「XJIS_100」
- C2 : v.Next でサポートしている「XJIS_140」
- C3 : v.Next でサポートしている「XJIS_140」+「VSS」(異体字を区別する)
となっています。
# 文字については、ワードパットで文字コードを入力→ Alt + X で合成しています。
今回のテストデータには、私の名前を使用しているのですが、「真」のコードが異なっています。
- No.1 : 通常の字を使用しているため「U+771F」
- No.2 : 基本文字の「U+771F」に、追加バリエーションの 「U+E0100」
- No.3 : 基本文字の「U+771F」に、追加バリエーションの 「U+E0101」
U+771F | U+771F + U+E0100 | U+771F + U+E0101 |
照合順序によってこれらのデータに対しての検索の結果が異なってきます。
SELECT * FROM CollateTest WHERE C1 = N'小澤真之' -- 真 : U+771F SELECT * FROM CollateTest WHERE C2 = N'小澤真之' -- 真 : U+771F SELECT * FROM CollateTest WHERE C3 = N'小澤真之' -- 真 : U+771F
各列に対して追加バリエーションを含まない形で検索をしているのですが、結果が以下となります。
- 「XJIS_100」の列に対して検索した場合 : 基本文字のデータのみ (完全一致) が検索される
- 「XJIS_140」の列に対して検索した場合:基本文字のデータ + 追加バリエーション 2 種の文字が検索される
- 基本文字を含んでいるデータが検索される
- 「XJIS_140_VSS」の列に対して検索した場合 : 基本文字のデータのみ (完全一致) が検索される
「XJIS_140」を使用して検索をした場合は、異体字かどうかの判断は厳密にしなくなるため、異体字セレクターの文字が使用されていても、基本文字が含まれていれば検索結果として取得することができています。
基本文字 + 追加バリエーションで検索した場合も同様となります。
SELECT * FROM CollateTest WHERE C1 = N'小澤真之' -- 真 : U+771F + U+E0101 SELECT * FROM CollateTest WHERE C2 = N'小澤真之' -- 真 : U+771F + U+E0101 SELECT * FROM CollateTest WHERE C3 = N'小澤真之' -- 真 : U+771F + U+E0101
「XJIS_100」「XJIS_140_VSS」に関しては、完全一致のものが検索されていますが、「XJIS_140」に関しては、同一の基本文字が使用されているデータが検索されています。
これは、LIKE の検索を行っても同一となるようです。
SELECT * FROM CollateTest WHERE C1 LIKE N'%真%' -- 真 : U+771F + U+E0101 SELECT * FROM CollateTest WHERE C2 LIKE N'%真%' -- 真 : U+771F + U+E0101 SELECT * FROM CollateTest WHERE C3 LIKE N'%真%' -- 真 : U+771F + U+E0101
「XJIS_100」と「XJIS_140_VSS」の違いについては、文字列関数を使用した場合に、差としてあらわれてくるようです。
SELECT No, LEN(C1) C1, LEN(C2) C2, LEN(C3) C3 FROM CollateTest
異体字に対応している照合順序を使用している場合、追加バリエーションを含んでいる文字も一文字として認識されていますが、異体字に対応していない「XJIS_100」については、文字数が想定している値 (4 文字) になっていません。
DATALENGTH 関数については、バイト数を取得しますので、こちらであれば度の照合順序でも同一の値となっています。
SELECT No, DATALENGTH(C1) C1, DATALENGTH(C2) C2, DATALENGTH(C3) C3 FROM CollateTest
文字列を分割するような関数では異体字に対応していないと、想定した結果となりません。
SELECT No, LEFT(C1, 4) C1, LEFT(C2, 4), LEFT(C3, 4) FROM CollateTest
SQL Server の文字表現は、Unicode の進化に合わせて対応されていますが、文字コード絡みは、いろいろと難しいですね。
# 都度調べないと覚えていません。。。。