# 数据模型扩展
**本文引用的文件**
- [schema.prisma](file://server/prisma/schema.prisma)
- [index.ts](file://server/src/models/index.ts)
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)
- [stage-manager.ts](file://server/src/modules/book-generator/stage-manager.ts)
- [migrate-genstage.ts](file://server/prisma/migrate-genstage.ts)
- [sync-genstage.ts](file://server/prisma/sync-genstage.ts)
- [database-structure.md](file://docs/database-structure.md)
- [package.json](file://server/package.json)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构概览](#架构概览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向AI有声书生成平台的数据模型扩展需求,系统化说明如何基于Prisma ORM进行实体关系设计、字段定义与约束变更;解释迁移管理与版本控制策略;提供新增表、索引优化与查询性能调优的实践指南;阐述数据模型演进、向后兼容与数据迁移的最佳实践,并覆盖数据验证、事务处理与并发控制的实现方法。
## 项目结构
围绕数据模型与ORM的核心位置如下:
- Prisma Schema:定义数据模型、索引与关系
- Prisma Client接入:全局实例化与连接管理
- 业务模块存储层:对Prisma的封装与事务使用
- 状态机与迁移脚本:确保历史数据与新字段一致
- 文档与依赖:数据库结构说明与Prisma版本
```mermaid
graph TB
subgraph "数据层"
PRISMA["Prisma Schema
server/prisma/schema.prisma"]
CLIENT["Prisma Client
server/src/models/index.ts"]
end
subgraph "业务层"
STORE["存储封装
book-generator.store.ts"]
STAGE["状态机与并发控制
stage-manager.ts"]
MIGRATE["迁移脚本
migrate-genstage.ts / sync-genstage.ts"]
end
subgraph "文档与依赖"
DOC["数据库结构文档
docs/database-structure.md"]
PKG["依赖与版本
server/package.json"]
end
PRISMA --> CLIENT
CLIENT --> STORE
STORE --> STAGE
MIGRATE --> PRISMA
DOC --> PRISMA
PKG --> PRISMA
```
**图表来源**
- [schema.prisma](file://server/prisma/schema.prisma)
- [index.ts](file://server/src/models/index.ts)
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)
- [stage-manager.ts](file://server/src/modules/book-generator/stage-manager.ts)
- [migrate-genstage.ts](file://server/prisma/migrate-genstage.ts)
- [sync-genstage.ts](file://server/prisma/sync-genstage.ts)
- [database-structure.md](file://docs/database-structure.md)
- [package.json](file://server/package.json)
**章节来源**
- [schema.prisma](file://server/prisma/schema.prisma)
- [index.ts](file://server/src/models/index.ts)
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)
- [stage-manager.ts](file://server/src/modules/book-generator/stage-manager.ts)
- [migrate-genstage.ts](file://server/prisma/migrate-genstage.ts)
- [sync-genstage.ts](file://server/prisma/sync-genstage.ts)
- [database-structure.md](file://docs/database-structure.md)
- [package.json](file://server/package.json)
## 核心组件
- Prisma Schema:集中定义实体、字段、索引、唯一约束与关系
- Prisma Client:全局单例,负责连接与查询
- 存储封装(BookStore):对Prisma的CRUD封装,包含事务与批量操作
- 状态机与并发控制:线性阶段模型、乐观锁与资源清理
- 迁移脚本:历史字段到新字段的迁移与同步
**章节来源**
- [schema.prisma](file://server/prisma/schema.prisma)
- [index.ts](file://server/src/models/index.ts)
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)
- [stage-manager.ts](file://server/src/modules/book-generator/stage-manager.ts)
- [migrate-genstage.ts](file://server/prisma/migrate-genstage.ts)
- [sync-genstage.ts](file://server/prisma/sync-genstage.ts)
## 架构概览
数据模型扩展遵循“Schema先行、Client接入、封装调用、状态机保障、迁移兜底”的整体流程。
```mermaid
sequenceDiagram
participant Dev as "开发者"
participant Schema as "Prisma Schema"
participant Client as "Prisma Client"
participant Store as "存储封装(BookStore)"
participant Stage as "状态机(stage-manager)"
participant DB as "MySQL"
Dev->>Schema : 修改/新增模型与索引
Schema->>Client : 生成客户端代码
Client->>DB : 执行迁移/查询
Store->>Client : CRUD/事务
Stage->>Client : 乐观锁状态转移
Client-->>DB : 提交/回滚
```
**图表来源**
- [schema.prisma](file://server/prisma/schema.prisma)
- [index.ts](file://server/src/models/index.ts)
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)
- [stage-manager.ts](file://server/src/modules/book-generator/stage-manager.ts)
## 详细组件分析
### Prisma ORM与Schema设计
- 数据源与生成器:定义provider与数据库连接
- 实体与字段:使用原生类型注解、默认值、长度限制
- 关系与外键:@relation声明字段映射与删除策略
- 索引与唯一:@@index、@@unique、@@map命名
- 复合唯一键:如BookChapter的bookId_parentId_level_number
```mermaid
erDiagram
USER ||--o{ COMMENT : "评论"
USER ||--o{ DRAFT : "草稿"
USER ||--o{ FAVORITE : "收藏"
USER ||--o{ ORDER : "订单"
USER ||--o{ PLAY_RECORD : "播放记录"
USER ||--o{ PLAYLIST : "播放列表"
USER ||--o{ SIGN_RECORD : "签到"
USER ||--o{ SUBSCRIPTION : "订阅"
USER ||--o{ TOKEN_BALANCE : "余额"
USER ||--o{ TOKEN_USAGE : "用量"
USER ||--o{ PREFERENCE : "偏好"
BOOK }o--o{ BOOK_CHAPTER : "章节"
BOOK ||--o{ VIDEO_PROJECT : "视频项目"
BOOK }o--o{ FAVORITE : "收藏"
BOOK_CHAPTER ||--o{ COMMENT : "评论"
BOOK_CHAPTER ||--o{ PLAY_RECORD : "播放记录"
BOOK_CHAPTER ||--o{ PLAYLIST_ITEM : "播放列表项"
BOOK_CHAPTER ||--o{ VIDEO_PROJECT : "视频项目"
PLAYLIST ||--o{ PLAYLIST_ITEM : "条目"
PLAYLIST }o--o{ USER : "拥有者"
ORDER }o--o{ USER : "购买者"
ORDER }o--o{ SUBSCRIPTION_PLAN : "套餐"
ORDER ||--o{ TOKEN_USAGE : "用量"
SUBSCRIPTION }o--o{ USER : "用户"
SUBSCRIPTION }o--o{ SUBSCRIPTION_PLAN : "套餐"
```
**图表来源**
- [schema.prisma](file://server/prisma/schema.prisma)
**章节来源**
- [schema.prisma](file://server/prisma/schema.prisma)
### Prisma Client接入与连接管理
- 单例初始化:在应用启动时创建PrismaClient
- 连接生命周期:统一connect与错误处理
- 导出复用:供各模块导入使用
**章节来源**
- [index.ts](file://server/src/models/index.ts)
### 存储封装(BookStore)与事务
- 事务边界:发布/取消发布书籍时使用$transaction保证一致性
- 批量操作:upsert避免重复创建,提升幂等性
- 查询封装:include关联、orderBy排序、条件筛选
- 状态映射:outlineJson解析、章节树构建
```mermaid
sequenceDiagram
participant Svc as "业务服务"
participant Store as "BookStore"
participant Prisma as "Prisma Client"
participant Tx as "事务"
participant DB as "MySQL"
Svc->>Store : publishAlbum(bookId)
Store->>Tx : 开启事务
Tx->>Prisma : 更新book.isPublished
Tx->>Prisma : 更新bookChapter.isPublic(有音频)
Prisma-->>Tx : 提交
Tx-->>Store : 成功
Store-->>Svc : 返回
```
**图表来源**
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)
**章节来源**
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)
### 状态机与并发控制
- 线性阶段:章节与书籍均采用线性阶段序列,便于顺序推进
- 转移矩阵:严格限制合法状态转移,防止逆向推进
- 乐观锁:updateMany带条件校验,失败重试或提示冲突
- 资源清理:回退时自动清理下游产物(音频/视频URL与时长)
```mermaid
flowchart TD
Start(["进入 safeTransition"]) --> CheckAllowed["检查是否允许转移"]
CheckAllowed --> |否| Error["抛出非法转移错误"]
CheckAllowed --> |是| CalcClean["计算需要清理的下游资源"]
CalcClean --> Optimistic["乐观锁写入:updateMany(genStage=当前)"]
Optimistic --> CountZero{"影响行数=0?"}
CountZero --> |是| QueryActual["查询实际状态"]
QueryActual --> SameTarget{"实际状态=目标?"}
SameTarget --> |是| Skip["跳过已达成"]
SameTarget --> |否| Conflict["记录冲突并跳过"]
CountZero --> |否| Done(["完成"])
```
**图表来源**
- [stage-manager.ts](file://server/src/modules/book-generator/stage-manager.ts)
**章节来源**
- [stage-manager.ts](file://server/src/modules/book-generator/stage-manager.ts)
### 历史数据迁移与同步
- 迁移脚本:将旧字段(status/contentStatus/audioStatus/videoStatus)映射到新字段genStage
- 同步脚本:结合状态机的安全转移函数,逐条同步并处理并发冲突
- 推断逻辑:根据子章节状态推断书籍阶段,确保一致性
```mermaid
sequenceDiagram
participant Script as "迁移/同步脚本"
participant Prisma as "Prisma Client"
participant Stage as "状态机函数"
participant DB as "MySQL"
Script->>Prisma : 查询旧字段
Script->>Script : 推断/计算新genStage
Script->>Stage : safeTransition/advance/sync
Stage->>Prisma : 乐观锁更新
Prisma-->>Stage : 结果
Stage-->>Script : 成功/跳过
```
**图表来源**
- [migrate-genstage.ts](file://server/prisma/migrate-genstage.ts)
- [sync-genstage.ts](file://server/prisma/sync-genstage.ts)
- [stage-manager.ts](file://server/src/modules/book-generator/stage-manager.ts)
**章节来源**
- [migrate-genstage.ts](file://server/prisma/migrate-genstage.ts)
- [sync-genstage.ts](file://server/prisma/sync-genstage.ts)
- [stage-manager.ts](file://server/src/modules/book-generator/stage-manager.ts)
## 依赖分析
- Prisma版本:6.x,需与客户端版本匹配
- 数据库:MySQL,使用Prisma client-js
- 依赖关系:业务模块通过存储封装间接依赖Prisma Client
```mermaid
graph LR
PKG["server/package.json"] --> PRISMA["Prisma 6.x"]
PKG --> CLIENT["@prisma/client"]
STORE["book-generator.store.ts"] --> CLIENT
STAGE["stage-manager.ts"] --> CLIENT
SCHEMA["schema.prisma"] --> PRISMA
```
**图表来源**
- [package.json](file://server/package.json)
- [schema.prisma](file://server/prisma/schema.prisma)
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)
- [stage-manager.ts](file://server/src/modules/book-generator/stage-manager.ts)
**章节来源**
- [package.json](file://server/package.json)
- [schema.prisma](file://server/prisma/schema.prisma)
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)
- [stage-manager.ts](file://server/src/modules/book-generator/stage-manager.ts)
## 性能考虑
- 索引设计
- 优先覆盖高频查询条件,如用户维度、状态、时间范围
- 复合索引避免回表,如Book(userId,status)、BookChapter(bookId,parent,level,number)
- 查询优化
- 使用select精确投影,减少字段传输
- 使用orderBy与limit控制结果集大小
- 避免N+1查询,合理使用include与嵌套where
- 写入优化
- 批量upsert替代多次insert/update
- 事务合并多个写操作,减少往返
- 状态机与幂等
- 乐观锁降低锁竞争,提升并发吞吐
- 资源清理避免脏数据残留
[本节为通用指导,无需具体文件分析]
## 故障排查指南
- 连接失败
- 检查DATABASE_URL环境变量与数据库可达性
- 确认Prisma Client初始化与connect调用
- 迁移异常
- 查看迁移日志与lock文件,必要时手动清理lock
- 使用迁移脚本或同步脚本修复genStage不一致
- 并发冲突
- safeTransition返回0影响行数时,检查实际状态与转移矩阵
- 避免跨模块同时修改同一记录,必要时加分布式锁
- 查询慢
- 为where/orderBy列建立复合索引
- 使用EXPLAIN分析执行计划,调整索引与查询条件
**章节来源**
- [index.ts](file://server/src/models/index.ts)
- [migrate-genstage.ts](file://server/prisma/migrate-genstage.ts)
- [sync-genstage.ts](file://server/prisma/sync-genstage.ts)
- [stage-manager.ts](file://server/src/modules/book-generator/stage-manager.ts)
## 结论
通过“Schema先行、Client接入、封装调用、状态机保障、迁移兜底”的整体设计,平台实现了可演进、可扩展、可维护的数据模型。遵循本文的扩展流程与最佳实践,可在保证向后兼容与数据一致性的前提下,安全地引入新表、字段与索引,持续提升系统性能与稳定性。
[本节为总结,无需具体文件分析]
## 附录
### 数据模型扩展实践清单
- 在schema.prisma中新增/修改模型与字段,补充索引与唯一约束
- 生成客户端代码并进行本地测试
- 在存储封装中添加/调整CRUD方法,必要时开启事务
- 编写迁移脚本或同步脚本,处理历史数据映射
- 在状态机中补充/校验状态转移矩阵,确保并发安全
- 编写单元/集成测试,覆盖关键路径与边界条件
- 评估并添加必要的索引,优化查询性能
- 更新文档与API契约,保持内外一致
**章节来源**
- [schema.prisma](file://server/prisma/schema.prisma)
- [book-generator.store.ts](file://server/src/modules/book-generator/book-generator.store.ts)
- [stage-manager.ts](file://server/src/modules/book-generator/stage-manager.ts)
- [migrate-genstage.ts](file://server/prisma/migrate-genstage.ts)
- [sync-genstage.ts](file://server/prisma/sync-genstage.ts)