# Schema隔离架构设计?0个Schema? > **文档版本?* V1.0 > **制定日期?* 2025-11-09 > **实施策略?* 3个详细迁?+ 7个空Schema预留 > **架构原则?* Just-in-time设计,聚焦当前需求,架构预留扩展 --- ## 📋 目录 1. [架构概述](#架构概述) 2. [10个Schema全景](#10个schema全景) 3. [Schema依赖关系](#schema依赖关系) 4. [详细设计?个迁移Schema](#详细设计3个迁移schema) 5. [预留?个空Schema](#预留7个空schema) 6. [迁移策略](#迁移策略) 7. [现有表分配方案](#现有表分配方? 8. [外键和跨Schema引用](#外键和跨schema引用) 9. [Prisma配置策略](#prisma配置策略) --- ## 架构概述 ### 设计目标 1. **模块化隔?* - 每个业务模块独立Schema,支持独立部? 2. **数据安全** - Schema级别的权限控? 3. **扩展性强** - 新模块快速接入,只需创建新Schema 4. **渐进式实?* - 优先迁移核心3个Schema,其余按需扩展 ### 实施策略?详细+7?? ``` Week 1重点? ┌─────────────────────────────────────────────? ? 3个详细Schema(完整设?数据迁移? ? ? ?platform_schema - 1个表(users? ? ? ?aia_schema - 5个表(对话相关) ? ? ?pkb_schema - 5个表(知识库相关? ? ├─────────────────────────────────────────────? ? 7个空Schema(只创建命名空间? ? ? 📋 asl_schema - Week 3再设计表 ? ? 📋 common_schema - 需要时再创建表 ? ? 📋 dc_schema - 数据清洗模块 ? ? 📋 rvw_schema - 审稿系统(含现有表) ? ? 📋 admin_schema - 运营管理(含现有表) ? ? 📋 ssa_schema - 智能统计分析 ? ? 📋 st_schema - 统计分析工具 ? └─────────────────────────────────────────────? ``` ### 核心原则 - ?**聚焦当前** - 只详细设计和迁移现在需要的(Platform/AIA/PKB? - ?**架构预留** - 创建7个空Schema,命名空间占? - ?**Just-in-time** - ASL等模块在开发前再详细设计(避免过度设计? - ?**降低风险** - Week 1工作量从2天降?.5? --- ## 10个Schema全景 | # | Schema名称 | 中文名称 | 状?| 用?| Week 1任务 | |---|-----------|---------|------|------|-----------| | 1 | `platform_schema` | 平台基础?| ?详细设计 | 用户、权限、认?| 迁移1个表 | | 2 | `aia_schema` | AI智能问答 | ?详细设计 | 对话、项目管?| 迁移5个表 | | 3 | `pkb_schema` | 个人知识?| ?详细设计 | 知识库、文档、批处理 | 迁移5个表 | | 4 | `asl_schema` | AI智能文献 | 📋 空Schema | 文献筛?| 只创建Schema | | 5 | `common_schema` | 通用能力?| 📋 空Schema | LLM使用记录、Feature Flags | 只创建Schema | | 6 | `dc_schema` | 数据清洗 | 📋 空Schema | 数据清洗工具 | 只创建Schema | | 7 | `rvw_schema` | 审稿系统 | 📋 空Schema | 稿件审查 | 只创建Schema+迁移1?| | 8 | `admin_schema` | 运营管理 | 📋 空Schema | 管理后台、日?| 只创建Schema+迁移1?| | 9 | `ssa_schema` | 智能统计分析 | 📋 空Schema | 智能数据分析 | 只创建Schema | | 10 | `st_schema` | 统计分析工具 | 📋 空Schema | 统计工具?| 只创建Schema | --- ## Schema依赖关系 ### 层级结构 ? ``` ┌─────────────────────────────────────────────────────────────? ? L3: 业务模块? ? ? ┌─────────?┌─────────?┌─────────?┌─────────?┌────────┐│ ? ? AIA ?? PKB ?? ASL ?? RVW ??ADMIN ││ ? └────┬────?└────┬────?└────┬────?└────┬────?└────┬───┘│ ? ? ? ? ? ? ? ? └───────────┴───────────┴───────────┴───────────? ? ? ? ? ├─────────────────────────────────────────────────────────────? ? L2: 通用能力? ? ? ┌──────────────? ┌──────────────? ? ? ? Common ? ? DC/SSA/ST ? ? ? ? (通用数据) ? ? (通用工具) ? ? ? └──────┬───────? └──────────────? ? ? ? ? ? └───────────────────────────────────────────────────? ? ? ? ├─────────────────────────────────────────────────────────────? ? L1: 平台基础? ? ? ┌──────────────────────────────────────────────────────? ? ? ? Platform Schema ? ? ? ? - 用户管理 (users) ? ? ? ? - 权限控制 (RBAC) ? ? ? ? - 认证服务 (JWT/Session) ? ? ? └──────────────────────────────────────────────────────? ? └─────────────────────────────────────────────────────────────? ``` ### 引用关系说明 **核心规则:单向依赖,向下引用** 1. **所有业务模??platform_schema.users** - 所有表?`user_id` 字段引用 `platform_schema.users(id)` - 跨Schema外键(PostgreSQL支持? 2. **业务模块内部表之?* - 同Schema内的表可以相互引用(如aia_schema.conversations ?aia_schema.projects? 3. **禁止反向依赖** - platform_schema **不能**引用业务模块Schema - 业务模块之间**不应**相互引用(保持独立性) --- ## 详细设计?个迁移Schema ### 1️⃣ platform_schema(平台基础层)? **用途:** 用户管理、权限控制、认证服? **迁移表:** 1? - `users` - ?`public.users` 迁移 #### 表结构:users | 字段?| 类型 | 说明 | 索引 | |-------|------|------|------| | `id` | UUID | 主键 | PK | | `email` | VARCHAR(255) | 邮箱(唯一?| UNIQUE, INDEX | | `password` | VARCHAR(255) | 密码哈希 | - | | `name` | VARCHAR(255) | 用户?| - | | `avatar_url` | VARCHAR(500) | 头像URL | - | | `role` | VARCHAR(50) | 角色(user/admin?| INDEX | | `status` | VARCHAR(50) | 状态(active/inactive?| INDEX | | `kb_quota` | INT | 知识库配?| - | | `kb_used` | INT | 已使用配?| - | | `trial_ends_at` | TIMESTAMP | 试用结束时间 | - | | `is_trial` | BOOLEAN | 是否试用 | - | | `last_login_at` | TIMESTAMP | 最后登录时?| - | | `created_at` | TIMESTAMP | 创建时间 | INDEX | | `updated_at` | TIMESTAMP | 更新时间 | - | **SQL DDL?* ```sql CREATE SCHEMA IF NOT EXISTS platform_schema; CREATE TABLE platform_schema.users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email VARCHAR(255) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, name VARCHAR(255), avatar_url VARCHAR(500), role VARCHAR(50) NOT NULL DEFAULT 'user', status VARCHAR(50) DEFAULT 'active', kb_quota INT DEFAULT 3, kb_used INT DEFAULT 0, trial_ends_at TIMESTAMP, is_trial BOOLEAN DEFAULT true, last_login_at TIMESTAMP, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 索引 CREATE INDEX idx_users_email ON platform_schema.users(email); CREATE INDEX idx_users_role ON platform_schema.users(role); CREATE INDEX idx_users_status ON platform_schema.users(status); CREATE INDEX idx_users_created_at ON platform_schema.users(created_at); ``` --- ### 2️⃣ aia_schema(AI智能问答)⭐ **用途:** AI对话、项目管理、通用对话 **迁移表:** 5? - `projects` - ?`public.projects` 迁移 - `conversations` - ?`public.conversations` 迁移 - `messages` - ?`public.messages` 迁移 - `general_conversations` - ?`public.general_conversations` 迁移 - `general_messages` - ?`public.general_messages` 迁移 #### 表结构概? **1. projects(项目表?* | 字段?| 类型 | 说明 | 外键 | |-------|------|------|------| | `id` | UUID | 主键 | - | | `user_id` | UUID | 用户ID | ?`platform_schema.users(id)` | | `name` | VARCHAR(255) | 项目名称 | - | | `background` | TEXT | 研究背景 | - | | `research_type` | VARCHAR(50) | 研究类型 | - | | `conversation_count` | INT | 对话?| - | | `created_at` | TIMESTAMP | 创建时间 | - | | `updated_at` | TIMESTAMP | 更新时间 | - | | `deleted_at` | TIMESTAMP | 删除时间(软删除?| - | **2. conversations(对话表?* | 字段?| 类型 | 说明 | 外键 | |-------|------|------|------| | `id` | UUID | 主键 | - | | `user_id` | UUID | 用户ID | ?`platform_schema.users(id)` | | `project_id` | UUID | 项目ID | ?`aia_schema.projects(id)` | | `agent_id` | VARCHAR(100) | 智能体ID | - | | `title` | VARCHAR(255) | 对话标题 | - | | `model_name` | VARCHAR(50) | 模型名称 | - | | `message_count` | INT | 消息?| - | | `total_tokens` | INT | 总Token?| - | | `metadata` | JSONB | 元数?| - | | `created_at` | TIMESTAMP | 创建时间 | - | | `updated_at` | TIMESTAMP | 更新时间 | - | | `deleted_at` | TIMESTAMP | 删除时间 | - | **3. messages(消息表?* | 字段?| 类型 | 说明 | 外键 | |-------|------|------|------| | `id` | UUID | 主键 | - | | `conversation_id` | UUID | 对话ID | ?`aia_schema.conversations(id)` | | `role` | VARCHAR(20) | 角色(user/assistant?| - | | `content` | TEXT | 消息内容 | - | | `model` | VARCHAR(50) | 使用的模?| - | | `metadata` | JSONB | 元数?| - | | `tokens` | INT | Token?| - | | `is_pinned` | BOOLEAN | 是否置顶 | - | | `created_at` | TIMESTAMP | 创建时间 | - | **4. general_conversations(通用对话表)** | 字段?| 类型 | 说明 | 外键 | |-------|------|------|------| | `id` | UUID | 主键 | - | | `user_id` | UUID | 用户ID | ?`platform_schema.users(id)` | | `title` | VARCHAR(255) | 对话标题 | - | | `model_name` | VARCHAR(50) | 模型名称 | - | | `created_at` | TIMESTAMP | 创建时间 | - | | `updated_at` | TIMESTAMP | 更新时间 | - | | `deleted_at` | TIMESTAMP | 删除时间 | - | **5. general_messages(通用消息表)** | 字段?| 类型 | 说明 | 外键 | |-------|------|------|------| | `id` | UUID | 主键 | - | | `conversation_id` | UUID | 对话ID | ?`aia_schema.general_conversations(id)` | | `role` | VARCHAR(20) | 角色 | - | | `content` | TEXT | 消息内容 | - | | `model` | VARCHAR(50) | 使用的模?| - | | `metadata` | JSONB | 元数?| - | | `tokens` | INT | Token?| - | | `created_at` | TIMESTAMP | 创建时间 | - | **SQL DDL?* ```sql CREATE SCHEMA IF NOT EXISTS aia_schema; -- 1. projects CREATE TABLE aia_schema.projects ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL, -- 引用platform_schema.users name VARCHAR(255) NOT NULL, background TEXT DEFAULT '', research_type VARCHAR(50) DEFAULT 'observational', conversation_count INT DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, deleted_at TIMESTAMP, FOREIGN KEY (user_id) REFERENCES platform_schema.users(id) ON DELETE CASCADE ); -- 2. conversations CREATE TABLE aia_schema.conversations ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL, project_id UUID, agent_id VARCHAR(100) NOT NULL, title VARCHAR(255) NOT NULL, model_name VARCHAR(50) DEFAULT 'deepseek-v3', message_count INT DEFAULT 0, total_tokens INT DEFAULT 0, metadata JSONB, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, deleted_at TIMESTAMP, FOREIGN KEY (user_id) REFERENCES platform_schema.users(id) ON DELETE CASCADE, FOREIGN KEY (project_id) REFERENCES aia_schema.projects(id) ON DELETE CASCADE ); -- 3. messages CREATE TABLE aia_schema.messages ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), conversation_id UUID NOT NULL, role VARCHAR(20) NOT NULL, content TEXT NOT NULL, model VARCHAR(50), metadata JSONB, tokens INT, is_pinned BOOLEAN DEFAULT false, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (conversation_id) REFERENCES aia_schema.conversations(id) ON DELETE CASCADE ); -- 4. general_conversations CREATE TABLE aia_schema.general_conversations ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL, title VARCHAR(255) NOT NULL, model_name VARCHAR(50), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, deleted_at TIMESTAMP, FOREIGN KEY (user_id) REFERENCES platform_schema.users(id) ON DELETE CASCADE ); -- 5. general_messages CREATE TABLE aia_schema.general_messages ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), conversation_id UUID NOT NULL, role VARCHAR(20) NOT NULL, content TEXT NOT NULL, model VARCHAR(50), metadata JSONB, tokens INT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (conversation_id) REFERENCES aia_schema.general_conversations(id) ON DELETE CASCADE ); -- 索引 CREATE INDEX idx_aia_projects_user_id ON aia_schema.projects(user_id); CREATE INDEX idx_aia_projects_created_at ON aia_schema.projects(created_at); CREATE INDEX idx_aia_conversations_user_id ON aia_schema.conversations(user_id); CREATE INDEX idx_aia_conversations_project_id ON aia_schema.conversations(project_id); CREATE INDEX idx_aia_messages_conversation_id ON aia_schema.messages(conversation_id); CREATE INDEX idx_aia_general_conversations_user_id ON aia_schema.general_conversations(user_id); CREATE INDEX idx_aia_general_messages_conversation_id ON aia_schema.general_messages(conversation_id); ``` --- ### 3️⃣ pkb_schema(个人知识库)⭐ **用途:** 知识库管理、文档管理、批处理任务 **迁移表:** 5? - `knowledge_bases` - ?`public.knowledge_bases` 迁移 - `documents` - ?`public.documents` 迁移 - `batch_tasks` - ?`public.batch_tasks` 迁移 - `batch_results` - ?`public.batch_results` 迁移 - `task_templates` - ?`public.task_templates` 迁移 #### 表结构概? **1. knowledge_bases(知识库表)** | 字段?| 类型 | 说明 | 外键 | |-------|------|------|------| | `id` | UUID | 主键 | - | | `user_id` | UUID | 用户ID | ?`platform_schema.users(id)` | | `name` | VARCHAR(255) | 知识库名?| - | | `description` | TEXT | 描述 | - | | `dify_dataset_id` | VARCHAR(255) | Dify知识库ID | - | | `file_count` | INT | 文件?| - | | `total_size_bytes` | BIGINT | 总大小(字节?| - | | `created_at` | TIMESTAMP | 创建时间 | - | | `updated_at` | TIMESTAMP | 更新时间 | - | **2. documents(文档表?* ?包含Phase 2全文阅读字段 | 字段?| 类型 | 说明 | 外键 | |-------|------|------|------| | `id` | UUID | 主键 | - | | `kb_id` | UUID | 知识库ID | ?`pkb_schema.knowledge_bases(id)` | | `user_id` | UUID | 用户ID | ?`platform_schema.users(id)` | | `filename` | VARCHAR(255) | 文件?| - | | `file_type` | VARCHAR(50) | 文件类型 | - | | `file_size_bytes` | BIGINT | 文件大小 | - | | `file_url` | TEXT | 文件URL | - | | `dify_document_id` | VARCHAR(255) | Dify文档ID | - | | `status` | VARCHAR(50) | 状?| - | | `progress` | INT | 进度?-100?| - | | `error_message` | TEXT | 错误信息 | - | | `segments_count` | INT | 分段?| - | | `tokens_count` | INT | Token?| - | | **Phase 2字段?* | | | | | `extraction_method` | VARCHAR(50) | 提取方法(pymupdf/nougat/mammoth/direct?| - | | `extraction_quality` | FLOAT | 提取质量?-1?| - | | `char_count` | INT | 字符?| - | | `language` | VARCHAR(20) | 语言(chinese/english?| - | | `extracted_text` | TEXT | 提取的文?| - | | `uploaded_at` | TIMESTAMP | 上传时间 | - | | `processed_at` | TIMESTAMP | 处理完成时间 | - | **3. batch_tasks(批处理任务表)** | 字段?| 类型 | 说明 | 外键 | |-------|------|------|------| | `id` | UUID | 主键 | - | | `user_id` | UUID | 用户ID | ?`platform_schema.users(id)` | | `kb_id` | UUID | 知识库ID | ?`pkb_schema.knowledge_bases(id)` | | `name` | VARCHAR(255) | 任务名称 | - | | `template_type` | VARCHAR(50) | 模板类型 | - | | `template_id` | VARCHAR(100) | 模板ID | - | | `prompt` | TEXT | 提示?| - | | `status` | VARCHAR(50) | 状?| - | | `total_documents` | INT | 总文档数 | - | | `completed_count` | INT | 完成?| - | | `failed_count` | INT | 失败?| - | | `model_type` | VARCHAR(50) | 模型类型 | - | | `concurrency` | INT | 并发?| - | | `started_at` | TIMESTAMP | 开始时?| - | | `completed_at` | TIMESTAMP | 完成时间 | - | | `duration_seconds` | INT | 执行时长(秒?| - | | `created_at` | TIMESTAMP | 创建时间 | - | | `updated_at` | TIMESTAMP | 更新时间 | - | **4. batch_results(批处理结果表)** | 字段?| 类型 | 说明 | 外键 | |-------|------|------|------| | `id` | UUID | 主键 | - | | `task_id` | UUID | 任务ID | ?`pkb_schema.batch_tasks(id)` | | `document_id` | UUID | 文档ID | ?`pkb_schema.documents(id)` | | `status` | VARCHAR(50) | 状?| - | | `data` | JSONB | 结构化数?| - | | `raw_output` | TEXT | 原始输出 | - | | `error_message` | TEXT | 错误信息 | - | | `processing_time_ms` | INT | 处理时长(毫秒) | - | | `tokens_used` | INT | Token使用?| - | | `created_at` | TIMESTAMP | 创建时间 | - | **5. task_templates(任务模板表?* | 字段?| 类型 | 说明 | 外键 | |-------|------|------|------| | `id` | UUID | 主键 | - | | `user_id` | UUID | 用户ID | ?`platform_schema.users(id)` | | `name` | VARCHAR(255) | 模板名称 | - | | `description` | TEXT | 描述 | - | | `prompt` | TEXT | 提示?| - | | `output_fields` | JSONB | 输出字段定义 | - | | `is_public` | BOOLEAN | 是否公开 | - | | `created_at` | TIMESTAMP | 创建时间 | - | | `updated_at` | TIMESTAMP | 更新时间 | - | **SQL DDL?* ```sql CREATE SCHEMA IF NOT EXISTS pkb_schema; -- 1. knowledge_bases CREATE TABLE pkb_schema.knowledge_bases ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL, name VARCHAR(255) NOT NULL, description TEXT, dify_dataset_id VARCHAR(255) NOT NULL, file_count INT DEFAULT 0, total_size_bytes BIGINT DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES platform_schema.users(id) ON DELETE CASCADE ); -- 2. documents (包含Phase 2字段) CREATE TABLE pkb_schema.documents ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), kb_id UUID NOT NULL, user_id UUID NOT NULL, filename VARCHAR(255) NOT NULL, file_type VARCHAR(50) NOT NULL, file_size_bytes BIGINT NOT NULL, file_url TEXT NOT NULL, dify_document_id VARCHAR(255) NOT NULL, status VARCHAR(50) DEFAULT 'uploading', progress INT DEFAULT 0, error_message TEXT, segments_count INT, tokens_count INT, -- Phase 2字段 extraction_method VARCHAR(50), extraction_quality FLOAT, char_count INT, language VARCHAR(20), extracted_text TEXT, uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, processed_at TIMESTAMP, FOREIGN KEY (kb_id) REFERENCES pkb_schema.knowledge_bases(id) ON DELETE CASCADE, FOREIGN KEY (user_id) REFERENCES platform_schema.users(id) ON DELETE CASCADE ); -- 3. batch_tasks CREATE TABLE pkb_schema.batch_tasks ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL, kb_id UUID NOT NULL, name VARCHAR(255) NOT NULL, template_type VARCHAR(50) NOT NULL, template_id VARCHAR(100), prompt TEXT NOT NULL, status VARCHAR(50) NOT NULL, total_documents INT NOT NULL, completed_count INT DEFAULT 0, failed_count INT DEFAULT 0, model_type VARCHAR(50) NOT NULL, concurrency INT DEFAULT 3, started_at TIMESTAMP, completed_at TIMESTAMP, duration_seconds INT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES platform_schema.users(id) ON DELETE CASCADE, FOREIGN KEY (kb_id) REFERENCES pkb_schema.knowledge_bases(id) ON DELETE CASCADE ); -- 4. batch_results CREATE TABLE pkb_schema.batch_results ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), task_id UUID NOT NULL, document_id UUID NOT NULL, status VARCHAR(50) NOT NULL, data JSONB, raw_output TEXT, error_message TEXT, processing_time_ms INT, tokens_used INT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (task_id) REFERENCES pkb_schema.batch_tasks(id) ON DELETE CASCADE, FOREIGN KEY (document_id) REFERENCES pkb_schema.documents(id) ON DELETE CASCADE ); -- 5. task_templates CREATE TABLE pkb_schema.task_templates ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL, name VARCHAR(255) NOT NULL, description TEXT, prompt TEXT NOT NULL, output_fields JSONB NOT NULL, is_public BOOLEAN DEFAULT false, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES platform_schema.users(id) ON DELETE CASCADE ); -- 索引 CREATE INDEX idx_pkb_knowledge_bases_user_id ON pkb_schema.knowledge_bases(user_id); CREATE INDEX idx_pkb_documents_kb_id ON pkb_schema.documents(kb_id); CREATE INDEX idx_pkb_documents_user_id ON pkb_schema.documents(user_id); CREATE INDEX idx_pkb_documents_status ON pkb_schema.documents(status); CREATE INDEX idx_pkb_batch_tasks_user_id ON pkb_schema.batch_tasks(user_id); CREATE INDEX idx_pkb_batch_tasks_kb_id ON pkb_schema.batch_tasks(kb_id); CREATE INDEX idx_pkb_batch_results_task_id ON pkb_schema.batch_results(task_id); CREATE INDEX idx_pkb_task_templates_user_id ON pkb_schema.task_templates(user_id); ``` --- ## 预留?个空Schema ### 创建策略 ? **只执?`CREATE SCHEMA`,不创建表结?* ```sql -- 4. AI智能文献(Week 3再详细设计) CREATE SCHEMA IF NOT EXISTS asl_schema; COMMENT ON SCHEMA asl_schema IS 'AI智能文献筛选模?- Week 3开发前再设计表结构'; -- 5. 通用能力层(需要时再创建表? CREATE SCHEMA IF NOT EXISTS common_schema; COMMENT ON SCHEMA common_schema IS '通用能力?- LLM使用记录、Feature Flags?; -- 6. 数据清洗模块 CREATE SCHEMA IF NOT EXISTS dc_schema; COMMENT ON SCHEMA dc_schema IS '数据清洗工具模块'; -- 7. 审稿系统(包含现有review_tasks表) CREATE SCHEMA IF NOT EXISTS rvw_schema; COMMENT ON SCHEMA rvw_schema IS '稿件审查系统模块'; -- 8. 运营管理(包含现有admin_logs表) CREATE SCHEMA IF NOT EXISTS admin_schema; COMMENT ON SCHEMA admin_schema IS '运营管理后台模块'; -- 9. 智能统计分析 CREATE SCHEMA IF NOT EXISTS ssa_schema; COMMENT ON SCHEMA ssa_schema IS '智能统计分析模块'; -- 10. 统计分析工具 CREATE SCHEMA IF NOT EXISTS st_schema; COMMENT ON SCHEMA st_schema IS '统计分析工具集模?; ``` ### 各空Schema的用? | Schema | 用途说?| 何时设计表结?| |--------|---------|--------------| | `asl_schema` | AI智能文献筛?| **Week 3 Day 1** - ASL开发前详细设计 | | `common_schema` | 通用能力(LLM使用记录、Feature Flags?| 需要时再设?| | `dc_schema` | 数据清洗工具 | Week 5+或按需 | | `rvw_schema` | 稿件审查系统 | Week 1迁移review_tasks,其他表按需 | | `admin_schema` | 运营管理后台 | Week 1迁移admin_logs,其他表按需 | | `ssa_schema` | 智能统计分析 | Week 5+或按需 | | `st_schema` | 统计分析工具?| Week 5+或按需 | --- ## 迁移策略 ### 迁移优先? | 优先?| Schema | 表数?| 数据量估?| 迁移时间 | |-------|--------|--------|-----------|---------| | **P0** | platform_schema | 1 | ~10?| 15分钟 | | **P0** | aia_schema | 5 | ~500?| 30分钟 | | **P0** | pkb_schema | 5 | ~100?| 30分钟 | | **P1** | rvw_schema | 1(review_tasks?| ~20?| 10分钟 | | **P1** | admin_schema | 1(admin_logs?| ~50?| 10分钟 | ### 迁移步骤?步法? **Step 1:创?0个Schema?分钟?* ```sql -- 执行脚本?01-create-all-10-schemas.sql -- 创建10个Schema?详细+7空) ``` **Step 2:创建表结构?0分钟?* ```sql -- 执行脚本? -- 002-migrate-platform.sql - 创建platform_schema.users -- 003-migrate-aia.sql - 创建aia_schema?个表 -- 004-migrate-pkb.sql - 创建pkb_schema?个表 ``` **Step 3:迁移数据(30分钟?* ```sql -- 使用 INSERT INTO ... SELECT FROM 方式 -- 保持ID不变,确保引用关系不? ``` **Step 4:验证(30分钟?* ```sql -- 执行脚本?05-validate-all.sql -- 验证数据完整性、外键约? ``` ### 数据迁移示例 **platform_schema.users?* ```sql INSERT INTO platform_schema.users SELECT * FROM public.users; ``` **aia_schema.projects?* ```sql INSERT INTO aia_schema.projects SELECT * FROM public.projects; ``` **验证?* ```sql -- 验证数据? SELECT 'users' AS table_name, COUNT(*) FROM platform_schema.users UNION ALL SELECT 'projects', COUNT(*) FROM aia_schema.projects UNION ALL SELECT 'conversations', COUNT(*) FROM aia_schema.conversations; ``` --- ## 现有表分配方? ### 当前public schema中的13个表 | # | 表名 | 目标Schema | 迁移时机 | 说明 | |---|------|-----------|---------|------| | 1 | `users` | `platform_schema` | Week 1 | ?P0核心?| | 2 | `projects` | `aia_schema` | Week 1 | ?P0核心?| | 3 | `conversations` | `aia_schema` | Week 1 | ?P0核心?| | 4 | `messages` | `aia_schema` | Week 1 | ?P0核心?| | 5 | `general_conversations` | `aia_schema` | Week 1 | ?P0核心?| | 6 | `general_messages` | `aia_schema` | Week 1 | ?P0核心?| | 7 | `knowledge_bases` | `pkb_schema` | Week 1 | ?P0核心?| | 8 | `documents` | `pkb_schema` | Week 1 | ?P0核心?| | 9 | `batch_tasks` | `pkb_schema` | Week 1 | ?P0核心?| | 10 | `batch_results` | `pkb_schema` | Week 1 | ?P0核心?| | 11 | `task_templates` | `pkb_schema` | Week 1 | ?P0核心?| | 12 | `review_tasks` | `rvw_schema` | Week 1或保?| 📋 P1可?| | 13 | `admin_logs` | `admin_schema` | Week 1或保?| 📋 P1可?| **说明?* - **优先迁移11个表**?个详细Schema(Platform/AIA/PKB? - **review_tasks和admin_logs**可以? - 选项A:Week 1一并迁移到对应的空Schema(简单) - 选项B:暂时保留在public,需要时再迁移(务实? - **建议选项A**:一次性迁移完成,避免残留 --- ## 外键和跨Schema引用 ### PostgreSQL跨Schema外键支持 ? PostgreSQL **完全支持**跨Schema的外键约束: ```sql -- 示例:aia_schema.projects 引用 platform_schema.users CREATE TABLE aia_schema.projects ( id UUID PRIMARY KEY, user_id UUID NOT NULL, name VARCHAR(255), FOREIGN KEY (user_id) REFERENCES platform_schema.users(id) ON DELETE CASCADE ); ``` ### 引用规则 **?允许的引用:** - 业务模块Schema ?`platform_schema.users(id)` - 同Schema内的表相互引? **?禁止的引用:** - `platform_schema` ?业务模块Schema(反向依赖) - 业务模块Schema之间相互引用(保持独立性) ### 数据一致性保? 1. **CASCADE删除** - 用户删除时,关联数据自动删除 2. **外键索引** - 所有外键字段创建索? 3. **事务保护** - 迁移在事务中执行,全成功或全失败 --- ## Prisma配置策略 ### Week 1的Prisma配置 **在schema.prisma中:** 1. **启用multiSchema预览特?* ```prisma generator client { provider = "prisma-client-js" previewFeatures = ["multiSchema"] } datasource db { provider = "postgresql" url = env("DATABASE_URL") schemas = [ "platform_schema", "aia_schema", "pkb_schema", "asl_schema", // 空Schema,预? "common_schema", // 空Schema,预? "dc_schema", // 空Schema,预? "rvw_schema", // 空Schema,预? "admin_schema", // 空Schema,预? "ssa_schema", // 空Schema,预? "st_schema" // 空Schema,预? ] } ``` 2. **只为3个详细Schema定义模型** ```prisma // Platform Schema model User { // ... @@map("users") @@schema("platform_schema") } // AIA Schema model Project { // ... @@map("projects") @@schema("aia_schema") } // PKB Schema model KnowledgeBase { // ... @@map("knowledge_bases") @@schema("pkb_schema") } ``` 3. **7个空Schema不定义模?* - 只在schemas列表中声? - Week 3再为asl_schema添加模型 - 其他按需添加 **详细Prisma配置参考:** - 见V2.2完整版文档的 Day 4 Prisma配置示例 --- ## 📊 工作量估? | 任务 | 预计时间 | 说明 | |------|---------|------| | **Day 1-2上午:架构规划与设计** | 8小时 | 本文?+ 3个Schema SQL | | **Day 2下午:编写迁移脚?* | 1.5小时 | 5个SQL脚本 | | **Day 3上午:执行迁?* | 2-3小时 | 备份 + 迁移 + 验证 | | **Day 3下午:功能测?* | 2小时 | 测试现有功能 | | **Day 4:Prisma配置** | 3小时 | 更新schema.prisma | | **总计** | **?6-17小时?天)** | ?| --- ## 🎯 成功标准 Week 1结束时,应达到: - [ ] ?10个Schema全部创建成功 - [ ] ?3个详细Schema?1个表数据100%迁移 - [ ] ?所有外键约束正确建? - [ ] ?现有功能(AIA、PKB)正常运? - [ ] ?Prisma Client生成成功 - [ ] ?7个空Schema验证通过(可查询、可创建表) --- ## 📝 后续步骤 ### Week 2 - 前端统一架构 - 后端代码分层 - 适配新的Schema结构 ### Week 3 - **详细设计asl_schema** ? - 为asl_schema创建表结? - 开发ASL核心功能 ### Week 5+ - 按需为其他空Schema设计表结? - LLM网关统一 - 其他模块开? --- **文档制定?* AI助手 **审核?* 待审? **最后更新:** 2025-11-09 **核心策略:聚焦当?+ 架构预留 + Just-in-time设计** ⭐⭐?