Contents
    1. 3) MySQLのインストール
  1. MySQLバインディング
  2. Senna MySQLバインディングとは?
  3. 使い方
  4. 機能と制限事項
  5. インストール手順詳細
  6. 独自拡張機能
    1. CREATE TABLE / CREATE INDEX 句の拡張
      1. インデックスタイプの指定
        1. 単語(mecab)インデックスを作成する場合
        2. NGRAMインデックスを作成する場合
        3. DELIMITEDインデックスを作成する場合
        4. MySQLの素のfulltext indexを作成する(sennaインデックスを使用しない)場合
        5. 正規化機能の使用/不使用
        6. INITIAL_N_SEGMENTS指定
    2. SHOW INDEX 句の拡張
    3. SHOW TABLE STATUS 句の拡張
    4. 2ind patch(2インデックス同時使用機能)
      1. 2ind patchとは
      2. 2ind patchのインストール(ソースからインストールする場合)
      3. 2ind-patchの使い方
      4. 2ind-patchの注意点
    5. snippet UDF
      1. snippet UDFのインストール
      2. snippet UDFの使い方
    6. skipmode-patch
      1. skipmode patchのインストール

旧ブラジル版MySQLバインディングのドキュメント置き場

この内容は、古いバージョンのMySQLバインディングの文書です

3) MySQLのインストール

MySQLバインディングを利用する場合のみ、MySQLをインストールする必要があります。 詳しくは、MySQL バインディングをご覧ください。

MySQLは4.0系, 4.1系, 5.0系に対応しています。 sennaを組み込むためにpatchをあてる必要がありますので、 sourceからビルドしなければなりません。

http://dev.mysql.com/downloads/ から必要なsourceコードをダウンロードし、 手元に展開した上で対応するsennaのパッチをあてます。

(patch versionとMySQLのversionが大きく違う場合は、patch -Fで大きめの数値を与えるとうまく通るかも知れません)

> cd mysql-4.0.27
> patch -p1 < ../senna/bindings/mysql/mysql-4.0.27.senna.diff

2ind-patchを併用する場合には、上記コマンドの実行後、

> patch -p1 < ../senna/bindings/mysql/mysql-4.0.27.senna.2ind.diff

と実行ください。

autotoolsを用いて、configureを再作成します。 bison 1.75, autoconf 2.59, automake 1.8(aclocal 1.8), libtool 1.4以上が必要です

> libtoolize -c -f
> aclocal-1.9
> autoheader
> automake-1.9 -c -a -i
> autoconf

sql/sql_yacc.yyをtouchします。

> touch sql/sql_yacc.yy

configureで環境設定を行い、 makeを実行してください。 configureには、「--with-senna」オプションを指定してください。

> ./configure --with-charset=utf8 --with-extra-charsets=ujis,sjis --with-named-curses-libs=/lib/libncurses.so.5 --with-senna
> make
> sudo make install

環境によっては「--with-named-curses-libs=/lib/libncurses.so.5」は必要なかったりします。 makeの途中でlibncurses.so.x.x関係のエラーが出た場合には、

# ldconfig -p | grep libncurses

としてlibncursesを探してください。

LinuxThreadsに対応していない環境では、「--with-named-thread-libs="-lpthread"」が必要となることがあります。

    • with-charsetと--with-extra-charsetsのいずれかに、

MeCabで指定した文字コードに対応する utf8,sjis,ujis(注意:eucではありません!)のいずれかの値が 入っていなければなりません。

MySQLのconfigureオプションについての説明 ( http://dev.mysql.com/doc/refman/4.1/ja/configure-options.html ) も参考にして、 なるべく性能が高いMySQLをmakeしてください。

configureオプションの実例はMySQLのconfigureオプションにあります。


コンフィグファイルを配置します。 ここではmy-medium.cnfをコピーしていますが、 データベースの規模に合わせて、 my-huge.cnfなどの他のコンフィグファイルをコピーしてください。

> sudo cp -p ./support-files/my-medium.cnf /etc/my.cnf

データベースを初期化します。

> sudo ./scripts/mysql_install_db

データベースの格納パス以下について、所有者とグループを変更します。

> sudo chown -R mysql:mysql /usr/local/var

mysql起動スクリプトを用いて、mysqlを起動します。

> chmod +x ./support-files/mysql.server
> sudo ./support-files/mysql.server start

mysqladminを使って、mysql serverが起動していることを確認します。

> mysqladmin version

mysql起動スクリプトが自動起動されるように配置します。

> sudo cp ./support-files/mysql.server /etc/init.d/mysql

MySQLバインディング

Senna MySQLバインディングとは?

MySQLは、バージョン3.23.23以降、FULLTEXTインデックスをサポートしており、 VARCHAR, TEXT型のフィールドに対して全文検索を実行することができますが、 1) 日本語のサポートが不完全、2) フレーズ検索が遅い、3) 更新が遅い、 といった問題点があります。

