Skip to Content
Documentation数据模型

数据模型

API 使用 Prisma + PostgreSQL。核心设计:全局媒体去重 + 用户个人库 + 按指纹共享字幕

ER 关系

Media(全局媒体库)

按来源分两种类型:

字段fileyoutube
fileHashSHA-256,唯一下载后填充
youtubeVideoId唯一
audioS3Key创建时有值下载后填充
coverUrlApp 生成YouTube 缩略图

去重键

  • 本地文件:fileHash
  • YouTube:youtubeVideoId

处理状态subtitleStatus):pending | processing | success | failed

辅助字段:subtitleLog(Worker 日志)、subtitleError(失败原因)

UserMedia(用户媒体库)

用户与全局媒体的关联表,支持:

  • 标题覆盖UserMedia.title 优先于 Media.title
  • 标签tags: string[],首页可按 tag 筛选

删除操作仅移除 UserMedia,不影响全局 Media 与其他用户。

Subtitle(字幕)

  • 通过 fileHash 与音频关联(即使 mediaId 尚未绑定也可存在)
  • (fileHash, language) 唯一
  • 创建后挂载到具体 Media.mediaId

指纹复用

attachSubtitlesByFileHash(mediaId, fileHash)

  1. 查找同 fileHash 的所有字幕
  2. 批量更新 mediaId 指向新媒体
  3. Media.subtitleStatus 设为 success

这使用户 B 上传用户 A 已处理过的相同音频时,零等待获得字幕。

SubtitleSegment(字幕片段)

字段说明
segmentIndex顺序号,与 Speech SSE 的 index 对应
text转写文本
startSeconds / endSeconds时间轴
translation译文
translationCached翻译是否来自缓存

子表:

  • SubtitleToken:Sudachi 分词,含 surface、reading、pos、kanji
  • SubtitleBunsetu:Ginza 文节,含 type、meaning、tokenIndices

Infra(运行时配置)

Infra 表存储键值型基础设施配置,API 启动时加载到内存。用于在不重启代码的情况下调整部分运行参数。

索引策略

主要查询路径:

  • 用户媒体列表:UserMedia.userId + createdAt DESC
  • Worker 认领任务:Media.subtitleStatus + sourceType + audioS3Key
  • 字幕分页:SubtitleSegment.subtitleId + segmentIndex
  • 指纹查找:Media.fileHashSubtitle.fileHash