# AI有声书生成工具 - 数据结构文档 ## 一、总体架构 系统采用 **书籍体系** 和 **学习路径体系** 两套并行的内容管理架构: ``` ┌─────────────────────────────────────────────────────────────┐ │ 书籍体系(有声书生成) │ │ Book → BookChapter → Audio │ └─────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ 学习路径体系(课程学习) │ │ LearningPath → Subject → Chapter → Section → ContentBlock │ └─────────────────────────────────────────────────────────────┘ ``` --- ## 二、书籍体系 ### 2.1 Book(书籍表) 存储书籍的元信息,包括标题、描述、大纲、进度等。 | 字段 | 类型 | 说明 | |------|------|------| | `id` | int | 书籍ID,自增主键 | | `userId` | int | 用户ID(可为空) | | `title` | varchar(191) | 书名 | | `subtitle` | varchar(191) | 副标题 | | `description` | text | 书籍描述 | | `targetAudience` | varchar(191) | 目标读者,默认"通用" | | `style` | varchar(191) | 风格,如"专业严谨" | | `totalChapters` | int | 总章节数 | | `estimatedWords` | int | 预估总字数 | | `status` | varchar(191) | 状态:draft/completed/generating/failed | | `progress` | int | 生成进度(百分比) | | `outlineJson` | longtext | 大纲JSON,结构见下方 | | `foreword` | text | 前言 | | `afterword` | text | 后记 | | `errorMsg` | text | 错误信息 | | `albumId` | int | 对应专辑ID(外键) | | `createdAt` | datetime | 创建时间 | | `updatedAt` | datetime | 更新时间 | #### outlineJson 结构 ```json { "mainTheme": "书籍主题", "structureLogic": "结构逻辑说明", "chapters": [ { "number": 1, "title": "第一章:xxx", "summary": "章节摘要", "keyPoints": ["知识点1", "知识点2"], "estimatedWords": 2800, "stories": [] } ] } ``` --- ### 2.2 BookChapter(书籍章节表) 存储书籍的章节信息,**keyPoints 字段存储该章节下的小节列表(JSON数组格式)**,形成事实上的三级目录结构。 | 字段 | 类型 | 说明 | |------|------|------| | `id` | int | 章节ID,自增主键 | | `bookId` | int | 所属书籍ID(外键→Book) | | `number` | int | 章节序号 | | `title` | varchar(191) | 章节标题 | | `summary` | text | 章节摘要 | | `keyPoints` | text | **小节列表(JSON数组)**,三级目录 | | `estimatedWords` | int | 预估字数 | | `content` | longtext | 章节正文内容 | | `wordCount` | int | 实际字数 | | `status` | varchar(191) | 状态:pending/completed/failed | | `errorMsg` | text | 错误信息 | | `generatedAt` | datetime | 生成时间 | | `audioId` | int | 对应音频ID(外键→Audio) | #### keyPoints 示例 ```json ["数据库与文件系统的本质差异", "三级模式与两级数据独立性", "DBMS的功能组成与典型架构", "数据模型的三大类别与对比"] ``` #### 三级目录结构 ``` Book(书) └── BookChapter(章)- 一级目录 └── keyPoints(小节)- 二级目录(JSON数组) ``` --- ### 2.3 Audio(音频表) 存储生成的音频文件信息。 | 字段 | 类型 | 说明 | |------|------|------| | `id` | int | 音频ID,自增主键 | | `userId` | int | 用户ID | | `title` | varchar(191) | 音频标题 | | `text` | text | 文本内容 | | `summary` | text | 摘要 | | `tags` | text | 标签 | | `audioUrl` | text | 音频文件URL | | `audioDuration` | int | 音频时长(秒) | | `audioSize` | int | 音频大小(字节) | | `wordCount` | int | 字数 | | `voiceId` | varchar(191) | 音色ID | | `voiceParams` | text | 音色参数 | | `status` | varchar(191) | 状态:processing/completed/failed | | `isFavorite` | tinyint | 是否收藏(0/1) | | `categoryId` | int | 分类ID(外键→Category) | | `albumId` | int | 所属专辑ID(外键→Album) | | `createdAt` | datetime | 创建时间 | | `updatedAt` | datetime | 更新时间 | --- ### 2.4 Album(专辑表) 用于组织和管理音频/书籍内容。 | 字段 | 类型 | 说明 | |------|------|------| | `id` | int | 专辑ID,自增主键 | | `userId` | int | 用户ID | | `name` | varchar(191) | 专辑名称 | | `description` | text | 专辑描述 | | `coverUrl` | varchar(191) | 封面图片URL | | `type` | varchar(191) | 类型:audio/book/video | | `status` | varchar(191) | 状态 | | `createdAt` | datetime | 创建时间 | | `updatedAt` | datetime | 更新时间 | --- ### 2.5 AlbumAudio(专辑音频关联表) | 字段 | 类型 | 说明 | |------|------|------| | `id` | int | 主键 | | `albumId` | int | 专辑ID(外键→Album) | | `audioId` | int | 音频ID(外键→Audio) | | `orderIndex` | int | 排序顺序 | --- ## 三、学习路径体系 适用于课程学习场景,采用完整的多层级结构。 ### 3.1 LearningPath(学习路径表) | 字段 | 类型 | 说明 | |------|------|------| | `id` | int | 主键 | | `userId` | int | 用户ID | | `topic` | text | 学习主题,如"机器学习" | | `status` | varchar(191) | 状态 | | `progress` | int | 进度 | | `totalCount` | int | 总数 | | `completedCount` | int | 已完成数 | | `currentStep` | varchar(191) | 当前步骤 | | `generationMode` | varchar(191) | 生成模式:progressive | | `createdAt` | datetime | 创建时间 | | `updatedAt` | datetime | 更新时间 | --- ### 3.2 Subject(科目表) 属于某个学习路径的科目/一级目录。 | 字段 | 类型 | 说明 | |------|------|------| | `id` | int | 主键 | | `learningPathId` | int | 所属学习路径ID(外键→LearningPath) | | `name` | varchar(191) | 科目名称 | | `orderIndex` | int | 排序顺序 | | `status` | varchar(191) | 状态 | | `aiResponse` | text | AI响应(JSON数组,存储子章节列表) | | `createdAt` | datetime | 创建时间 | | `updatedAt` | datetime | 更新时间 | #### aiResponse 示例 ```json ["心理学导论", "统计学基础", "人体解剖学", "生理心理学", "认知心理学"] ``` --- ### 3.3 Chapter(章节表) 属于某个科目的章节/二级目录。 | 字段 | 类型 | 说明 | |------|------|------| | `id` | int | 主键 | | `subjectId` | int | 所属科目ID(外键→Subject) | | `name` | varchar(191) | 章节名称 | | `orderIndex` | int | 排序顺序 | | `status` | varchar(191) | 状态 | | `aiResponse` | text | AI响应(JSON数组,存储小节列表) | | `createdAt` | datetime | 创建时间 | | `updatedAt` | datetime | 更新时间 | #### aiResponse 示例 ```json [ "第一章 心理学概述:心理学的研究对象、任务与方法", "第二章 心理学的生物学基础:神经系统的结构与功能", "第三章 感觉与知觉:感知觉的基本原理与现象" ] ``` --- ### 3.4 Section(小节表) 属于某个章节的小节/三级目录。 | 字段 | 类型 | 说明 | |------|------|------| | `id` | int | 主键 | | `chapterId` | int | 所属章节ID(外键→Chapter) | | `name` | varchar(191) | 小节名称 | | `orderIndex` | int | 排序顺序 | | `status` | varchar(191) | 状态 | | `aiResponse` | text | AI响应(JSON数组,存储内容块列表) | | `createdAt` | datetime | 创建时间 | | `updatedAt` | datetime | 更新时间 | #### aiResponse 示例 ```json [ {"section": "课程概述与目标", "content": "介绍本章的学习目标..."}, {"section": "学习规划的基本概念", "content": "讲解学习规划的定义..."} ] ``` --- ### 3.5 ContentBlock(内容块表) 小节下的具体内容。 | 字段 | 类型 | 说明 | |------|------|------| | `id` | int | 主键 | | `sectionId` | int | 所属小节ID(外键→Section) | | `content` | text | 内容文本 | | `orderIndex` | int | 排序顺序 | | `wordCount` | int | 字数 | | `createdAt` | datetime | 创建时间 | | `updatedAt` | datetime | 更新时间 | --- ## 四、学习路径五级目录结构 ``` LearningPath(学习路径/书本) └── Subject(科目/一级目录) └── Chapter(章节/二级目录) └── Section(小节/三级目录) └── ContentBlock(内容块/四级目录) ``` --- ## 五、核心关系图 ``` ┌──────────────────────────────────────────────────────────────────┐ │ 书籍体系 │ │ │ │ Book ──────< BookChapter ──────< Audio │ │ │ │ │ │ │ │ │ │ │ │ └────> Album <───┴───> AlbumAudio │ │ │ └──────────────────────────────────────────────────────────────────┘ ┌──────────────────────────────────────────────────────────────────┐ │ 学习路径体系 │ │ │ │ LearningPath ──< Subject ──< Chapter ──< Section ──< ContentBlock│ │ │ └──────────────────────────────────────────────────────────────────┘ ``` --- ## 六、状态字段说明 ### Book/BookChapter 状态流转 ``` draft → generating → completed ↘ failed ``` | 状态 | 含义 | |------|------| | `draft` | 草稿/待生成 | | `generating` | 生成中 | | `completed` | 已完成 | | `failed` | 生成失败 | ### Audio 状态 | 状态 | 含义 | |------|------| | `processing` | 处理中 | | `completed` | 已完成 | | `failed` | 失败 | ### Subject/Chapter/Section 状态 | 状态 | 含义 | |------|------| | `pending` | 等待生成 | | `generating` | 生成中 | | `completed` | 已完成 | | `failed` | 失败 | | `confirmed` | 已确认 | --- ## 七、索引设计 | 表名 | 索引 | 用途 | |------|------|------| | Book | `Book_userId_status_idx` | 按用户和状态查询 | | Book | `Book_createdAt_idx` | 按创建时间排序 | | Book | `Book_albumId_key` | 唯一索引,关联专辑 | | BookChapter | `BookChapter_bookId_number_key` | 唯一索引,书籍+序号 | | BookChapter | `BookChapter_bookId_idx` | 查询某书籍的所有章节 | | BookChapter | `BookChapter_audioId_key` | 唯一索引,关联音频 | | Audio | `Audio_userId_createdAt_idx` | 用户音频列表 | | Audio | `Audio_userId_isFavorite_idx` | 用户收藏列表 | | Audio | `Audio_categoryId_idx` | 分类查询 | | Audio | `Audio_albumId_idx` | 专辑内音频查询 | | Subject | `Subject_learningPathId_orderIndex_idx` | 学习路径下的科目排序 | | Chapter | `Chapter_subjectId_orderIndex_idx` | 科目下的章节排序 | | Section | `Section_chapterId_orderIndex_idx` | 章节下的小节排序 | | ContentBlock | `ContentBlock_sectionId_orderIndex_idx` | 小节下的内容排序 | --- ## 八、常用查询示例 ### 查询某书籍的所有章节 ```sql SELECT * FROM BookChapter WHERE bookId = 1 ORDER BY number; ``` ### 查询某章节下的所有小节(keyPoints) ```sql SELECT id, number, title, summary, keyPoints FROM BookChapter WHERE bookId = 1 AND number = 1; ``` ### 查询某专辑下的所有音频 ```sql SELECT a.* FROM Audio a JOIN AlbumAudio aa ON a.id = aa.audioId WHERE aa.albumId = 1 ORDER BY aa.orderIndex; ``` ### 查询某学习路径的完整结构 ```sql SELECT lp.topic, s.name as subject, c.name as chapter, sc.name as section FROM LearningPath lp JOIN Subject s ON s.learningPathId = lp.id JOIN Chapter c ON c.subjectId = s.id JOIN Section sc ON sc.chapterId = c.id WHERE lp.id = 1 ORDER BY s.orderIndex, c.orderIndex, sc.orderIndex; ```