• 我在工作中用到的触发器


    公司的主营产品是一款视频拍摄的app,同类竞品有抖音等等,作为一个服务器开发人员,除了开发维护接口,还需要负责公司产品管理平台的开发维护。

    所以,注册用户的管理和用户上传视频的管理,是管理平台中很重要的两个功能。随着注册用户和上传视频的日益增加,运营和产品经理对管理平台提出了新的需求。原有的管理平台使用的查询sql的性能已经很糟糕,多表联查和子查询让sql在注册用户数据量和上传时数据量只有3万时就会锁表,所以,针对用户和视频管理的优化势在必行。

    • 视频管理优化

    视频管理部分,需要展示的数据如图

    视频基本信息表设计如下

    /*表: im_video*/-----------------
    
    /*列信息*/-----------
    
    Field                 Type          Collation           Null    Key     Default  Extra           Privileges                       Comment                                                                                    
    --------------------  ------------  ------------------  ------  ------  -------  --------------  -------------------------------  -------------------------------------------------------------------------------------------
    id                    int(11)       (NULL)              NO      PRI     (NULL)   auto_increment  select,insert,update,references  视频ID                                                                                   
    user_id               int(11)       (NULL)              NO      MUL     (NULL)                   select,insert,update,references  用户ID                                                                                   
    video_type            int(11)       (NULL)              NO              1                        select,insert,update,references  视频类型:1.视频,2.图片                                                             
    video_url             varchar(100)  utf8mb4_general_ci  YES             (NULL)                   select,insert,update,references  视频/图片 S3 URL                                                                       
    video_s3_key          varchar(100)  utf8mb4_general_ci  YES             (NULL)                   select,insert,update,references  视频S3存储对象                                                                       
    thumbnail_url         varchar(100)  utf8mb4_general_ci  YES             (NULL)                   select,insert,update,references  缩略图                                                                                  
    thumbnail_s3_key      varchar(100)  utf8mb4_general_ci  YES             (NULL)                   select,insert,update,references  S3存储对象                                                                             
    video_title           varchar(500)  utf8mb4_general_ci  YES                                      select,insert,update,references  视频描述标题                                                                         
    video_size            bigint(32)    (NULL)              YES             0                        select,insert,update,references  视频Size                                                                                 
    video_resolution      varchar(20)   utf8mb4_general_ci  YES                                      select,insert,update,references  视频分辨率                                                                            
    video_time            int(11)       (NULL)              YES             0                        select,insert,update,references  视频时长(毫秒)                                                                       
    material_id_arr       varchar(100)  utf8mb4_general_ci  YES             0                        select,insert,update,references  使用素材ID集合字符串                                                              
    video_status          int(11)       (NULL)              YES             1                        select,insert,update,references  视频状态:1.正常,0.关闭,2.用户删除                                              
    ctime                 timestamp     (NULL)              YES             (NULL)                   select,insert,update,references  添加时间                                                                               
    etime                 timestamp     (NULL)              YES             (NULL)                   select,insert,update,references  更新时间                                                                               
    tags                  varchar(600)  utf8mb4_unicode_ci  YES                                      select,insert,update,references  用户tag Json集合                                                                       
    video_bitrate         int(11)       (NULL)              YES             0                        select,insert,update,references  视频码率                                                                               
    shoot_screen_type     int(11)       (NULL)              YES             0                        select,insert,update,references  拍摄屏幕模式:1.竖屏, 2.横屏                                                      
    camera_type           int(11)       (NULL)              YES             0                        select,insert,update,references  摄像头情况(1.只有后置摄像头/2.只有前置摄像头/3.前置后置都用了)   
    gif_thumbnail_s3_key  varchar(50)   utf8mb4_general_ci  YES             (NULL)                   select,insert,update,references  上传S3的GIF图地址                                                                    
    
    /*索引信息*/--------------
    
    Table     Non_unique  Key_name       Seq_in_index  Column_name  Collation  Cardinality  Sub_part  Packed  Null    Index_type  Comment  Index_comment  
    --------  ----------  -------------  ------------  -----------  ---------  -----------  --------  ------  ------  ----------  -------  ---------------
    im_video           0  PRIMARY                   1  id           A                 1234    (NULL)  (NULL)          BTREE                               
    im_video           1  video_user_id             1  user_id      A                  154    (NULL)  (NULL)          BTREE  

    可见,视频的点赞数、观看数等计数信息,在视频的基础表里是无法统计的。

    因此为了统计视频被点赞(点赞不可撤销)、被观看,分别设计了点赞表和观看表。视频被点赞或播放,app都会通过接口上报一次数据,服务器记录。

    点赞记录表

    /*表: im_video_like*/----------------------
    
    /*列信息*/-----------
    
    Field     Type       Collation  Null    Key     Default            Extra                        Privileges                       Comment       
    --------  ---------  ---------  ------  ------  -----------------  ---------------------------  -------------------------------  --------------
    id        int(11)    (NULL)     NO      PRI     (NULL)             auto_increment               select,insert,update,references  Id            
    video_id  int(11)    (NULL)     YES     MUL     (NULL)                                          select,insert,update,references  视频ID      
    user_id   int(11)    (NULL)     YES     MUL     (NULL)                                          select,insert,update,references  用户ID      
    ctime     timestamp  (NULL)     YES             CURRENT_TIMESTAMP  on update CURRENT_TIMESTAMP  select,insert,update,references  点赞时间  
    
    /*索引信息*/--------------
    
    Table          Non_unique  Key_name             Seq_in_index  Column_name  Collation  Cardinality  Sub_part  Packed  Null    Index_type  Comment  Index_comment  
    -------------  ----------  -------------------  ------------  -----------  ---------  -----------  --------  ------  ------  ----------  -------  ---------------
    im_video_like           0  PRIMARY                         1  id           A                  535    (NULL)  (NULL)          BTREE                               
    im_video_like           1  video_like_video_id             1  video_id     A                  535    (NULL)  (NULL)  YES     BTREE                               
    im_video_like           1  video_like_user_id              1  user_id      A                   53    (NULL)  (NULL)  YES     BTREE  

    播放记录表

    /*表: im_video_view*/----------------------
    
    /*列信息*/-----------
    
    Field       Type         Collation        Null    Key     Default            Extra                        Privileges                       Comment                                       
    ----------  -----------  ---------------  ------  ------  -----------------  ---------------------------  -------------------------------  ----------------------------------------------
    id          int(11)      (NULL)           NO      PRI     (NULL)             auto_increment               select,insert,update,references  Id                                            
    video_id    int(11)      (NULL)           YES     MUL     (NULL)                                          select,insert,update,references  视频ID                                      
    user_id     int(11)      (NULL)           YES     MUL     (NULL)                                          select,insert,update,references  用户ID                                      
    ip          varchar(50)  utf8_general_ci  YES     MUL                                                     select,insert,update,references  IP(游客)                                    
    view_type   int(11)      (NULL)           YES             1                                               select,insert,update,references  观看类型:1.应用内,2.应用外(分享)  
    view_count  int(11)      (NULL)           YES             0                                               select,insert,update,references  非去重观看数递增                      
    ctime       timestamp    (NULL)           YES             CURRENT_TIMESTAMP  on update CURRENT_TIMESTAMP  select,insert,update,references  创建时间                                  
    
    /*索引信息*/--------------
    
    Table          Non_unique  Key_name             Seq_in_index  Column_name  Collation  Cardinality  Sub_part  Packed  Null    Index_type  Comment  Index_comment  
    -------------  ----------  -------------------  ------------  -----------  ---------  -----------  --------  ------  ------  ----------  -------  ---------------
    im_video_view           0  PRIMARY                         1  id           A                 3067    (NULL)  (NULL)          BTREE                               
    im_video_view           1  video_view_video_id             1  video_id     A                 3067    (NULL)  (NULL)  YES     BTREE                               
    im_video_view           1  video_view_user_id              1  user_id      A                  255    (NULL)  (NULL)  YES     BTREE                               
    im_video_view           1  video_view_ip                   1  ip           A                 1533    (NULL)  (NULL)  YES     BTREE 

    理论上,到这里就可以满足运营的需求了,比如ID为23的视频的点赞数可以通过以下sql实现

    SELECT COUNT(*) FROM `im_video_like` WHERE video_id=23;

    视频的观看数有个重复观看的差别,根据user_id和用户IP区分。如下图,ID为247的视频的观看记录

    SELECT * FROM `im_video_view` WHERE video_id=247;
        id  video_id  user_id  ip             view_type  view_count                ctime  
    ------  --------  -------  -------------  ---------  ----------  ---------------------
         5       247        4  140.207.22.8           1          10    2017-07-03 15:56:37
        21       247       12  192.168.100.1          1           7    2017-07-03 16:50:01
        93       247        8  192.168.100.1          1           1    2017-07-04 10:44:51

    可见,视频247被id=4的用户累计观看了10次,被id=12的用户累计观看了7次。

    如果我们需要的是去重后的观看数,则执行

    SELECT COUNT(*) FROM `im_video_view` WHERE video_id=247;
    count(*)  
    ----------
             3

    如果需要的是非去重的数据,则执行

    SELECT SUM(view_count) FROM `im_video_view` WHERE video_id=247;
    sum(view_count)  
    -----------------
    18               

    对单条数据如上处理没问题,但是当数据量到百万级时,肯定会影响sql查询性能。所以我们又设计了一张表,专门用来统计视频点赞数、视频播放数的信息。

    /*表: im_video_count*/-----------------------
    
    /*列信息*/-----------
    
    Field                    Type     Collation  Null    Key     Default  Extra   Privileges                       Comment                         
    -----------------------  -------  ---------  ------  ------  -------  ------  -------------------------------  --------------------------------
    video_id                 int(11)  (NULL)     NO      PRI     (NULL)           select,insert,update,references  视频ID                        
    user_id                  int(11)  (NULL)     NO              (NULL)           select,insert,update,references  用户ID                        
    like_count               int(11)  (NULL)     YES             0                select,insert,update,references  点赞数                       
    comment_count            int(11)  (NULL)     YES             0                select,insert,update,references  评论数                       
    view_count               int(11)  (NULL)     YES             0                select,insert,update,references  观看数(应用内)            
    view_share_count         int(11)  (NULL)     YES             0                select,insert,update,references  分享观看数                 
    share_count              int(11)  (NULL)     YES             0                select,insert,update,references  分享数                       
    collect_count            int(11)  (NULL)     YES             0                select,insert,update,references  收藏数                       
    view_count_repeat        int(11)  (NULL)     YES             0                select,insert,update,references  重复观看数(应用内)  
    view_share_count_repeat  int(11)  (NULL)     YES             0                select,insert,update,references  重复分享观看数           
    like_count_today         int(11)  (NULL)     YES             0                select,insert,update,references  今日点赞数                 
    like_count_yesterday     int(11)  (NULL)     YES             0                select,insert,update,references  昨日点赞数                 
    view_count_today         int(11)  (NULL)     YES             0                select,insert,update,references  今日观看数                 
    view_count_yesterday     int(11)  (NULL)     YES             0                select,insert,update,references  昨日观看数                 
    
    /*索引信息*/--------------
    
    Table           Non_unique  Key_name  Seq_in_index  Column_name  Collation  Cardinality  Sub_part  Packed  Null    Index_type  Comment  Index_comment  
    --------------  ----------  --------  ------------  -----------  ---------  -----------  --------  ------  ------  ----------  -------  ---------------
    im_video_count           0  PRIMARY              1  video_id     A                 1216    (NULL)  (NULL)          BTREE
    im_video_count表中的数据,基本上都通过触发器实现更新,部分数据通过数据库的定时任务实现。
    以统计视频的点赞数为例,每当视频被点赞,表im_video_like都会插入一条记录,我们写了这样的一个触发器,每次im_video_like插入了新数据,im_video_count表对应视频的like_count,like_count_today均在原数据基础上加1。
    DELIMITER $$
    
    USE `imagingly`$$
    
    DROP TRIGGER /*!50032 IF EXISTS */ `trigger_video_like_insert`$$
    
    CREATE
        /*!50017 DEFINER = 'root'@'127.0.0.1' */
        TRIGGER `trigger_video_like_insert` AFTER INSERT ON `im_video_like` 
        FOR EACH ROW BEGIN
        
        #DECLARE userId INT(11);#被点赞视频的视频Id
        #SET userId = (SELECT user_id FROM `im_video` WHERE id =new.video_id);
        #点赞改变im_video_count表中对应视频的统计数据
            UPDATE `im_video_count` SET like_count =  like_count+1,like_count_today=like_count_today+1 WHERE video_id = new.video_id;
            #用户统计表,点赞数+1
            UPDATE `im_user_count` SET like_count_total=like_count_total+1,like_count_today=like_count_today+1 WHERE user_id=new.user_id;
        END;
    $$
    
    DELIMITER ;

    至于昨日点赞数、昨日观看数,则通过每天凌晨执行一次mysql定时任务实现,具体实现如下:

    DROP EVENT IF EXISTS `imagingly`.`bakVideoLikeAndViewCount`;
    DELIMITER $$
    
     SET GLOBAL event_scheduler = ON$$     -- required for event to execute but not create    
    
    CREATE    /*[DEFINER = { user | CURRENT_USER }]*/    EVENT `imagingly`.`bakVideoLikeAndViewCount`
    
    ON SCHEDULE
        EVERY 1 DAY 
        STARTS '2017-12-28 00:00:05'
        ON COMPLETION PRESERVE 
        ENABLE
        COMMENT '每日凌晨00:00:05,每隔一小时,今日点赞数赋值给昨日点赞数,今日观看数赋值给昨日观看数,今日点赞数、今日观看数清零'
    DO
        BEGIN
            UPDATE `im_video_count` SET like_count_yesterday=like_count_today,view_count_yesterday=view_count_today,like_count_today=0,view_count_today=0;END$$
    
    DELIMITER ;

    如此,以后获取点赞数、视频播放数,只需要左联im_video_count即可获得,节省了sql查询的时间。

  • 相关阅读:
    设计模式之观察者模式
    设计模式之模板方法模式
    设计模式之代理模式(全面讲解)
    设计模式之工厂模式(包含三种模式)
    设计模式之单例模式(包含三种方式)
    opencv+vs2015 堆内存析构异常
    用python来压缩文件
    GPT安装ubuntu的问题
    Two Sum and add Two Numbers
    [LeetCode] Palindrome Partitioning II
  • 原文地址:https://www.cnblogs.com/wangchaoBlog/p/8193471.html
Copyright © 2020-2023  润新知