3.
実装方法
具体的にデータベースに実装する方法を説明します。
ここでは、SQL Server を対象としますが、要件を満たせれば、どのデータベース製品でもかまいません。
3.1. テーブルの変更
例として、テキスト型の列を持つシンプルなテーブルを想定します。
テーブル:SimpleSentence
列名 |
データ型 |
ID |
int |
SENTENCE |
ntext |
IDは、レコードを特定するためのユニークな数値です。SENTENCE は ntext 型で、この列がフルテキスト検索の対象です。日本語の短い一文がデータであるとしましょう。
このテーブルに、文字成分表のための列を追加します。
テーブル:SimpleSentence
列名 |
データ型 |
ID |
int |
SENTENCE |
ntext |
CC_SENTENCE |
bigint |
追加した CC_SENTENCE 列のデータ型はbigintで、64bit の整数です。よって、使用する文字成分表の大きさは、64bit です。
テーブルの変更はこれだけです。フルテキスト検索の対象となる列が複数ある場合には、その列毎に文字成分表のための列を用意します。
3.2. 文字成分表の作成
データベースにアクセスするプログラムに、文字成分表を作成する関数、メソッドを追加します。
以下は、C#で作成したメソッドの例です。
protected Int64 GatCharComponents( string text )
{
text = NormalizeString(text);
Int64 components = 0;
foreach (Char ch in text)
{
Int64 onebit = (Int64)1 << ((int)ch % 64);
components = components | onebit;
}
return components;
}
各文字に対応するビットは、文字コードの数値を64で割った余りの位置のビットをONにする単純なものです。
3.3. SQL文の変更
対象となるテーブルに対して実行されるSQL文を変更します。
INSERT、UPDATEの変更
レコードの追加、変更処理を修正します。
追加の際には、SENTENCE 列に格納する文字列から、GatCharComponents メソッドで文字成分表を作成し、CC_SENTENCE 列に格納します。
変更も同様で、SENTENCE 列を UPDATE する際には、新しい文字列で文字成分表を作成し、CC_SENTENCE 列も UPDATE します。
SELECTの変更
文字成分表を使用する前のSQL文が次のようであったとします。
SELECT *
FROM SimpleSentence
WHERE SENTENCE LIKE @SearchWord
@SearchWordはパラーメータで検索文字列です。検索文字列が含まれるレコードを抽出したいので、前後に'%'が付いています。
このSQL文で、文字成分表を使用するには、以下のようにします。
SELECT *
FROM SimpleSentence
WHERE CC_SENTENCE=(CC_SENTENCE|@Component)
AND SENTENCE LIKE @SearchWord
@Componentは、検索文字列の文字成分表です。
WHERE句の後ろに加えた
CC_SENTENCE=(CC_SENTENCE|@Component)
によって、レコードの数が絞り込まれます。
3.4. 文字列データの正規化
基本的な実装方法は以上のようなものですが、ひとつ解決しなければならない問題があります。
文字成分表では、ひらがなとカタカナ、アルファベットの大文字と小文字、全角と半角などを区別してしまうという点です。
この問題を放置すれば、単純に LIKE だけで検索した場合と結果が異なってしまいます。
解決するには、二つの方法が考えられます。
- データベースの設定に合わせて文字列を正規化する。
- 独自に文字列を正規化しテーブルに検索用の列を追加する。
1.データベースの設定に合わせて文字列を正規化する
データベースで設定されている区別されない文字に合わせて、文字を統一します。
ひらがなとカタカナが区別されない設定であれば、すべてのひらがなをカタカナに、または、すべてのカタカナをひらがなに変換して、文字成分表を作成します。
2.独自に文字列を正規化しテーブルに検索用の列を追加する
データベースの設定とは関係なく、文字列を正規化して文字成分表を作成します。
この場合、LIKE 演算子で検索する場合と一致しなければならないので、テーブルに検索用の列を追加し、正規化された文字列を格納するようにします。
テーブル:SimpleSentence
列名 | データ型 |
---|
ID | int |
SENTENCE | ntext |
CC_SENTENCE | bigint |
NM_SENTENCE | ntext |
INSERT,UPDATE では、NM_SENTENCE に正規化された SENTENCE の文字列を格納します。
SELECT 文でLIKE 演算子の対象を SENTENCE ではなく、NM_SENTENCE にします。