giftiaのblog

抖音实现关注用户、关注列的视频流的数据库设计

· giftia

一、关注关系表设计

关注关系表记录了用户之间的关注行为,是社交网络的基础。

CREATE TABLE user_follows (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    follower_id BIGINT NOT NULL COMMENT '关注者ID',
    following_id BIGINT NOT NULL COMMENT '被关注者ID',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '关注时间',
    status TINYINT DEFAULT 1 COMMENT '关注状态: 1=正常, 0=已取消',
    INDEX idx_follower (follower_id),
    INDEX idx_following (following_id),
    UNIQUE KEY uniq_follow (follower_id, following_id)
);

核心索引分析

  1. 用户关注列表查询

    SELECT following_id 
    FROM user_follows 
    WHERE follower_id = ? AND status = 1 
    ORDER BY created_at DESC 
    LIMIT 20;
    
    • 使用idx_follower (follower_id)索引,可快速定位用户的所有关注记录
    • 按关注时间倒序排列,支持最新关注优先展示
  2. 用户粉丝列表查询

    SELECT follower_id 
    FROM user_follows 
    WHERE following_id = ? AND status = 1 
    ORDER BY created_at DESC 
    LIMIT 20;
    
    • 使用idx_following (following_id)索引,优化粉丝列表的快速查询
    • 同样支持按关注时间排序,新粉丝优先展示
  3. 唯一索引约束

    • uniq_follow (follower_id, following_id)确保用户间关注关系的唯一性
    • 防止重复关注,保证数据完整性

二、视频表索引优化

视频表存储了所有用户发布的视频信息,是内容分发的核心。

CREATE TABLE videos (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    user_id BIGINT NOT NULL COMMENT '发布者ID',
    title VARCHAR(255) DEFAULT '' COMMENT '视频标题',
    video_url VARCHAR(1024) NOT NULL COMMENT '视频地址',
    cover_url VARCHAR(1024) DEFAULT '' COMMENT '封面地址',
    duration INT DEFAULT 0 COMMENT '视频时长(秒)',
    view_count BIGINT DEFAULT 0 COMMENT '播放量',
    like_count BIGINT DEFAULT 0 COMMENT '点赞数',
    comment_count BIGINT DEFAULT 0 COMMENT '评论数',
    share_count BIGINT DEFAULT 0 COMMENT '分享数',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '发布时间',
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    status TINYINT DEFAULT 1 COMMENT '状态: 1=发布, 0=草稿, -1=已删除',
    INDEX idx_user_id (user_id),
    INDEX idx_created_at (created_at)
);

关键索引作用

  1. 用户作品列表查询

    SELECT * 
    FROM videos 
    WHERE user_id = ? AND status = 1 
    ORDER BY created_at DESC 
    LIMIT 20;
    
    • idx_user_id (user_id)索引快速定位用户发布的所有视频
    • 结合created_at字段倒序,实现最新发布的视频优先展示
  2. 时间线查询优化

    SELECT * 
    FROM videos 
    WHERE created_at > ? AND status = 1 
    ORDER BY created_at DESC 
    LIMIT 100;
    
    • idx_created_at (created_at)索引支持范围查询
    • 适合按时间滚动加载最新视频内容

三、关注流缓存表索引策略

关注流缓存表是提升性能的关键,它预先聚合了用户关注对象发布的视频。

CREATE TABLE following_video_feeds (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    user_id BIGINT NOT NULL COMMENT '用户ID',
    video_id BIGINT NOT NULL COMMENT '视频ID',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
    INDEX idx_user_id_created (user_id, created_at),
    UNIQUE KEY uniq_user_video (user_id, video_id)
);

高性能索引设计

  1. 关注流查询

    SELECT v.* 
    FROM following_video_feeds f 
    JOIN videos v ON f.video_id = v.id 
    WHERE f.user_id = ? 
    ORDER BY f.created_at DESC 
    LIMIT 20;
    
    • 复合索引idx_user_id_created (user_id, created_at)是核心优化点
    • 先按user_id过滤,再按created_at排序,避免文件排序操作
  2. 唯一性保证

    • uniq_user_video (user_id, video_id)确保同一视频不会重复推送给用户
    • 防止视频流中出现重复内容,提升用户体验

四、索引优化实践建议

  1. 冷热数据分离

    • videos表按时间分表,近期热门数据单独存储
    • 减少单表数据量,提高索引效率
  2. 定期索引维护

    ANALYZE TABLE user_follows;
    OPTIMIZE TABLE following_video_feeds;
    
    • 定期分析和优化索引,保持最佳性能
  3. 覆盖索引优化

    SELECT video_id, created_at 
    FROM following_video_feeds 
    WHERE user_id = ? 
    ORDER BY created_at DESC 
    LIMIT 20;
    
    • 确保查询字段都在索引中,避免回表操作
  4. 监控与调整

    SHOW STATUS LIKE 'Handler_read%';
    SHOW INDEX FROM user_follows;
    
    • 通过监控索引使用情况,及时发现并调整低效索引

五、其他

  1. 大V关注流压力

    • 对于千万级粉丝的大V,采用推拉结合模式
    • 普通用户采用拉模式,核心用户采用推模式
  2. 索引空间占用

    • 对索引字段进行合理压缩
    • 定期清理无效数据,减小索引体积
  3. 写操作性能影响

    • 采用异步索引更新机制
    • 对写入密集型操作优化索引结构