处理数据库中的标签

时间:2017-01-05 20:42:24

标签: php mysql

我的网站包含视频,它们包含标签,我不知道如何将整个内容存储在数据库中。 我试过这种方式:

Table: Videos
Columns: video_id, title, tagsList
Indexes: video_id

Table: Tag
Columns: video_id, tagTitle
Indexes: video_id, tagTitle

问题是我有超过10万个视频,每个视频大约有10个标签,所以我的Tag表有1M行。因此,如果我想打印所有标签以及每个标签的视频数量,则需要花费不合理的时间。

3 个答案:

答案 0 :(得分:2)

首先,我们必须定义问题。所以在这里我看到了两个问题

  1. 数据库结构
  2. 访问信息的效果
    1. 对于数据库,您实际上可以创建像小猫发布的标签集合的数据透视表。
    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) );

      这里的情况是要有一个好的索引,它将为您提供尽可能快的信息。

      1. 关于获取基本信息:

        • 首先,我会问自己,我可以预加载几个标签,并点击more按钮或其他内容加载更多标签。获取所有标签并不方便,因为当时并非所有标签都可以被用户/系统读取。
        • 如果获得所有标签的性能不可接受,我是否使用可靠的技术来实现这一目标?也许用mongo数据库(https://www.mongodb.com)存储所有标签会为我提供更好的性能
        • 如果我需要计数器,我将使用物化视图,当我可以继续执行由事件触发的所有聚合过程(向电影添加标签等)以存储在此视图中而无需在运行时计算所有这些。
      2. 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分钟更新一次。