Senna MySQLバインディングは、MySQLのFULLTEXTインデックスを置き換える形で Sennaライブラリを組み込むもので、上記の問題点を全て解消し、 高速・高精度なSennaの特徴をMySQLからフルに使用可能にします。

また全文検索に関する構文は、MySQLのオリジナルのFULLTEXTインデックス向けの 構文がそのまま使用可能なため、スムーズに適用することができます。

使い方

Senna MySQLバインディングを使用するためには、Senna組み込み版のMySQLをインストールします。 Senna組み込み版のMySQLをインストールするには二つの方法があります。

  1. Senna MySQLバインディングを組み込み済みのバイナリパッケージをインストールする
  2. MySQLのソースにSenna MySQLバインディングパッチを当ててコンパイル・インストールする

インストール後、MySQLサーバを起動すれば、 http://dev.mysql.com/doc/refman/4.1/ja/fulltext-search.html に書かれている方法でSennaのfulltext indexを構築し、 全文検索機能を使用することができるようになります。

機能と制限事項

  • 4.0系, 4.1系, 5.0系, 5.1系の各最新バージョンのMySQLで使用できます。
  • IN BOOLEAN MODEとデフォルト(NLQ MODE)の全文検索(MATCH AGAINST)クエリをサポートします。
  • IN BOOLEAN MODEでは、+, -, <, >, (, ), ~, *, " の全演算子が使用できます。
  • EUC, SJIS, UTF8の3種類のエンコーディングを使用できます。
  • 文字正規化機能を使用できます。UTF8の場合はNFKC正規化をサポートします。
  • 関連文書検索機能が使用できます。
  • 近傍(近接)検索機能が使用できます。
  • MyISAM と MERGEの2種類のストレージエンジンをサポートします。(MERGEは4.0.27のみ)
  • スニペット機能が使用できます。
  • 単語インデックス(mecab使用), NGRAMインデックス, 空白区切りインデックスの3種類が選択できます。
  • fulltextインデックスと他のインデックスを組み合わせて検索処理を高速化する機能があります(2ind patch)
  • ヒット件数取得とLIMIT指定検索を高速化する機能があります(skipmode patch) (4.0.27のみ)

インストール手順詳細

インストール方法を参照下さい。

独自拡張機能

Senna MySQLバインディングでは、より実用的な全文検索アプリケーションで MySQLを使用できるようにいくつかの拡張機能を加えています。 (拡張機能を提供してくださったGREEの小泉さん、iYappoの大沢さんに深く感謝します)

CREATE TABLE / CREATE INDEX 句の拡張

生成する Senna の各種パラメータを指定できます。

インデックスタイプの指定

単語インデックス, NGRAMインデックス, DELIMITEDインデックスの3種のいずれかを選択できます。

単語(mecab)インデックスを作成する場合

インデックスタイプを指定しなければ単語インデックスが使用されます。

(例)

  CREATE TABLE test (
    id INTEGER AUTO_INCREMENT,
    PRIMARY KEY (id),
    text TEXT NOT NULL,
    FULLTEXT INDEX (text)
  );
NGRAMインデックスを作成する場合

USING NGRAMを指定します。

(例)

  CREATE TABLE test (
    id INTEGER AUTO_INCREMENT,
    PRIMARY KEY (id),
    text TEXT NOT NULL,
    FULLTEXT INDEX USING NGRAM (text)
  );
DELIMITEDインデックスを作成する場合

USING DELIMITEDを指定すると、空白で区切られた文字列単位でインデックスを作成します。

(例)

  CREATE TABLE test (
    id INTEGER AUTO_INCREMENT,
    PRIMARY KEY (id),
    text TEXT NOT NULL,
    FULLTEXT INDEX USING DELIMITED (text)
  );
MySQLの素のfulltext indexを作成する(sennaインデックスを使用しない)場合

USING NO SENNAを指定します。

(例)

  CREATE TABLE test (
    id INTEGER AUTO_INCREMENT,
    PRIMARY KEY (id),
    text TEXT NOT NULL,
    FULLTEXT INDEX USING NO SENNA (text)
  );
