もっとgroongaを知ってもらおう!ということで週刊groongaをはじめました。毎週木曜にgroongaやmroongaのトピックを投稿予定です。
groongaやmroongaを実際に使っていて、記事を書いてもいいよ、という人を募集しています。
詳細はgroonga普及のための協力のお願いを参照してください。
はじめに
MySQLで高速に全文検索するためのオープンソースのストレージエンジンとしてmroongaを公開しています。最新のバージョンは2013年2月9日にリリースしたmroonga 3.00です。
mroonga 3.00では、文字列を比較したり並べ替えるときに使われるCOLLATION(照合順序)のうち、 utf8_general_ci と utf8mb4_general_ci をサポートしました。
照合順序として utf8_general_ci もしくは utf8mb4_general_ci を使いたい場合には、 groonga-normalizer-mysql パッケージをあらかじめインストールしておく必要があります。
COLLATIONを使うと大文字小文字の区別なく比較(例えば、Aとaを同一視する)することができます。例の場合はgroongaのnormalizerが提供している機能と同じです。
ただし、mroongaではgroongaのnormalizerを使って同一視する文字を判定し、その結果のソートはMySQLにやってもらうという役割を分担した仕組みになっています。
そのため、groongaのnormalizerとMyISAMやInnoDBとで同一視する文字が異なっていると、仕組み上他のストレージエンジンを使った場合と結果が異なるという問題がありました。
今回の改良でMyISAMでもInnoDBでもmroongaでも同じ文字を同一視するようになりました。
例えば、「a」(U+0061 LATIN SMALL LETTER A)は「A」(U+0041 LATIN CAPITAL LETTER A)だけではなく、「à」(U+00E0 LATIN SMALL LETTER A WITH GRAVE)や「Á」(U+00C1 LATIN CAPITAL LETTER A WITH ACUTE)とも同一視されます。
この変更は非互換な変更です。
上記の違いを実際に比べてみましょう。
1つ前のmroonga 2.10であらかじめ以下のSQLで test_collate テーブルを作成します。
use test;
drop table IF EXISTS test_collate;
create table test_collate (
id int primary key auto_increment,
note text,
val varchar(4),
FULLTEXT INDEX(val)
) engine=mroonga default charset utf8;
次に、サンプルデータを投入します。
use test;
insert into test_collate (val, note) values ('A','LATIN CAPITAL LETTER A');
insert into test_collate (val, note) values ('a','LATIN SMALL LETTER A');
insert into test_collate (val, note) values (_utf8 x'c3a0','LATIN SMALL LETTER A WITH GRAVE');
insert into test_collate (val, note) values (_utf8 x'c381','LATIN CAPITAL LETTER A WITH
ACUTE');
insert into test_collate (val, note) values ('A','全角大文字');
insert into test_collate (val, note) values ('a','全角小文字');
"a"にマッチするものを検索すると「à」(U+00E0 LATIN SMALL LETTER A WITH GRAVE)や「Á」(U+00C1 LATIN CAPITAL LETTER A WITH ACUTE)は検索結果に含まれないことがわかります。
mysql> select * from test_collate where match (val) against ("a");
+----+------------------------+------+
| id | note | val |
+----+------------------------+------+
| 1 | LATIN CAPITAL LETTER A | A |
| 2 | LATIN SMALL LETTER A | a |
| 5 | 全角大文字 | A |
| 6 | 全角小文字 | a |
+----+------------------------+------+
4 rows in set (0.00 sec)
次に、 groonga-normalizer-mysql パッケージをインストールし、mroongaを3.00にアップグレードします。
その後、ALTER TABLEで新規にカラムを追加します。
use test;
ALTER TABLE test_collate ADD val2 varchar(4) COLLATE 'utf8_roman_ci';
ALTER TABLE test_collate ADD FULLTEXT INDEX val2_idx (val2);
ALTER TABLE test_collate ADD val3 varchar(4) COLLATE 'utf8_general_ci';
ALTER TABLE test_collate ADD FULLTEXT INDEX val3_idx (val3);
追加したカラムへサンプルデータを投入します。
use test;
insert into test_collate (val2, note) values ('A','LATIN CAPITAL LETTER A');
insert into test_collate (val2, note) values ('a','LATIN SMALL LETTER A');
insert into test_collate (val2, note) values (_utf8 x'c3a0','LATIN SMALL LETTER A WITH GRAVE');
insert into test_collate (val2, note) values (_utf8 x'c381','LATIN CAPITAL LETTER A WITH ACUTE');
insert into test_collate (val2, note) values ('A','全角大文字');
insert into test_collate (val2, note) values ('a','全角小文字');
insert into test_collate (val3, note) values ('A','LATIN CAPITAL LETTER A');
insert into test_collate (val3, note) values ('a','LATIN SMALL LETTER A');
insert into test_collate (val3, note) values (_utf8 x'c3a0','LATIN SMALL LETTER A WITH GRAVE');
insert into test_collate (val3, note) values (_utf8 x'c381','LATIN CAPITAL LETTER A WITH ACUTE');
insert into test_collate (val3, note) values ('A','全角大文字');
insert into test_collate (val3, note) values ('a','全角小文字');
追加したカラムに対しても"a"でマッチするか確認します。
mysql> select * from test_collate where match(val2) against("a");
+----+------------------------+------+------+------+
| id | note | val | val2 | val3 |
+----+------------------------+------+------+------+
| 7 | LATIN CAPITAL LETTER A | | A | |
| 8 | LATIN SMALL LETTER A | | a | |
| 11 | 全角大文字 | | A | |
| 12 | 全角小文字 | | a | |
+----+------------------------+------+------+------+
4 rows in set (0.00 sec)mysql> select * from test_collate where match(val3) against("a");
+----+-----------------------------------+------+------+------+
| id | note | val | val2 | val3 |
+----+-----------------------------------+------+------+------+
| 13 | LATIN CAPITAL LETTER A | | | A |
| 14 | LATIN SMALL LETTER A | | | a |
| 15 | LATIN SMALL LETTER A WITH GRAVE | | | à |
| 16 | LATIN CAPITAL LETTER A WITH ACUTE | | | Á |
+----+-----------------------------------+------+------+------+
4 rows in set (0.00 sec)
新規追加したカラムに関して、 utf8_roman_ci を指定するとgroongaのnormalizerが使われ(従来通りの挙動)、 utf8_general_ci を指定するとMySQL互換の結果になっていることがわかります。
既存のデータベースへの影響について
新しく作成するテーブル・カラム・インデックスから有効になります。
すでに存在しているカラム・インデックスはこれまで通り、groonga独自のnormalizer(NormalizerAuto)が使われます。
そのため、mroongaを3.00へとアップデートして既存のデータベースを使い続けるとカラム毎に異なるnormalizerを使うことになる点に注意が必要です。
全体で同じnormalizerを使う方法について
新しく作るテーブル・カラム・インデックスのCOLLATIONとして utf8_roman_ci など utf8_general_ci ではないCOLLATIONを指定するとgroongaのnormalizerに統一(従来通りの挙動)できます。
まとめ
mroongaでMySQL互換のCOLLATIONを使う方法を紹介しました。
mroongaに興味を持ったなら、まずはインストールして試してみてください。
ユーザーガイドも用意しています。