SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

SQL Server v.Next の 「140」「VSS」 の照合順序を試してみる

leave a comment

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
image image image

照合順序によってこれらのデータに対しての検索の結果が異なってきます。

SELECT * FROM CollateTest WHERE C1 = N'小澤真之' -- 真 : U+771F
SELECT * FROM CollateTest WHERE C2 = N'小澤真之' -- 真 : U+771F
SELECT * FROM CollateTest WHERE C3 = N'小澤真之' -- 真 : U+771F

各列に対して追加バリエーションを含まない形で検索をしているのですが、結果が以下となります。
image

  • 「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

 
image
「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

image
 
「XJIS_100」と「XJIS_140_VSS」の違いについては、文字列関数を使用した場合に、差としてあらわれてくるようです。

SELECT No, LEN(C1) C1, LEN(C2) C2, LEN(C3) C3 FROM CollateTest

異体字に対応している照合順序を使用している場合、追加バリエーションを含んでいる文字も一文字として認識されていますが、異体字に対応していない「XJIS_100」については、文字数が想定している値 (4 文字) になっていません。
image
DATALENGTH 関数については、バイト数を取得しますので、こちらであれば度の照合順序でも同一の値となっています。

SELECT No, DATALENGTH(C1) C1, DATALENGTH(C2) C2, DATALENGTH(C3) C3 FROM CollateTest

image
文字列を分割するような関数では異体字に対応していないと、想定した結果となりません。

SELECT No, LEFT(C1, 4) C1, LEFT(C2, 4), LEFT(C3, 4) FROM CollateTest

image
SQL Server の文字表現は、Unicode の進化に合わせて対応されていますが、文字コード絡みは、いろいろと難しいですね。

# 都度調べないと覚えていません。。。。

Share

Written by Masayuki.Ozawa

4月 3rd, 2017 at 10:36 pm

Posted in SQL Server

Tagged with ,

Leave a Reply