我正在使用这样的数据库设置:
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";
但这并没有让我感到非常高效。有更好的方法吗?
答案 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>