2

この質問のさまざまな化身が以前にここで尋ねられましたが、もう一度試してみようと思いました.

データベースのレイアウトがひどいものでした。1 つのエンティティ (ウィジェット) が 2 つのテーブルに分割されました。

CREATE TABLE widgets (widget_id int(10) NOT NULL auto_increment)

CREATE TABLE widget_data ( widget_id int(10), field ENUM('name','size','color','brand'), data TEXT)

これは理想的ではありませんでした。特定の名前、色、ブランドのウィジェットを見つけたい場合は、widget_data テーブルで 3 方向の結合を行う必要がありました。だから私は合理的なテーブルタイプに変換しました:

CREATE TABLE widgets (widget_id int(10) NOT NULL auto_increment, name VARCHAR(32),size INT(3),color VARCHAR(16), brand VARCHAR(32))

これにより、ほとんどのクエリが大幅に改善されます。しかし、それは検索を難しくします。以前は、「%black%」などのウィジェットを検索したい場合は、SELECT * FROM widget_data WHERE data LIKE '%black%'. これにより、黒色のウィジェット、またはブラックウェル産業などによって作成されたウィジェットのすべてのインスタンスが得られます。どのフィールドが一致したかを正確に把握し、それをユーザーに表示することもできます。

新しいテーブル レイアウトを使用して同様の検索を実行するにはどうすればよいですか? もちろんできますWHERE name LIKE '%black%' OR size LIKE '%black%'...が、それは不格好に思えます。また、どのフィールドが一致したかはまだわかりません。照合する列ごとに個別のクエリを実行できます。これにより、すべての一致とその一致方法が得られますが、パフォーマンスが低下します。何か案は?

4

3 に答える 3

4

相反する 2 つの要件があります。すべてのデータが 1 つのフィールドにあるかのように検索したいが、一致した特定のフィールドを特定したい。

あなたのWHERE name LIKE '%black%' OR size LIKE '%black%'... 表現に問題はありません。あなたが定義したように、テーブル上で完全に有効な検索です。コードで結果をチェックして、どれが一致したかを確認してみませんか? 最小限のオーバーヘッドです。

SQL のよりクリーンな構文が必要な場合は、テーブルにビューを作成し、他のフィールドを連結して構成される追加のフィールドを追加できます。

CREATE VIEW extra_widget_data AS
  SELECT (name, size, color, brand,
          CONCAT(name, size, color, brand) as all_fields)
  FROM widget_data;

次に、このフィールドにインデックスを追加する必要があります。これには、より多くのスペース、維持するための CPU 時間が必要です。その価値はないと思います。

于 2009-12-03T16:01:15.000 に答える
3

列の選択に式の一部を含めることができWHEREます。例えば:

SELECT 
  *, 
  (name LIKE '%black%') AS name_matched,
  (size LIKE '%black%') AS size_matched
FROM widget_data 
WHERE name LIKE '%black%' OR size LIKE '%black%'...

次にname_matched、スクリプト側の値を確認します。

パフォーマンスにどのように影響するかはわかりません。本番に入る前に自由にテストしてください

于 2009-12-03T15:30:09.970 に答える
0

おそらく、MySQL の全文検索機能を調べたいと思うでしょう。これにより、varchar 型の複数の列と照合することができます。

http://dev.mysql.com/doc/refman/5.1/en/fulltext-search.html

于 2009-12-03T15:26:45.670 に答える