Consider these two tables stored in a MySQL database. The first stores a list of movies and the second stores metadata about each movie. Rather than adding 'category' and 'actor' fields to the movies table, they are stored as key/value pairs in the movie_attributes table, as each movie may have more than one category or actor attributed to it.
movies
id name
-----------
0 hot rod
1 star wars
movie_attributes
id movie_id key value
----------------------------------------
0 0 genre comedy
1 0 genre stupid
2 0 actor andy samberg
3 0 actor harrison ford
4 0 actor chester tam
5 1 genre adventure
6 1 actor harrison ford
What would be the most efficient way to query the movies based on a search criteria that allows the user to select multiple genres and multiple actors? If the user adds more than one category to their search, I would like the results to include movies from both categories (but only those videos that also match the actors selected.)
For example, this pseudo-query:
select * from movies where (genre = 'comedy' OR genre = 'adventure') AND (actor = 'harrison ford')
would return this:
id name
-----------
0 hot rod
1 star wars
Currently, my solution uses a mess of subqueries and it's awfuly slow, as my database contains more than two attribute key types per movie (genres, actors, actresses, tags, etc..) and it's terribly slow. Here's the real query that's equivalent to the example pseudo-query above:
select * from movies
WHERE (select count(*) from movie_attributes
WHERE key='genre'
AND (value='comedy'
OR value='adventure'))>0
AND
(select count(*) from movie_attributes
WHERE key='actor'
AND (value='harrison ford'))>0
Is there a more efficient way to achieve the same results using joins or some other SQL voodoo magic I'm unfamiliar with? Thanks!