这个问题与this one类似,但有所不同:我有八种不同类型的标签。
这样的事情:
videos [id, title]
tags1 [id, tag]
tags2 [id, tag]
tags3 [id, tag]
tags4 [id, tag]
tags5 [id, tag]
tags6 [id, tag]
tags7 [id, tag]
tags8 [id, tag]
video_tags1 [vid_id, tag_id]
video_tags2 [vid_id, tag_id]
video_tags3 [vid_id, tag_id]
video_tags4 [vid_id, tag_id]
video_tags5 [vid_id, tag_id]
video_tags6 [vid_id, tag_id]
video_tags7 [vid_id, tag_id]
video_tags8 [vid_id, tag_id]
鉴于单个video.id,我想根据哪些视频共享最多的相关视频。我发现很难找到一种方法来做到这一点,更不用说一种不会让服务器瘫痪的方法。
答案 0 :(得分:2)
如果您可以更改数据库模型,那么这些提案可能适合您。
以这种方式重新定义表格:
videos [id, title]
tags [id, tag_type,tag]
videos_tags [vid_id, tag_id]
你也可以添加一个tag_type表(它有8行,每个yourtag类型一个),以提高一致性。
然后这个查询(它可能有一些语法错误,但我的意图是你明白了)会给你视频ID和匹配标签的数量与提供的:
select
videos.id, count(videos.id) as nEqualTags
from
videos videos inner join video_tags vtags on (vtags.vid_id=videos.id )
where
vtags.tag_id in (select tag_id from videos_tags where vt.id = ?)
group by
videos.id
order by
nEqualTags desc
如果nEqualTags
低于特定值,您可以添加更多逻辑以减少结果。
(并且还考虑添加一些索引以获得更好的性能)。
希望有所帮助
答案 1 :(得分:1)
我认为在规范化表上工作总是一个好主意,在这种情况下,这个UNION查询可以提供帮助:
(select 1 as tab, vid_id, tag_id from video_tags1
union select 2 as tab, vid_id, tag_id from video_tags2
union select 3 as tab, vid_id, tag_id from video_tags3
...)
现在你必须使用这样的查询:
SELECT
tags_1.vid_id, count(*) as common_tags
FROM
(big union above) video_tags
INNER JOIN
(big union above) video_tags_1
ON video_tags.tab = video_tags_1.tab
AND video_tags.tags_id = video_tags_1.tags_id
AND video_tags.vid_id = 1
AND video_tags_1.vid_id <> 1
GROUP BY video_tags_1.vid_id
ORDER BY common_tags DESC
这将按照它们共有的标签数量返回所有按DESC订购的记录。这可能是如何进行的想法。您应该再添加一个JOIN以获取视频的标题。 如果你还需要获得它们共有的标签的描述......那么它是可能的,但我认为它会使查询复杂化很多!
您确定无法更改数据库模型,只使用表格标记和视频标记吗?它会让事情变得容易多了!