Что такое эффективный способ запроса к модели сущности-атрибута-значения - PullRequest
1 голос
/ 04 августа 2010

Я работаю с базой данных, настроенной так:

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

Но это не кажется мне невероятно эффективным. Есть ли лучший подход к этому?

Ответы [ 2 ]

1 голос
/ 04 августа 2010

Хотя у EAV есть место, у вас уже есть 3 несколько гарантированных имени атрибута (так как вы ищете его, я предполагаю, что многие атрибуты разделяют эти атрибуты).Пахнет как не кандидат в EAV или возможная комбинация атрибутов, которые могут находиться в их отдельной таблице artistdates (id,artist,start,end), которые могут быть связаны в таблице EAV как E=<whatever>,A=artistdate_id,V=<artistdate_id>, если хотите.

Сила EAV предназначена для тех ситуаций, в которых фактические имеющиеся атрибуты не согласованы и которые обычно запрашиваются только по идентификатору объекта или наличию атрибута (возможно, в сочетании со значением).Как только вы ищете комбинации атрибутов, производительность будет снижаться, и возникает вопрос, должны ли они жить отдельно в структуре EAV или их следует разделить на «традиционную» таблицу на основе строк.

1 голос
/ 04 августа 2010

Для ясности вы можете поместить элементы предложения 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"
;

Вы также можете нормализовать поле, чтобы сэкономить немного места (при условии, что поле не является перечислением)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...