正規化機能の使用/不使用

デフォルトでは正規化機能が有効になります。 無効化するためには、USING NO NORMALIZEを指定します。

(例) 正規化なしでNGRAMインデックスを作成する場合

  CREATE TABLE test (
    id INTEGER AUTO_INCREMENT,
    PRIMARY KEY (id),
    text TEXT NOT NULL,
    FULLTEXT INDEX USING SENNA, NO NORMALIZE, NGRAM (text)
  );
INITIAL_N_SEGMENTS指定

USING 数値を指定することによって、INITIAL_N_SEGMENTS (インデックスバッファ領域の初期値)をインデックス作成時に設定できます。

(例) INITIAL_N_SEGMENTS=2048でインデックスを作成する場合

  CREATE TABLE test (
    id INTEGER AUTO_INCREMENT,
    PRIMARY KEY (id),
    text TEXT NOT NULL,
    FULLTEXT INDEX USING SENNA, 2048 (text)
  );

SHOW INDEX 句の拡張

CREATE TABLE / CREATE INDEX の拡張に伴い SHOW INDEX 句も拡張して、使用しているインデックスの種類を調べることができるようになりました。

 mysql> SHOW INDEX FROM test;
 +-------+------------+----------+- ... -+--------+------+--------------------------------+---------+
 | Table | Non_unique | Key_name |       | Packed | Null | Index_type                     | Comment |
 +-------+------------+----------+- ... -+--------+------+--------------------------------+---------+
 | test  |          0 | PRIMARY  |       | NULL   |      | BTREE                          |         |
 | test  |          1 | text     |       | NULL   | YES  | FULLTEXT,SENNA,NORMALIZE,NGRAM |         |
 +-------+------------+----------+--... -+--------+------+--------------------------------+---------+ 
 2 rows in set (0.04 sec)

SHOW TABLE STATUS 句の拡張

SHOW TABLE STATUS 句 によって、あるテーブルで使われている Senna の転置テーブルや語彙テーブルのレコード数の合計や、インデックスファイルのサイズを知ることができるようになります。複数の全文検索インデックスがあったときにはあまり意味がありませんが...。

 +-------+--------+ ... -------+----------------+----------------+--------------------+---------+
 | Name  | Type   | ... k_time | Create_options | Senna_key_size | Senna_lexicon_size | Comment | 
 +-------+--------+ ... -------+----------------+----------------+--------------------+---------+
 | test1 | MyISAM | ...        |                |              0 |                  0 |         |
 | test2 | MyISAM | ...        |                |              0 |                  0 |         |
 | test3 | MyISAM | ...        |                |              0 |                  0 |         |
 | test4 | MyISAM | ...        |                |              0 |                  0 |         |
 | test5 | MyISAM | ...        |                |              0 |                  0 |         |
 +-------+--------+ ... -------+----------------+----------------+--------------------+---------+

次のカラムが追加されています。

  • Senna_keys_size

シンボル表 (.SEN) のレコード数の合計を示します。

  • Senna_keys_file_size

シンボル表 (.SEN) のファイルサイズの合計を示します。

  • Senna_lexicon_size

語彙テーブル (.SEN.I) のレコード数の合計を示します。

  • Senna_lexicon_file_size

語彙テーブル (.SEN.I) のファイルサイズの合計を示します。

  • Senna_inv_seg_size

転置テーブルのバッファ (.SEN.i) のファイルサイズを示します。

  • Senna_inv_chunk_size

転置テーブル (.SEN.i.c) のファイルサイズを示します。

2ind patch(2インデックス同時使用機能)

2ind patchとは

MySQLでクエリを実行する際には、 1つのテーブルに対して1つのインデックスしか利用できません。

通常のクエリの場合は、 複数のカラムにまたがったインデックスを用意することによって、 現実的にこの制限を回避することができます。

しかし、全文検索用のインデックスを用いた場合、 他のインデックスが利用できないため、 以下のような問題が生じます。

1. limit指定で出力を制限しても応答が遅い問題

  select columns from table where match(a) against(b) limit 1000, 10

のように、オフセットに大きな値を指定するとテーブルスキャンが発生し、 応答が遅くなります。

2. count(*)等で件数を取得するだけでも応答が遅い問題

  select count(*) from table where match(a) against(b);

のように件数を取得するだけでもテーブルスキャンが発生し、 応答が遅くなります。

3. 全文検索以外の条件で絞り込む処理が遅い問題

  select columns from table where match(a) against(b) and c like 'hoge%';

