# PKB - 个人知识库模块:数据库设计 > **版本:** v1.0 > **更新时间:** 2025-11-12 > **数据库Schema:** `pkb_schema` > **状态:** ✅ 已实施并迁移 --- ## 📋 目录 1. [模块概述](#模块概述) 2. [Schema信息](#schema信息) 3. [数据库表设计](#数据库表设计) 4. [表关系图](#表关系图) 5. [索引设计](#索引设计) 6. [Phase 3功能说明](#phase-3功能说明) 7. [变更历史](#变更历史) --- ## 模块概述 ### 功能定位 **PKB(Personal Knowledge Base)- 个人知识库模块**提供文献管理和智能问答能力,核心功能: 1. **知识库管理** - 创建和管理个人知识库 2. **文档上传** - 支持PDF/Word/TXT等格式文档 3. **智能问答** - 基于知识库的RAG(检索增强生成)对话 4. **批处理任务** - 批量处理文献提取(Phase 3) 5. **任务模板** - 预定义的批处理任务模板(Phase 3) ### 核心业务场景 - 用户创建知识库(如"CLL相关知识库") - 上传PDF文献到知识库 - 自动提取文本并向量化 - 基于知识库进行智能问答 - 批量提取文献中的结构化信息 ### 与Dify平台集成 PKB模块深度集成Dify平台: - 每个知识库对应一个Dify Dataset - 每个文档对应一个Dify Document - 使用Dify的向量检索和RAG能力 --- ## Schema信息 ### Schema名称 ```sql pkb_schema ``` ### 创建语句 ```sql CREATE SCHEMA IF NOT EXISTS pkb_schema; GRANT ALL ON SCHEMA pkb_schema TO aiclinical_admin; ``` ### 数据迁移 - **迁移时间:** 2025-11-12 - **源Schema:** public - **迁移脚本:** `docs/09-架构实施/migration-scripts/004-migrate-pkb.sql` - **数据完整性:** ✅ 100%迁移成功 --- ## 数据库表设计 ### 表列表 | 表名 | 用途 | 行数(估计) | 状态 | |------|------|------------|------| | `knowledge_bases` | 知识库 | 5-50/用户 | ✅ 已部署 | | `documents` | 文档 | 10-1000/知识库 | ✅ 已部署 | | `batch_tasks` | 批处理任务 | 1-100/知识库 | ✅ Phase 3 | | `batch_results` | 批处理结果 | N条/任务 | ✅ Phase 3 | | `task_templates` | 任务模板 | 10-50/用户 | ✅ Phase 3(预留) | **总计:** 5个表(2个核心表 + 3个Phase 3表) --- ### 1. knowledge_bases - 知识库表 **用途:** 存储用户创建的个人知识库 #### 表结构 | 字段名 | 数据类型 | 约束 | 说明 | |--------|---------|------|------| | id | TEXT | PRIMARY KEY | 知识库唯一标识(UUID) | | user_id | TEXT | NOT NULL, FK | 所属用户ID | | name | TEXT | NOT NULL | 知识库名称 | | description | TEXT | NULL | 知识库描述 | | dify_dataset_id | TEXT | NOT NULL, UNIQUE | Dify平台的Dataset ID | | file_count | INTEGER | NOT NULL, DEFAULT 0 | 文件数量 | | total_size_bytes | BIGINT | NOT NULL, DEFAULT 0 | 总文件大小(字节) | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL | 更新时间 | #### Prisma Model ```prisma model KnowledgeBase { id String @id @default(uuid()) userId String @map("user_id") name String description String? difyDatasetId String @map("dify_dataset_id") fileCount Int @default(0) @map("file_count") totalSizeBytes BigInt @default(0) @map("total_size_bytes") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") user User @relation(fields: [userId], references: [id], onDelete: Cascade) documents Document[] batchTasks BatchTask[] @@index([userId]) @@index([difyDatasetId]) @@map("knowledge_bases") @@schema("pkb_schema") } ``` #### 业务规则 1. **Dify绑定** - 每个知识库对应唯一的Dify Dataset 2. **统计字段** - `file_count`和`total_size_bytes`需实时更新 3. **用户隔离** - 通过`user_id`实现数据隔离 4. **级联删除** - 删除知识库时,文档和任务也被删除 --- ### 2. documents - 文档表 **用途:** 存储知识库中的文档信息 #### 表结构 | 字段名 | 数据类型 | 约束 | 说明 | |--------|---------|------|------| | id | TEXT | PRIMARY KEY | 文档唯一标识(UUID) | | kb_id | TEXT | NOT NULL, FK | 所属知识库ID | | user_id | TEXT | NOT NULL, FK | 所属用户ID | | filename | TEXT | NOT NULL | 文件名 | | file_type | TEXT | NOT NULL | 文件类型(pdf/doc/txt等) | | file_size_bytes | BIGINT | NOT NULL | 文件大小(字节) | | file_url | TEXT | NOT NULL | 文件存储URL | | dify_document_id | TEXT | NOT NULL | Dify平台的Document ID | | status | TEXT | NOT NULL, DEFAULT 'uploading' | 状态(uploading/processing/completed/failed) | | progress | INTEGER | NOT NULL, DEFAULT 0 | 处理进度(0-100) | | error_message | TEXT | NULL | 错误信息 | | segments_count | INTEGER | NULL | 切片数量 | | tokens_count | INTEGER | NULL | Token数量 | | extraction_method | TEXT | NULL | 提取方法(auto/ocr/parse) | | **Phase 2字段** | | | **全文阅读功能** | | full_text | TEXT | NULL | 完整文本内容 | | full_text_length | INTEGER | NULL | 文本长度 | | metadata | JSONB | NULL | 元数据(作者、标题、摘要等) | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL | 更新时间 | #### Prisma Model ```prisma model Document { id String @id @default(uuid()) kbId String @map("kb_id") userId String @map("user_id") filename String fileType String @map("file_type") fileSizeBytes BigInt @map("file_size_bytes") fileUrl String @map("file_url") difyDocumentId String @map("dify_document_id") status String @default("uploading") progress Int @default(0) errorMessage String? @map("error_message") segmentsCount Int? @map("segments_count") tokensCount Int? @map("tokens_count") extractionMethod String? @map("extraction_method") // Phase 2: 全文阅读功能 fullText String? @map("full_text") @db.Text fullTextLength Int? @map("full_text_length") metadata Json? createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") knowledgeBase KnowledgeBase @relation(fields: [kbId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) batchResults BatchResult[] @@index([kbId]) @@index([userId]) @@index([status]) @@index([difyDocumentId]) @@index([extractionMethod]) @@map("documents") @@schema("pkb_schema") } ``` #### 业务规则 1. **状态机** - `status`字段管理文档处理流程 - `uploading` → `processing` → `completed` - 失败时转为`failed` 2. **Dify同步** - 每个文档对应Dify中的一个Document 3. **提取方法** - 支持自动识别、OCR、解析三种方式 4. **Phase 2扩展** - `full_text`字段用于全文阅读和深度分析 --- ### 3. batch_tasks - 批处理任务表 (Phase 3) **用途:** 批量处理文献,提取结构化信息 #### 表结构 | 字段名 | 数据类型 | 约束 | 说明 | |--------|---------|------|------| | id | TEXT | PRIMARY KEY | 任务唯一标识(UUID) | | user_id | TEXT | NOT NULL, FK | 所属用户ID | | kb_id | TEXT | NOT NULL, FK | 所属知识库ID | | task_name | TEXT | NOT NULL | 任务名称 | | task_type | TEXT | NOT NULL | 任务类型(extract_info/summarize等) | | prompt_template | TEXT | NOT NULL | Prompt模板 | | model_name | TEXT | NOT NULL, DEFAULT 'gpt-4' | 使用的LLM模型 | | status | TEXT | NOT NULL, DEFAULT 'pending' | 状态(pending/running/completed/failed) | | total_documents | INTEGER | NOT NULL, DEFAULT 0 | 总文档数 | | processed_count | INTEGER | NOT NULL, DEFAULT 0 | 已处理数 | | success_count | INTEGER | NOT NULL, DEFAULT 0 | 成功数 | | failed_count | INTEGER | NOT NULL, DEFAULT 0 | 失败数 | | error_message | TEXT | NULL | 错误信息 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL | 更新时间 | #### Prisma Model ```prisma model BatchTask { id String @id @default(uuid()) userId String @map("user_id") kbId String @map("kb_id") taskName String @map("task_name") taskType String @map("task_type") promptTemplate String @map("prompt_template") @db.Text modelName String @default("gpt-4") @map("model_name") status String @default("pending") totalDocuments Int @default(0) @map("total_documents") processedCount Int @default(0) @map("processed_count") successCount Int @default(0) @map("success_count") failedCount Int @default(0) @map("failed_count") errorMessage String? @map("error_message") @db.Text user User @relation(fields: [userId], references: [id], onDelete: Cascade) knowledgeBase KnowledgeBase @relation(fields: [kbId], references: [id], onDelete: Cascade) results BatchResult[] createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@index([userId]) @@index([kbId]) @@index([status]) @@index([createdAt]) @@map("batch_tasks") @@schema("pkb_schema") } ``` #### 业务规则 1. **任务类型** - 支持多种批处理类型 - `extract_info` - 提取结构化信息 - `summarize` - 批量摘要 - `classify` - 文献分类 2. **状态机** - `status`管理任务执行状态 3. **进度跟踪** - 实时更新计数器字段 4. **模型选择** - 支持多种LLM模型 --- ### 4. batch_results - 批处理结果表 (Phase 3) **用途:** 存储批处理任务的每篇文献结果 #### 表结构 | 字段名 | 数据类型 | 约束 | 说明 | |--------|---------|------|------| | id | TEXT | PRIMARY KEY | 结果唯一标识(UUID) | | task_id | TEXT | NOT NULL, FK | 所属任务ID | | document_id | TEXT | NOT NULL, FK | 所属文档ID | | status | TEXT | NOT NULL, DEFAULT 'pending' | 状态(pending/processing/completed/failed) | | result_data | JSONB | NULL | 提取的结构化数据 | | raw_output | TEXT | NULL | LLM原始输出 | | tokens_used | INTEGER | NULL | 使用的Token数 | | error_message | TEXT | NULL | 错误信息 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 | #### Prisma Model ```prisma model BatchResult { id String @id @default(uuid()) taskId String @map("task_id") documentId String @map("document_id") status String @default("pending") resultData Json? @map("result_data") rawOutput String? @map("raw_output") @db.Text tokensUsed Int? @map("tokens_used") errorMessage String? @map("error_message") @db.Text task BatchTask @relation(fields: [taskId], references: [id], onDelete: Cascade) document Document @relation(fields: [documentId], references: [id], onDelete: Cascade) createdAt DateTime @default(now()) @map("created_at") @@index([taskId]) @@index([documentId]) @@index([status]) @@map("batch_results") @@schema("pkb_schema") } ``` #### 业务规则 1. **结果存储** - `result_data`存储JSON格式的结构化数据 2. **原始输出** - `raw_output`保留LLM原始输出,便于调试 3. **Token统计** - 记录每篇文献的Token消耗 --- ### 5. task_templates - 任务模板表 (Phase 3, 暂不实现) **用途:** 存储预定义的批处理任务模板 #### 表结构 | 字段名 | 数据类型 | 约束 | 说明 | |--------|---------|------|------| | id | TEXT | PRIMARY KEY | 模板唯一标识(UUID) | | user_id | TEXT | NOT NULL, FK | 所属用户ID | | template_name | TEXT | NOT NULL | 模板名称 | | task_type | TEXT | NOT NULL | 任务类型 | | prompt_template | TEXT | NOT NULL | Prompt模板 | | output_fields | JSONB | NOT NULL, DEFAULT '{}' | 输出字段定义 | | model_name | TEXT | NOT NULL, DEFAULT 'gpt-4' | 默认模型 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL | 更新时间 | #### Prisma Model ```prisma model TaskTemplate { id String @id @default(uuid()) userId String @map("user_id") templateName String @map("template_name") taskType String @map("task_type") promptTemplate String @map("prompt_template") @db.Text outputFields Json @default("{}") @map("output_fields") modelName String @default("gpt-4") @map("model_name") user User @relation(fields: [userId], references: [id], onDelete: Cascade) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@index([userId]) @@map("task_templates") @@schema("pkb_schema") } ``` #### 业务规则 1. **模板复用** - 用户可保存常用的任务配置 2. **字段定义** - `output_fields`定义期望的输出结构 3. **暂不实现** - Phase 3预留,后续开发 --- ## 表关系图 ```mermaid erDiagram PLATFORM_USERS ||--o{ KNOWLEDGE_BASES : "owns" PLATFORM_USERS ||--o{ DOCUMENTS : "uploads" PLATFORM_USERS ||--o{ BATCH_TASKS : "creates" PLATFORM_USERS ||--o{ TASK_TEMPLATES : "defines" KNOWLEDGE_BASES ||--o{ DOCUMENTS : "contains" KNOWLEDGE_BASES ||--o{ BATCH_TASKS : "processes" BATCH_TASKS ||--o{ BATCH_RESULTS : "generates" DOCUMENTS ||--o{ BATCH_RESULTS : "analyzed_by" PLATFORM_USERS { text id PK text email text password } KNOWLEDGE_BASES { text id PK text user_id FK text name text dify_dataset_id int file_count bigint total_size_bytes } DOCUMENTS { text id PK text kb_id FK text user_id FK text filename text file_type text dify_document_id text status text full_text jsonb metadata } BATCH_TASKS { text id PK text user_id FK text kb_id FK text task_name text task_type text status int total_documents int processed_count } BATCH_RESULTS { text id PK text task_id FK text document_id FK text status jsonb result_data text raw_output } TASK_TEMPLATES { text id PK text user_id FK text template_name text task_type jsonb output_fields } ``` ### 跨Schema引用 **外键关系:** - `knowledge_bases.user_id` → `platform_schema.users.id` - `documents.user_id` → `platform_schema.users.id` - `batch_tasks.user_id` → `platform_schema.users.id` - `task_templates.user_id` → `platform_schema.users.id` **说明:** Prisma自动处理跨Schema外键,应用代码无需关心Schema前缀 --- ## 索引设计 ### 主键索引 所有表的`id`字段自动创建B-tree主键索引。 ### 外键索引 | 表名 | 索引字段 | 用途 | |------|---------|------| | knowledge_bases | user_id | 查询用户的所有知识库 | | knowledge_bases | dify_dataset_id | Dify数据同步 | | documents | kb_id | 查询知识库的所有文档 | | documents | user_id | 查询用户的所有文档 | | documents | status | 过滤文档状态 | | documents | dify_document_id | Dify数据同步 | | documents | extraction_method | 按提取方法过滤 | | batch_tasks | user_id | 查询用户的任务 | | batch_tasks | kb_id | 查询知识库的任务 | | batch_tasks | status | 过滤任务状态 | | batch_results | task_id | 查询任务的所有结果 | | batch_results | document_id | 查询文档的处理结果 | | batch_results | status | 过滤结果状态 | | task_templates | user_id | 查询用户的模板 | ### 时间索引 | 表名 | 索引字段 | 用途 | |------|---------|------| | batch_tasks | created_at | 按时间排序任务 | --- ## Phase 3功能说明 ### 批处理工作流程 ```mermaid sequenceDiagram participant User participant API participant BatchTask participant Document participant LLM participant BatchResult User->>API: 创建批处理任务 API->>BatchTask: 创建任务记录 API->>Document: 查询知识库文档列表 loop 每篇文档 BatchTask->>Document: 读取文档全文 BatchTask->>LLM: 调用LLM提取信息 LLM-->>BatchTask: 返回结构化数据 BatchTask->>BatchResult: 保存结果 BatchTask->>BatchTask: 更新进度 end BatchTask->>API: 任务完成 API-->>User: 返回结果汇总 ``` ### 批处理任务类型示例 1. **信息提取** (`extract_info`) - 提取研究方法、样本量、P值等 - 输出JSON格式的结构化数据 2. **文献摘要** (`summarize`) - 批量生成文献摘要 - 统一格式和长度 3. **文献分类** (`classify`) - 根据研究类型分类 - 标签化管理 --- ## 变更历史 ### v1.0 - 2025-11-12 - 初始版本 ✅ **变更内容:** 1. 从`public` schema迁移到`pkb_schema` 2. 5个表全部迁移: - knowledge_bases - documents - batch_tasks - batch_results - task_templates 3. 在Prisma中添加`@@schema("pkb_schema")`标签 4. 所有数据100%完整迁移 **迁移脚本:** `docs/09-架构实施/migration-scripts/004-migrate-pkb.sql` **验证状态:** ✅ 已验证,功能正常 **特殊处理:** - `batch_results.rawOutput` → `raw_output`(列名映射修正) - `task_templates.outputFields` → `output_fields`(列名映射修正) --- ## 📚 相关文档 - [Schema隔离架构设计](../../../09-架构实施/01-Schema隔离架构设计(10个).md) - [Schema迁移完成报告](../../../09-架构实施/Schema迁移完成报告.md) - [Prisma配置完成报告](../../../09-架构实施/Prisma配置完成报告.md) - [快速功能测试报告](../../../09-架构实施/快速功能测试报告.md) - [AIA数据库设计文档](../../AIA-AI智能问答/02-技术设计/01-数据库设计.md) --- **文档维护者:** AI助手 **最后更新:** 2025-11-12 **文档状态:** ✅ 已完成并验证