我的网站包含视频,它们包含标签,我不知道如何将整个内容存储在数据库中。 我试过这种方式:
Table: Videos
Columns: video_id, title, tagsList
Indexes: video_id
Table: Tag
Columns: video_id, tagTitle
Indexes: video_id, tagTitle
问题是我有超过10万个视频,每个视频大约有10个标签,所以我的Tag表有1M行。因此,如果我想打印所有标签以及每个标签的视频数量,则需要花费不合理的时间。
答案 0 :(得分:2)
首先,我们必须定义问题。所以在这里我看到了两个问题
CREATE TABLE `video_tag` (
`video_id` int not null,
`tag_id` int not null,
`added` datetime not null,
INDEX `main` (`tag_id` asc, `added` asc),
INDEX `video` (`video_id` asc)
);
这里的情况是要有一个好的索引,它将为您提供尽可能快的信息。
关于获取基本信息:
more
按钮或其他内容加载更多标签。获取所有标签并不方便,因为当时并非所有标签都可以被用户/系统读取。a)作为结论,关于你的信息。我会预加载几个标签,然后根据需要获取更多标签。 b)我会创建物化视图。表
CREATE TABLE `mv_movies_tags_counter` (
`video_id` int not null,
`count` int not null,
INDEX `video` (`video_id` asc)
);
并在事件上更新计数器:在电影中添加/删除标签。所以这可以通过mysql trigger https://dev.mysql.com/doc/refman/5.5/en/trigger-syntax.html
自动触发DELIMITER $$
CREATE TRIGGER inc_tags_counter AFTER INSERT ON video_tag
FOR EACH ROW
BEGIN
UPDATE mv_movies_tags_counter SET count = count + 1 WHERE video_id = NEW.video_id;
END $$
DELIMITER ;
DELIMITER $$
CREATE TRIGGER inc_tags_counter AFTER DELETE ON video_tag
FOR EACH ROW
BEGIN
UPDATE mv_movies_tags_counter SET count = count - 1 WHERE video_id = NEW.video_id;
END $$
DELIMITER ;
答案 1 :(得分:1)
改为创建数据透视表。所以你有这样的东西
Table: Videos
Columns: video_id, title, tagsList
Indexes: video_id
Table: Tag
Columns: tag_id, tagTitle
Indexes: tag_id
Table: video_tag
Columns: video_id, tag_id
Indexes: tag_id,video_id
然后使video_tag上的列成为外键并引用每个表上的列
答案 2 :(得分:1)
您可以通过使数据修改速度慢一点来更快地进行查询:) @T alagbe的答案中的好处是,如果连接器表只包含2个ID字段,那么它的内存占用量很低。但我认为这还不够。
我会将该连接器表扩展为您对视频进行排序的字段。例如,如果视频按照添加日期排序,则:
CREATE TABLE `video_tag` (
`video_id` int not null,
`tag_id` int not null,
`added` datetime not null,
INDEX `main` (`tag_id` asc, `added` asc),
INDEX `video` (`video_id` asc)
);
请注意,重要的是复合索引" main"。您甚至可以从此表中删除其他索引。您可以拥有多个这样的表,但每次有人添加或删除视频时,您都必须更新它们。 什么也可以加速这样的情况是稀疏索引。但MySQL(AFAIK)不支持这些。
更新:您还可以考虑的是缓存特定过滤的视频列表。这些可以通过crontab任务每10-30分钟更新一次。