# 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  
**文档状态：** ✅ 已完成并验证






