许多类型的系统使用标签来组织内容,包括博客和StackOverflow。假设我正在制作一个电影网站,希望用户能够标记电影,以及使用标签组合搜索电影。
这是一个示例数据库结构:
movies:
id, name
movie_tag_options (used to provide users with list of available tag options):
id, name
movie_tags:
id, m_id, mto_id
假设有一部名为“变形金刚9 - 爆炸”的电影,它的标签是“动作”,“PG-13”和“可怕的电影”。我希望用户能够通过搜索“动作,PG-13,可怕的电影”找到这部电影。
我将在PHP中爆炸标签字符串以获取标签数组:
action
PG-13
terrible movie
所以我的问题是,如何使用标签名称来查找带有这些标签的电影?电影也可以包含其他标签,但只有在搜索中包含所有标签时才会返回。
我能想到的唯一解决方案是对标记名称进行非规范化并将其存储在movie_tags
以及movie_tag_options
中(即向name
添加重复的movie_tags
列}),然后在PHP中构建一个查询,为每个标记生成JOIN
语句。像这样:
SELECT id, name FROM movies
JOIN movie_tags mt0 ON mt0.name = "action"
JOIN movie_tags mt1 ON mt1.name = "PG-13"
JOIN movie_tags mt2 ON mt2.name = "terrible movie"
JOIN
行将通过PHP生成并插入到查询中。
这种方法的缺点是将标签名称存储在两个表中而不是一个表中。
有更好的方法吗?
答案 0 :(得分:2)
或者您可以使用
select a.name, count(c.id) c
from movies a
join movie_tags b on a.id = b.m_id
join movie_tag_options c on b.mto_id = c.id
where c.name in ('action', 'PG-13', 'terrible movie')
group by a.id
having c = 3;