Kouhei Sutou
kou****@clear*****
2015年 6月 26日 (金) 21:57:44 JST
須藤です。 In <CA+Tq-Ro9VuhcHkbSn8-OU_5bcv2FLTmsRe3nfm9P_OEELJ****@mail*****> "[groonga-dev,03310] Re: テーブルの_keyとフラグについて" on Fri, 26 Jun 2015 20:55:00 +0900, Hiroyuki Sato <hiroy****@gmail*****> wrote: >> * 1,2: このような理解で良いでしょうか? >> 1, テーブルのキー >> (1) 一意である >> 同じキーのエントリを複数件、一つのテーブルに登録することはできない。 はい、その通りです。 >> 2, データ用のキーのフラグ >> (1) キーを使って他のテーブルを検索しない場合: TABLE_NO_KEY はい、その通りです。 あとは、できるだけサイズを小さくしたい、速くしたい、ただし、 いろいろある制約は我慢できるという場合に選びます。 >> (2) キーを使って他のテーブルを完全一致でのみ検索する場合: TABLE_HASH_KEY はい、その通りです。 あとは、↓よりも速度が欲しいときに選びます。が、全文検索が入 ったり、多くのレコード・カラムの出力処理が入ると、全体からみ てTABLE_HASH_KEYと↓の時間の差はそんなに気にならなくなるので、 気にする場合は少ないです。 >> (3) キーを使って他のテーブルを全文検索で使う場合: TABLE_PAT_KEY または TABLE_DAT_KEY そんなに間違っていないんですが、ほとんどはTABLE_PAT_KEYです。 TABLE_DAT_KEYはサイズが大きくなりやすい(うえにTABLE_PAT_KEY はサイズがすごく小さくなる)ので、全文検索用のトークンが多く なる場合(だいたいそう)はTABLE_PAT_KEYです。 では、TABLE_DAT_KEYはどういうときに使うかというと、トークン 数に上限があって、トークンの前方一致検索もしたいというような ケースです。(前方一致検索が必要ないならTABLE_HASH_KEYでよ い。) たとえば、タグ検索やWikiのタイトル検索で、タグやタイトルで 「Groonga/テーブル」みたいに階層構造をつけている場合です。 また、テーブルについて書いてあるドキュメントも参考になると思 います。 http://groonga.org/ja/docs/reference/tables.html >> 3, インデックステーブルのキーのフラグ >> (1) _keyにはどのような値が入るのか? >> https://gist.github.com/hiroyuki-sato/8f3e399474ff7cb20ab8 これは、「一つのエントリに複数のIDを格納するような場合」の方 がイメージとしては近くて、こっちの [単語, [_id, 単語の出現位置]] の「単語」部分が_keyになって、こうなります。 _id _key title_idx 1 Haskell [[1,0]] 2 Groonga [[2,0]] 3 Erlang [[3,3]] 4 Go [[4,0]] 5 Scala [[5,6]] 6 入門 [[1,7],[2,7],[4,4]] 7 できる [[3,0],[5,2]] 8 言語 [[4,2]] 9 三日 [[5,0]] 10 で [[5,2]] なので、 > https://gist.github.com/hiroyuki-sato/276fa18be508a731faed の「lexcon (lx: lexicon id)」の表のところまではあっているん ですが、「title_idxの内容は、「どのレコード(bXX)」の「何番目 の文字」かを指定する。」の表は違うんです。 _id title_idx 対応する単語 l6 b1,7 入門 l7 b2,7 入門 l8 b4,4 入門 というように_idが別々には「振られません」。 _id title_idx 対応する単語(←が_key) l6 [[b1,7],[b2,7],[b4,4]] 入門 というように、同じ_id(= 同じ_key)のところに全部入っていま す。 ベクターカラムのところも、↓と書いているので、もしかしたらイ メージが違うかもしれません。(データとしてはあっています。) _id title b1 Haskell入門 b1 Leraning Haskell ベクターカラムのときは同じ_idに対して複数の格納場所(複数の 列)がある、みたいにイメージしているのかと思うんですが、 _id title b1 [Haskell入門, Leraning Haskell] というように、列は1つでベクターカラムの中に複数の格納場所が あるというイメージで考えてください。で、インデックスカラムも 後者と同じように、列は1つ(_id(= _key)は1つ)で、カラムの 中に複数の出現位置を格納しているのです。 > 念のため確認をしたいのですが > インデックスのテーブルのフラグは、TABLE_NO_KEYは指定せず、TABLE_HASH_KEY, TABLE_PAT_KEY, TABLE_DAT_KEY > のどれかを指定するという理解でよいのでしょうか? はい、その通りです。 他の全文検索エンジンは語彙表を外に出していなくて(ユーザーは しなくていい・指定できない)、トークナイザーやノーマライザー は指定できるんですが、Groongaは語彙表から外に出しているので、 検索時の仕組みがわからないと、イメージがつかみにくいかもしれ ません。わかると理にかなっているなぁと思えるのですが。。。 >> 追伸: 今度の読書会ってこの辺が話題でしょうか?参加しようかな.. 次は 4.7.3. カラムインデックスによる関連テーブルをまたぐ検索 http://groonga.org/ja/docs/tutorial/match_columns.html#nested-index-search-among-related-table-by-column-index からで、もう少し進んだところですが、参加者がわかっていないと ころがあれば、ドキュメントに書いていないことでも絵を描きなが ら説明しているので、理解が進むと思います。なので、ぜひ! あ、だいぶ回が進んでいるので途中参加は敷居が高い…と感じてい る人がいるかもしれないので補足しておくと、途中参加の人は歓迎 です。なぜなら、これまで継続して参加している人たちの理解が深 まる機会が増えるからです。 途中参加の人は当然わからないところがでてきます。そのとき、こ れまで参加していた人が説明します。これがポイントで、何回も説 明することで理解が進みます。もし、うまく説明できなかったら理 解できていなかったということなので、他の人が説明します。これ もやはり理解が進みます。 なので、途中参加は歓迎なのです。 Gistに書いていることの補足なんですが、実は、KEY_NORMALIZEは deprecatedになっているのです。代わりに --normalizer NormalizerAutoを指定してください。ドキュメント でもまだKEY_NORMALIZEを使っているところが多く残っているので 直さないといけないんですよねぇ。。。 -- 須藤 功平 <kou****@clear*****> 株式会社クリアコード <http://www.clear-code.com/> Groongaベースの全文検索システムを総合サポート: http://groonga.org/ja/support/ パッチ採用 - プログラミングが楽しい人向けの採用プロセス: http://www.clear-code.com/recruitment/