Search code examples
mysqlentity-attribute-value

What is an efficient way to query against an entity-attribute-value model


I'm working with a database set up like this:

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

And I want to query all the entities with artist name "some name" that have started but not ended.

I came up with something like this:

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

But this doesn't strike me as being incredibly efficient. Is there a better approach to this?


Solution

  • For clarity you can put the join clause items in the join clause, but in terms of query optimisation that is pretty much the way to do it.

    You could consider rewriting the query to something like this though:

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

    You could also normalize the field to save a little space (assuming that field is not an enum)