# 数据模型扩展 **本文引用的文件** - [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)