1

私は人々の名前を持つSQLテーブルで「あいまい」検索をしようとしています:

これはテーブルです:

+----+------------+
| T1 | T2         |
+----+------------+
| 1  | Last,First |
| 2  | Last,First |
| 3  | Last,First |
+----+------------+

クエリが「First Last」の場合でも機能するようにT2、演算子を使用してクエリを実行する select ステートメントを取得したいLIKE

考えられる唯一の方法は、値を分割して連結し、エントリを再度検索することです。これを行うより良い方法はありますか?

4

2 に答える 2

5

last, firstはい、両方をデータベースに入れる可能性がある場合はfirst last、スキーマを適切に設計することをお勧めします。

列の一部を検索したり、操作したりしようとしていることに気付いた場合スキーマはほぼ確実に壊れています。ほぼ確実にパフォーマンスが低下します。

正しい方法は、次のようにテーブルを作成することです。

T1  FirstName  LastName
==  =========  ========
 1  Pax        Diablo
 2  Bob        Smith
 3  George     Jones

これにより、データベース内のすべての名前を分割しようとするよりも、(クエリを実行する前に 1 回) ユーザーが入力した名前をより効率的に分割できます。


データベースが常に を保持している場合last, first、スキーマの変更は実際には必要ない場合があります。

その場合の問題は、単にユーザーが入力した内容を解釈することです。

1 つの可能性は、パフォーマンス キラーですが、like単語ごとに for を実行することです。したがって、ユーザーが を入力した場合pax diablo、結果のクエリは次のようになります。

select T1 from mytable
    where T2 like '%pax%'
      and T2 like '%diablo%'

そうすれば、順序はあまり気にしません。

ただし、遅いクエリが嫌いなので、絶対に必要な場合 (またはデータベースが比較的小さく、そのままになる可能性が高い場合) を除き、遅いクエリは避けようとします。

これらの種類のクエリを高速化するには、次のようなさまざまな方法があります。

  • DBMS が持つ全文検索機能を使用します。
  • 挿入/更新トリガー中に単語を抽出して保存する (および削除トリガー中にそれらを削除する) ことにより、このような機能をエミュレートします。
  • その前のケースだけでなく、現在の列の小文字の値で使用される追加の列も確保します (速度のため)。
  • last, first検索にフォームを使用する必要があることをユーザーに伝えます。
  • %something%可能な限り検索文字列を回避しようとします ( を使用するとsomething%、インデックスは引き続き使用できます)。
  • 私の前述の「名前を2つの列に分割する」方法。
于 2012-08-14T03:01:52.633 に答える
1

これを試すことができます。ただし、名前を分離して、テーブルのスキーマを再構築することをお勧めします。

SELECT *
FROM myTable
WHERE T2 LIKE CONCAT('%', 'First', '%','Last', '%') OR
      T2 LIKE CONCAT('%', 'Last', '%','First', '%')
于 2012-08-14T03:01:32.393 に答える