什么是查询实体 - 属性 - 值模型的有效方法

时间:2010-08-03 23:35:17

标签: mysql entity-attribute-value

我正在使用这样的数据库设置:

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

我想查询所有已经开始但未结束的艺术家名称“some name”的实体。

我想出了类似的东西:

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";

但这并没有让我感到非常高效。有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

为了清楚起见,您可以将join子句项放在join子句中,但就查询优化而言,这几乎就是这样做的。

您可以考虑将查询重写为类似的内容:

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"
;

您还可以规范化字段以节省一点空间(假设该字段不是枚举)

答案 1 :(得分:1)

虽然EAV有它的位置,但你已经有3个有点保证的属性名称(当你搜索它时我假设很多实体共享这些属性)。闻起来像EAV的非候选者,或可能在他们的单独表artistdates (id,artist,start,end)中的可能的属性组合,如果你愿意,可能在EAV表中链接为E=<whatever>,A=artistdate_id,V=<artistdate_id>

EAV的强大功能适用于存在的实际属性不一致的情况,通常仅通过entity-id查询,或者存在属性(可能与值结合)。一旦你正在寻找属性的组合受到影响,问题是它们是否应该在EAV结构中单独存在,或者它们应该被拆分为“传统的”基于行的表。 / p>