Я работаю с базой данных, настроенной как это:
entity field value
1 start_date June 1, 2010
1 end_date August 30, 2010
1 artist 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";
Но это, кажется мне, не невероятно эффективно. Существует ли лучший подход к этому?
Для ясности вы можете поместить элементы предложения соединения в предложение соединения, но с точки зрения оптимизации запросов это в значительной степени способ сделать это.
Вы могли бы подумать о том, чтобы переписать запрос примерно так:
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"
;
Вы также можете нормализовать поле, чтобы сэкономить немного места (при условии, что это поле не является перечислением)
Хотя у EAV есть свое место, у вас уже есть 3 гарантированных имени атрибута (поскольку вы его ищете, я предполагаю, что многие объекты разделяют эти атрибуты).Пахнет не кандидатом на EAV или возможной комбинацией атрибутов, которые могут быть указаны в отдельной таблице Artistdates (id, artist, start, end)
, которые, возможно, могут быть связаны в таблице EAV как E = <что угодно>, A = artistdate_id, V =
, если хотите.
Возможности EAV предназначены для тех ситуаций, в которых фактические присутствующие атрибуты несовместимы и которые обычно запрашиваются только по идентификатору объекта или наличию атрибута (возможно, в сочетании со значением). Как только вы будете искать комбинации атрибутов, производительность пострадает , и вопрос в том, должны ли они жить отдельно в структуре EAV или их следует разделить в «традиционную» таблицу на основе строк.