1案件に20個のキーワードを設定し、それらを検索したいという要件があるとき、どういうテーブル設計が自然(ベター)ですか?
1. 1テーブルに20個のキーワード項目を用意する。
kanriNumber, keyword1, keyword2, keyword3..., contents
2. 案件テーブルとキーワードテーブルの2つを用意する。
kanriNumber, contents
kanriNumber, keyNumber, keyword
3. その他
他にいい方法があれば教えてください。
テーブルを2つに分けたほうがSQL文はまとまりがよくなると思いますが、
パフォーマンスが悪くなるのでは、と心配しています。
2の際に想定しているSQL文をコメント欄に書きます。
母体データ件数は、どのくらいあるのでしょうか?
まず、「列名 LIKE '%a%'」といった検索条件を使う発想をやめましょう。こういった条件指定をすると、インデクスを定義しても、有効利用されず、母体データ件数に比例して性能劣化します。
せっかくキーワード列を設けるなら、「列名='キーワード'」か、「列名 LIKE 'c%'」といったように
インデクスを有効利用できる検索条件を使えるように設計できませんか?
そうでないなら、キーワードを持った列を作ること自体、意味がありません。
「=」条件やLIKEの前方一致の条件にすれば、キーワード列のインデクスを有効利用できるので、案2の方式を採用しても性能を出せます。
どうしても、「列名 LIKE '%a%'」のような検索条件しか設計できなければ、キーワードを持つ列など作るのはやめて、全文検索などの機能を使うことを検討する必要があるでしょう。
AND条件
SELECT DISTINCT Anken.* FROM Anken INNER JOIN Keyword AS Key1 ON Anken.kanriNumber = Key1.kanriNumber INNER JOIN Keyword AS Key2 ON Anken.kanriNumber = Key2.kanriNumber INNER JOIN Keyword AS Key3 ON Anken.kanriNumber = Key3.kanriNumber WHERE (Key1.keyword LIKE '%a%') AND (Key2.keyword LIKE '%b%') AND (Key3.keyword LIKE '%c%')
OR条件
SELECT DISTINCT Anken.* FROM Anken INNER JOIN Keyword ON Anken.kanriNumber = Keyword.kanriNumber WHERE (Keyword.keyword LIKE '%a%') OR (Keyword.keyword LIKE '%b%') OR (Keyword.keyword LIKE '%d%')
ありがとうございます。
そうですね、このSQL文のほうがすっきりしていていいですね。
設計レベルでは何かないでしょうか?
ありがとうございます。
> まず、「列名 LIKE '%a%'」といった検索条件を使う発想をやめましょう。
なるほど、性能劣化は問題ですね。ちょっと考え直します。