# 内容关系模型

<cite>
**本文引用的文件**
- [schema.prisma](file://server/prisma/schema.prisma)
- [migration.sql](file://server/prisma/migrations/20260422105352_add_content_status/migration.sql)
- [book-generator.types.ts](file://server/src/modules/book-generator/book-generator.types.ts)
- [book-generator.service.ts](file://server/src/modules/book-generator/book-generator.service.ts)
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)
- [album-controller.ts](file://server/src/modules/book-generator/album-controller.ts)
- [history.controller.ts](file://server/src/modules/history/history.controller.ts)
- [comments.controller.ts](file://server/src/modules/comments/comments.controller.ts)
- [favorites.controller.ts](file://server/src/modules/favorites/favorites.controller.ts)
- [check-parentid.js](file://server/check-parentid.js)
- [fix-null-parentid.js](file://server/fix-null-parentid.js)
- [fix-book5-structure.js](file://server/fix-book5-structure.js)
- [database-structure.md](file://docs/database-structure.md)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本文件面向AI有声书生成平台，系统化阐述内容关系模型，重点覆盖：
- 书籍与章节的父子关系设计（含级联删除与数据一致性）
- 章节层级（parentId、level、number）如何构建树形结构及对导航与播放列表的影响
- 章节与播放记录、评论、收藏、播放列表项等关联表的关系映射
- 外键约束设计原则与索引策略
- 复杂查询场景示例与AI生成流程中的模型支撑

## 项目结构
围绕内容关系模型的核心文件分布如下：
- 数据库模型定义：Prisma Schema
- 外键与索引：迁移SQL
- 业务层：书籍生成编排、存储与控制器
- 关联模块：历史、评论、收藏、播放列表等

```mermaid
graph TB
subgraph "数据层"
SCHEMA["schema.prisma<br/>模型与关系定义"]
MIG["migration.sql<br/>外键与索引"]
end
subgraph "业务层"
TYPES["book-generator.types.ts<br/>类型定义"]
STORE["book-generator.store.ts<br/>存储与查询"]
SERVICE["book-generator.service.ts<br/>编排与流程控制"]
CTRL["album-controller.ts<br/>专辑/章节API"]
end
subgraph "关联模块"
HIS["history.controller.ts<br/>历史记录"]
COM["comments.controller.ts<br/>评论"]
FAV["favorites.controller.ts<br/>收藏"]
end
SCHEMA --> MIG
TYPES --> STORE
STORE --> SERVICE
SERVICE --> CTRL
SCHEMA -. 关联 .-> HIS
SCHEMA -. 关联 .-> COM
SCHEMA -. 关联 .-> FAV
```

图表来源
- [schema.prisma](file://server/prisma/schema.prisma)
- [migration.sql](file://server/prisma/migrations/20260422105352_add_content_status/migration.sql)
- [book-generator.types.ts](file://server/src/modules/book-generator/book-generator.types.ts)
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)
- [book-generator.service.ts](file://server/src/modules/book-generator/book-generator.service.ts)
- [album-controller.ts](file://server/src/modules/book-generator/album-controller.ts)
- [history.controller.ts](file://server/src/modules/history/history.controller.ts)
- [comments.controller.ts](file://server/src/modules/comments/comments.controller.ts)
- [favorites.controller.ts](file://server/src/modules/favorites/favorites.controller.ts)

章节来源
- [schema.prisma](file://server/prisma/schema.prisma)
- [migration.sql](file://server/prisma/migrations/20260422105352_add_content_status/migration.sql)

## 核心组件
- 书籍(Book)：顶层实体，承载书籍元信息与章节集合
- 章节(BookChapter)：树形结构核心，通过parentId、level、number构成层级
- 关联表：播放记录(PlayRecord)、评论(Comment)、收藏(Favorite)、播放列表项(PlaylistItem)

关键点：
- 章节树形结构由“bookId + parentId + level + number”唯一约束保障层级唯一性
- 章节与书籍之间存在级联删除，确保书籍删除时自动清理章节
- 章节与播放记录、评论、播放列表项之间建立一对一/一对多关系，支撑播放、互动与播放列表

章节来源
- [schema.prisma](file://server/prisma/schema.prisma)
- [book-generator.types.ts](file://server/src/modules/book-generator/book-generator.types.ts)

## 架构总览
内容关系模型在AI生成流程中的作用：
- 大纲生成：基于章节树形结构，逐层推进内容生成
- 内容创作：按章节层级生成正文，更新章节状态与媒体资源
- 音频/视频合成：按叶节点（level最大）生成媒体，再向上合并
- 导航与播放：树形结构驱动章节导航；播放列表基于章节或音频项

```mermaid
sequenceDiagram
participant U as "用户"
participant C as "专辑控制器(album-controller)"
participant S as "编排服务(book-generator.service)"
participant ST as "存储(book-generator.store)"
participant DB as "数据库(schema.prisma)"
U->>C : 请求生成书籍内容
C->>S : 触发批量生成编排
S->>ST : 获取章节树(getChapterTree)
ST->>DB : 查询章节(level, number排序)
DB-->>ST : 返回章节树
S->>ST : 生成叶节点内容(generate_content)
ST->>DB : 更新章节(genStage/content)
S->>ST : 生成叶节点音频(generate_audio)
ST->>DB : 更新章节(audioUrl/duration)
S->>ST : 合并父节点音频(merge_audio)
ST->>DB : 更新父章节(audioUrl/duration)
S-->>U : 推送进度/完成
```

图表来源
- [book-generator.service.ts](file://server/src/modules/book-generator/book-generator.service.ts)
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)
- [album-controller.ts](file://server/src/modules/book-generator/album-controller.ts)
- [schema.prisma](file://server/prisma/schema.prisma)

## 详细组件分析

### 书籍与章节的父子关系设计
- 章节树形结构
  - level：层级，1=章，2=节，3=小节
  - parentId：父节点ID，0表示章级根节点
  - number：同级序号，用于排序
  - 唯一约束：bookId + parentId + level + number，确保同一层级下序号唯一
- 级联删除
  - 章节与书籍：onDelete: Cascade，删除书籍时自动删除章节
  - 播放列表项与播放列表：onDelete: Cascade，删除播放列表时自动删除项
- 数据一致性
  - 通过唯一约束与外键约束，保证章节树的完整性
  - 通过事务操作（如发布/取消发布）保证状态变更原子性

```mermaid
erDiagram
BOOK {
int id PK
int userId
string title
boolean isPublished
string genStage
}
BOOKCHAPTER {
int id PK
int bookId FK
int parentId
int level
int number
string title
string audioUrl
int audioDuration
string genStage
}
PLAYRECORD {
int id PK
int userId FK
int chapterId FK
float progress
}
COMMENT {
int id PK
int userId FK
int chapterId FK
string content
}
FAVORITE {
int id PK
int userId FK
int bookId FK
}
PLAYLIST {
int id PK
int userId FK
string name
}
PLAYLISTITEM {
int id PK
int playlistId FK
int chapterId FK
int order
}
BOOK ||--o{ BOOKCHAPTER : "包含"
BOOKCHAPTER ||--o{ PLAYRECORD : "被播放"
BOOKCHAPTER ||--o{ COMMENT : "被评论"
BOOKCHAPTER ||--o{ PLAYLISTITEM : "作为项"
PLAYLIST ||--o{ PLAYLISTITEM : "包含"
USER ||--o{ PLAYRECORD : "产生记录"
USER ||--o{ COMMENT : "发表"
USER ||--o{ FAVORITE : "收藏"
BOOK ||--o{ FAVORITE : "被收藏"
```

图表来源
- [schema.prisma](file://server/prisma/schema.prisma)
- [migration.sql](file://server/prisma/migrations/20260422105352_add_content_status/migration.sql)

章节来源
- [schema.prisma](file://server/prisma/schema.prisma)
- [migration.sql](file://server/prisma/migrations/20260422105352_add_content_status/migration.sql)

### 章节层级与树形结构
- 层级关系
  - level=1：章（parentId=0）
  - level=2：节（parentId指向章）
  - level=3：小节（parentId指向节）
- 排序与导航
  - 同级按number升序排列
  - 前端按parentId分组构建树，支持章→节→小节三层导航
- 数据修复与校验
  - 修复异常level=1记录与错误parentId
  - 统一parentId为0（章级）或具体父节点ID

```mermaid
flowchart TD
Start(["开始"]) --> LoadChapters["加载书籍章节<br/>按 level+number 排序"]
LoadChapters --> BuildMap["构建映射：level=1/2 映射表"]
BuildMap --> LinkSections["连接节到章<br/>parentId=章ID"]
LinkSections --> LinkSubsections["连接小节到节<br/>parentId=节ID"]
LinkSubsections --> MergeAudio["按章聚合小节音频"]
MergeAudio --> UpdateChapter["更新章音频URL与时长"]
UpdateChapter --> End(["结束"])
```

图表来源
- [album-controller.ts](file://server/src/modules/book-generator/album-controller.ts)
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)

章节来源
- [album-controller.ts](file://server/src/modules/book-generator/album-controller.ts)
- [check-parentid.js](file://server/check-parentid.js)
- [fix-null-parentid.js](file://server/fix-null-parentid.js)
- [fix-book5-structure.js](file://server/fix-book5-structure.js)

### 与播放记录、评论、收藏、播放列表项的关系映射
- 播放记录(PlayRecord)
  - 关系：章节→播放记录（一对多）
  - 约束：onDelete: Restrict，防止误删播放记录
  - 用途：记录用户对章节的播放进度与时长
- 评论(Comment)
  - 关系：章节→评论（一对多）
  - 约束：onDelete: Restrict
  - 用途：章节评论与评分
- 收藏(Favorite)
  - 关系：书籍→收藏（一对多）
  - 约束：onDelete: Cascade（删除书籍时级联删除收藏）
  - 用途：用户收藏书籍
- 播放列表项(PlaylistItem)
  - 关系：播放列表→播放列表项（一对多）
  - 约束：onDelete: Cascade（删除播放列表时级联删除项）
  - 约束：onDelete: Set Null（章节删除时将项的chapterId置空）

章节来源
- [schema.prisma](file://server/prisma/schema.prisma)
- [migration.sql](file://server/prisma/migrations/20260422105352_add_content_status/migration.sql)

### 外键约束与更新行为
- onDelete行为
  - 章节→书籍：Cascade（删除书籍删除章节）
  - 收藏→书籍：Cascade（删除书籍删除收藏）
  - 播放列表→播放列表项：Cascade（删除播放列表删除项）
  - 播放记录/评论：Restrict（禁止删除仍有记录的章节）
  - 播放列表项→章节：Set Null（章节删除不影响播放列表项，但断链）
- onUpdate行为
  - 多数关系采用RESTRICT，避免级联更新导致的意外数据漂移
  - 个别关系采用CASCADE（如书籍与章节），确保主从一致

章节来源
- [migration.sql](file://server/prisma/migrations/20260422105352_add_content_status/migration.sql)
- [schema.prisma](file://server/prisma/schema.prisma)

### 索引策略与查询优化
- 复合唯一约束
  - 章节唯一约束：bookId + parentId + level + number，确保层级内序号唯一
- 常用索引
  - 章节：bookId、bookId+parentId、bookId+level，支撑树形查询与层级筛选
  - 播放记录：userId、chapterId，支撑用户播放历史与章节播放统计
  - 收藏：userId、bookId，支撑用户收藏查询
  - 播放列表项：playlistId+order，支撑播放列表顺序检索
- 查询优化建议
  - 树形查询优先使用bookId+level+number排序
  - 播放历史与统计查询结合chapterId与userId索引
  - 批量操作使用事务，减少锁竞争

章节来源
- [schema.prisma](file://server/prisma/schema.prisma)
- [migration.sql](file://server/prisma/migrations/20260422105352_add_content_status/migration.sql)

### 复杂查询场景示例
- 获取书籍完整大纲
  - 依据bookId查询所有章节，按level与number排序，构建章→节→小节树
- 查询章节播放历史
  - 以chapterId为条件，结合userId索引，查询PlayRecord列表
- 统计章节使用情况
  - 按chapterId分组统计播放次数、平均时长与用户数

章节来源
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)
- [album-controller.ts](file://server/src/modules/book-generator/album-controller.ts)
- [schema.prisma](file://server/prisma/schema.prisma)

### 在AI生成流程中的作用
- 大纲生成：根据书籍规模与目标受众生成章节大纲，形成level=1的章
- 内容创作：逐层生成节与小节内容，更新genStage与content
- 媒体合成：叶节点（level最大）生成音频/视频，再向上合并至父节点
- 导航与播放：树形结构支撑章节导航；播放列表基于章节或音频项

章节来源
- [book-generator.service.ts](file://server/src/modules/book-generator/book-generator.service.ts)
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)
- [database-structure.md](file://docs/database-structure.md)

## 依赖分析
- 组件耦合
  - 控制器依赖存储层，存储层依赖Prisma客户端
  - 编排服务协调存储与外部TTS/视频服务
- 外部依赖
  - Prisma ORM负责模型映射与查询
  - MySQL提供持久化存储与外键约束
- 循环依赖
  - 无明显循环依赖，模块职责清晰

```mermaid
graph LR
CTRL["album-controller.ts"] --> STORE["book-generator.store.ts"]
STORE --> PRISMA["@prisma/client"]
SERVICE["book-generator.service.ts"] --> STORE
SERVICE --> PRISMA
TYPES["book-generator.types.ts"] --> STORE
TYPES --> SERVICE
```

图表来源
- [album-controller.ts](file://server/src/modules/book-generator/album-controller.ts)
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)
- [book-generator.service.ts](file://server/src/modules/book-generator/book-generator.service.ts)
- [book-generator.types.ts](file://server/src/modules/book-generator/book-generator.types.ts)

## 性能考量
- 查询性能
  - 利用复合索引与唯一约束，降低重复与冲突
  - 树形查询按level与number排序，避免全表扫描
- 写入性能
  - 批量upsert减少重复创建与唯一冲突
  - 事务包裹批量更新，提升一致性与吞吐
- 存储与归档
  - 媒体资源URL化，减少文本字段膨胀
  - 播放历史与统计可异步归档，减轻主表压力

## 故障排查指南
- 章节层级异常
  - 症状：level=1但number异常大、parentId为NULL或指向错误
  - 处理：统一parentId为0或修正为正确父节点；删除无效记录
- 章节树不完整
  - 症状：节/小节缺失或错位
  - 处理：按bookId+level+number重建映射，核对parentId
- 播放记录/评论丢失
  - 症状：删除章节后播放记录/评论仍存在
  - 处理：确认onDelete行为为Restrict，避免误删；必要时迁移数据

章节来源
- [check-parentid.js](file://server/check-parentid.js)
- [fix-null-parentid.js](file://server/fix-null-parentid.js)
- [fix-book5-structure.js](file://server/fix-book5-structure.js)

## 结论
本内容关系模型以“bookId + parentId + level + number”的唯一约束为核心，构建稳定可靠的树形结构，配合级联删除与外键约束，确保书籍与章节数据的一致性。通过合理的索引策略与查询优化，支撑复杂的导航与播放列表需求。在AI生成流程中，该模型为大纲生成、内容创作与媒体合成提供了坚实的数据基础。

## 附录
- 相关文档与参考
  - 数据库结构说明
  - 书籍生成模块说明

章节来源
- [database-structure.md](file://docs/database-structure.md)