1

私は次のように設定されたデータベースを使用しています。

  entity field       value
   1      start_date  June 1, 2010
   1      end_date    August 30, 2010
   1      artist      some name

そして、開始したが終了していないアーティスト名「somename」のすべてのエンティティにクエリを実行したいと思います。

私はこのようなものを思いついた:

SELECT start.entity
FROM field_values AS `start`
  INNER JOIN field_values AS `end`
  INNER JOIN field_values AS `artist`
WHERE 
  (start.field = 'start_date' AND end.field = 'end_date' AND artist.field='artist')  AND 
  (STR_TO_DATE(start.value, '%M %d, %Y') < NOW() AND 
   STR_TO_DATE(end.value, '%M %d, %Y') > NOW())  AND 
  artist.value="some artist";

しかし、これは信じられないほど効率的であると私は思いません。これに対するより良いアプローチはありますか?

4

2 に答える 2

1

わかりやすくするために、結合句の項目を結合句に入れることができますが、クエリの最適化に関しては、これがほとんどの方法です。

ただし、クエリを次のように書き直すことを検討できます。

SELECT start.entity
FROM entity
  JOIN field_values AS start
    ON entity.id = start.entity AND start.field = 'start_date'
  INNER JOIN field_values AS end
    ON entity.id = end.entity AND end.field = 'end_date'
  INNER JOIN field_values AS artist
    ON entity.id = artist.entity AND artist.field = 'artist'
WHERE STR_TO_DATE(start.value, '%M %d, %Y') < NOW()
  AND STR_TO_DATE(end.value, '%M %d, %Y') > NOW()
  AND artist.value="some artist"
;

フィールドを正規化して少しスペースを節約することもできます(そのフィールドが列挙型ではないと仮定します)

于 2010-08-03T23:46:32.213 に答える
1

EAVにはその場所がありますが、すでに3つのある程度保証された属性名があります(検索しているときに、多くのエンティティがそれらの属性を共有していると思います)。EAVの候補ではない、または別のテーブルに含まれる可能性のある属性の組み合わせのようなにおいがします。これは、必要に応じartistdates (id,artist,start,end)てEAVテーブルにリンクする可能性がありE=<whatever>,A=artistdate_id,V=<artistdate_id>ます。

EAVの威力は、存在する実際の属性に一貫性がなく、通常はエンティティIDのみ、または属性の存在(場合によっては値との組み合わせ)によって照会される状況にあります。属性の組み合わせを探しているとすぐにパフォーマンス低下し、問題はそれらをEAV構造で別々に配置するか、「従来の」行ベースのテーブルに分割するかです。

于 2010-08-03T23:58:59.473 に答える