Skip to content

数据库设计

数据库使用 PostgreSQL + GORM,迁移由 migrate 角色(migrations.AutoMigrate)统一执行。所有表按业务域组织,实体定义在 internal/model/entity/

ER 总览(按业务域)

text
┌── 用户与权限域 ──┐   ┌── 视频域 ──┐   ┌── 社交互动域 ──┐
│ users            │   │ videos     │   │ video_comments │
│ user_profiles    │   │ video_sources│  │ video_likes    │
│ roles            │   │ video_transcodes│ video_favorites │
│ authorities      │   │ video_manifest│ │ video_play_logs│
│ role_authority   │   │ tags        │   │ comment_likes  │
│ user_authority   │   │ video_tags  │   └────────────────┘
└──────────────────┘   └────────────┘
┌── 文件域 ──┐   ┌── 弹幕域 ──┐   ┌── 其他 ──┐
│ files      │   │ danmaku    │   │ audit_logs│
│            │   │ sensitive_words │ └──────────┘
└────────────┘   └────────────┘

用户与权限

说明关键列
users用户主表idusernamepassword(bcrypt)、emailstatusrole
user_profiles用户扩展资料user_idnicknameavatar
roles角色表code(如 admin/user)、name
authorities权限点resource(资源方法)、uri(资源路径)
role_authority角色-权限关联role_idauthority_id(联合主键)
user_authority用户-权限直接关联user_idauthority_id

文件管理

说明关键列
files通用文件表bucketobject_keyref_type(视频原片/封面/manifest/评论附件)、sizemime_typeref_count(引用计数)、status

files 是统一的对象引用表:原片、封面、DASH manifest、评论附件全部登记于此,支持引用计数(秒传去重依据)。

视频域

说明关键列
videos视频主表titledescriptioncover_file_iddurationstatus(uploading/processing/published/failed)、visibilitylike_count / favorite_count / play_count(冗余计数)
video_sources原始视频上传记录video_idfile_iduploaded_at
video_transcodes转码任务与状态video_idstatus(pending/processing/completed/failed)、resolutioncodecmanifest_file_id;索引 (status, updated_at, video_id) 供 watchdog 扫描
video_manifest播放清单video_idprotocol(dash)、file_idprofiles(档位 JSON)
tags / video_tags标签及视频-标签多对多-

为什么 videos 冗余计数列? 列表页高频展示三计数,直接读 videos 列避免 join 明细表;明细表(video_likes 等)只做持久化审计与去重。

社交互动域

说明关键列
video_comments评论video_iduser_idparent_id(父子结构)、contentstatus
video_likes点赞明细video_iduser_id(复合主键)
video_favorites收藏明细video_iduser_id(复合主键)
video_play_logs播放日志video_iduser_idipuser_agentplayed_at
comment_likes评论点赞comment_iduser_id

明细表与 Redis 的关系:

计数Redis 实时DB 持久化
点赞interaction:like:{videoID}(Set 去重)video_likes + videos.like_count
收藏interaction:fav:{videoID}(Set 去重)video_favorites + videos.favorite_count
播放interaction:play:{videoID}(INCR)video_play_logs + videos.play_count

弹幕域

说明关键列
danmaku弹幕video_iduser_idcontenttime_offset(时间轴位置)、colormode
sensitive_words敏感词库word(AC 自动机加载)

审计

说明
audit_logs操作审计日志(预留)

设计要点

  1. 复合主键做幂等video_likes / video_favorites(video_id, user_id) 复合主键,Flusher 幂等落库天然去重;
  2. 状态机驱动videos.statusvideo_transcodes.status 构成转码流水线的状态机,配合 Redis 租约实现分布式幂等;
  3. 冗余计数列:展示读 videos 冗余列,明细表只增不改,避免热点行更新;
  4. 索引支撑 Watchdog(status, updated_at, video_id) 索引让超时扫描走索引;
  5. 单库共享:当前所有服务共享 PostgreSQL,按「服务只读写自己归属的表集合」划分,跨服务用 ID 引用 + 事件/API(详见架构演进文档)。

迁移管理

bash
# 手动执行迁移
go run ./cmd/vistack migrate

多副本部署时,建议将迁移作为独立一次性任务执行(K8s Job / compose run once),避免多实例同时 AutoMigrate 竞争。

基于 MIT License 发布