MySQL データベースに書籍のテーブルがあり、「タイトル」フィールドでキーワード (ユーザーが検索フィールドに入力) を検索したいとします。PHPでこれを行う最良の方法は何ですか? MySQLLIKE
コマンドは最も効率的な検索方法ですか?
6 に答える
はい、通常、最も効率的な方法はデータベースを検索することです。これを行うには、次の 3 つの選択肢があります。
- LIKE、ILIKEで正確な部分文字列に一致
- POSIX 正規表現に一致するRLIKE
- 自然言語処理を目的とした別の 3 種類の検索に一致するFULLTEXTインデックス
したがって、何が最適かを判断するために実際に何を検索するかによって異なります。本のタイトルについては、部分文字列が完全に一致する LIKE 検索を提供します。これは、探している本がわかっている場合に役立ちます。また、単語やフレーズに似たタイトルを見つけるのに役立つ FULLTEXT 検索も提供します。もちろん、インターフェイス上で異なる名前を付けます。おそらく、部分文字列検索では正確な名前を付け、全文検索では同じような名前を付けます。
フルテキストの例: http://www.onlamp.com/pub/a/onlamp/2003/06/26/fulltext.html
ここでは、いくつかのキーワードを分解して、それらのキーワードで列をフィルタリングするための句を作成する簡単な方法を、AND または OR で結合します。
$terms=explode(',', $_GET['keywords']);
$clauses=array();
foreach($terms as $term)
{
//remove any chars you don't want to be searching - adjust to suit
//your requirements
$clean=trim(preg_replace('/[^a-z0-9]/i', '', $term));
if (!empty($clean))
{
//note use of mysql_escape_string - while not strictly required
//in this example due to the preg_replace earlier, it's good
//practice to sanitize your DB inputs in case you modify that
//filter...
$clauses[]="title like '%".mysql_escape_string($clean)."%'";
}
}
if (!empty($clauses))
{
//concatenate the clauses together with AND or OR, depending on
//your requirements
$filter='('.implode(' AND ', $clauses).')';
//build and execute the required SQL
$sql="select * from foo where $filter";
}
else
{
//no search term, do something else, find everything?
}
sphinxの使用を検討してください。これは、mysql データベースを直接使用できるオープン ソースの全文エンジンです。LIKE ステートメントを手作業でコーディングするよりもはるかにスケーラブルで柔軟です (そして、SQL インジェクションの影響をはるかに受けにくくなります)。
Paul Dixon のコード例は、LIKE ベースのアプローチの主なアイデアをうまく伝えています。
このユーザビリティのアイデアを追加します: インターフェイスに (AND | OR) ラジオ ボタン セットを提供します。デフォルトは AND です。ユーザーのクエリの結果がゼロ (0) 一致で、少なくとも 2 つの単語が含まれている場合は、オプションで応答します。趣旨:
"申し訳ありませんが、検索フレーズに一致するものが見つかりませんでした。検索を拡張して、フレーズ内の任意の単語に一致させますか?
これを表現するより良い方法があるかもしれませんが、基本的な考え方は、ユーザーが AND と OR のブール論理について考える必要なく、ユーザーを別のクエリ (成功する可能性がある) に導くことです。
言葉ならLikeが一番効率的だと思います。すでに述べたように、複数の単語は爆発機能で分割できます。その後、ループして、データベースを個別に検索するために使用できます。同じ結果が 2 回返された場合は、値を配列に読み込むことで確認できます。配列に既に存在する場合は、無視します。次に、カウント機能を使用すると、ループで印刷中にどこで停止するかがわかります。並べ替えは、similar_text 関数で行うことができます。パーセンテージは、配列のソートに使用されます。それは最高です。
また、mysqlマニュアルでsoundex関数(soundex、sounds like)を確認することもできますhttp://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_soundex たとえば厳密な場合、これらの一致を返す機能チェック (LIKE または = による) は結果を返しませんでした。