のように、全文検索以外に他のカラムに関する条件を指定した場合、 そのカラムにインデックスが張られていてもテーブルスキャンが発生し、 応答が遅くなります。

4. 全文検索以外の条件でソートする処理が遅い問題

  select columns from table where match(a) against(b) order by c;

のように、ソート条件を指定した場合、そのカラムにインデックスが 張られていてもテーブルスキャンが発生し、応答が遅くなります。。

このような問題を解決するために、 MySQLが全文検索用のインデックスと通常のインデックスの両方を併用できるようにする2ind-patchパッチが使用できます。

2ind patchのインストール(ソースからインストールする場合)

MySQLソースに、mysql-x.x.x.senna.diff を当てたあと、

patch -p1 < {senna-package}/bindings/mysql/mysql-x.x.x.senna.2ind.diff

のように実行して、2ind patchを当てます。その他の手順はインストール方法の通りです。

2ind-patchの使い方

  • 1. 2.のパタンについては、特に意識することなく、通常通りにSQLを発行するだけで2ind-patchの効果が得られます。
  • 3. 4.のパタンについては、絞り込みやソート時に使用したいインデックスを以下のように明示的に指定する必要があります。
  select columns from table force index(c) where match(a) against(b) and c like 'hoge%';
  select columns from table force index(c) where match(a) against(b) order by c;

(主キーであれば force index(PRIMARY) のように指定します)

2ind-patchの注意点

  • 前述の4つのクエリパタン以外では効果が得られるとは限りません。全文検索条件で大量のレコードがヒットすることによって発生するディスクI/Oが性能阻害要因である場合にのみ効果が期待できます。
  • 2ind-patchはMySQLがもともと備えているインデックスを利用します。高い検索パフォーマンスを出すためには、key_buffer_sizeなど、もともとのMySQLのインデックスに対するパラメータを調整する必要があります。

snippet UDF

検索結果を表示する際に、文書中のキーワードの周辺のみを表示したい場合があります。 このキーワードの周辺のテキストを、snippetまたはKWIC(KeyWord In Context)と呼びます。 この機能を実現するのが、snippet UDFです。

snippet UDFのインストール

UDFのディレクトリに移動

> cd {senna-package}/bindings/mysql/udf/

Subversionからソースを取得した場合のみ、autogen.shの実行

> ./autogen.sh

configure

> ./configure --prefix=/usr

makeします。

> make

installします。

> sudo make install

MySQLにUDFを組み込みます。 ちなみに、make loadでは「mysql -u root -p」コマンドを呼び出してUDFを登録しています。 MySQLのrootユーザのパスワードを入力ください。

> make load

snippet UDFの使い方

snippet UDFは大変引数の多いMySQLの関数です。

SELECT snippet(文書, snippetの長さの最大バイト数, snippetの最大個数, 文書の文字コード, 
  htmlエンコーディングの有無, snippetの開始タグ, snippetの終了タグ, 
  単語1, 単語1の前につけられるタグ, 単語1の後につけられるタグ, 
  単語2, 単語2の前につけられるタグ, 単語2の後につけられるタグ, ...);

文字コードは、sjis, ujis, utf8, defaultのいずれかを指定ください。 htmlエンコーディングの有無は、0か1を指定ください。 1の場合は文書中の<,>,&,"をそれぞれ&lt;,&gt;,&amp;,&quot;に変換して出力します。

例は以下のとおりです。

SELECT snippet(body, 120, 3, 'ujis', 
  1, '...', '...<br>\n', 
  '検索', '<span class="word1">', '</span>', 
  '実験', '<span class="word2">', '</span>'
)
FROM contents
WHERE MATCH(body) AGAINST('*D+ 検索 実験' IN BOOLEAN MODE)
LIMIT 0,10;

skipmode-patch

skipmode-patchは、検索クエリーにおいてヒット件数取得とLIMIT指定検索を高速化する機能です。 MySQL-4.0.27でのみ使用することができます。

skipmode patchのインストール

MySQLソースに、mysql-x.x.x.senna.diff を当てたあと、

patch -p1 < {senna-package}/bindings/mysql/mysql-x.x.x.senna.2ind.diff
patch -p1 < {senna-package}/bindings/mysql/mysql-x.x.x.senna.2ind.skipmode.diff

のように実行して、2ind patchとskipmode patchの両方を当てます。 その他の手順はインストール方法の通りです。

Last modified: 2007-03-19