# 数据库设计文档 本文档描述 RAG 知识库系统中所有数据库的结构和用途。 > **架构更新**:v6.0 重构后,数据库从 6 个独立文件合并为 3 个,通过 `data/db.py` 统一管理。 --- ## 数据库架构概览 ### 统一数据访问层 所有数据库通过 `data/db.py` 中的统一接口访问: ```python from data.db import get_connection, init_databases # 初始化数据库(首次运行时调用) init_databases() # 使用连接 with get_connection("core") as conn: cursor = conn.cursor() cursor.execute("SELECT * FROM sessions WHERE user_id = ?", (user_id,)) rows = cursor.fetchall() ``` ### 数据库文件列表 | 数据库 | 文件名 | 主要功能 | 所属模块 | |--------|--------|----------|----------| | core | `rag_core.db` | 会话管理、审计日志、用户反馈、FAQ | services/ | | knowledge | `knowledge.db` | 知识库同步、文档哈希、纲要缓存、版本管理 | knowledge/ | | exam | `exam.db` | 题目存储、试卷管理、批阅记录、分析报告 | exam_pkg/ | --- ## 1. rag_core.db - 核心交互数据库 **所属模块**:`services/session.py`、`services/audit.py`、`services/feedback.py` ### 1.1 sessions 表 - 会话表 | 字段 | 类型 | 说明 | |------|------|------| | `session_id` | TEXT | 会话ID(UUID),主键 | | `user_id` | TEXT | 所属用户ID | | `created_at` | TIMESTAMP | 创建时间 | | `last_active` | TIMESTAMP | 最后活跃时间 | | `metadata` | TEXT | 元数据(JSON格式) | **索引**: - `idx_sessions_user(user_id)` **作用**:实现多用户会话隔离,支持多轮对话记忆。 ### 1.2 messages 表 - 消息历史表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `session_id` | TEXT | 关联会话ID | | `role` | TEXT | 角色:user / assistant | | `content` | TEXT | 消息内容 | | `created_at` | TIMESTAMP | 创建时间 | **索引**: - `idx_messages_session(session_id, created_at)` **外键**: - `session_id` → sessions(session_id) ON DELETE CASCADE ### 1.3 audit_logs 表 - 审计日志表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `user_id` | TEXT | 用户ID | | `username` | TEXT | 用户名 | | `action` | TEXT | 操作类型(chat/rag/search/upload_document等) | | `query` | TEXT | 用户查询内容 | | `result_summary` | TEXT | 结果摘要 | | `sources` | TEXT | 来源文档(JSON数组) | | `role` | TEXT | 用户角色 | | `department` | TEXT | 用户部门 | | `ip_address` | TEXT | 客户端IP | | `duration_ms` | INTEGER | 处理耗时(毫秒) | | `created_at` | TIMESTAMP | 创建时间 | **索引**: - `idx_audit_user(user_id, created_at)` - `idx_audit_action(action, created_at)` - `idx_audit_created(created_at)` **作用**:记录所有用户操作,用于安全审计和行为分析。 ### 1.4 feedbacks 表 - 反馈表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `session_id` | TEXT | 会话ID | | `query` | TEXT | 用户问题 | | `answer` | TEXT | 系统回答 | | `sources` | TEXT | 来源文档(JSON) | | `rating` | INTEGER | 评分:1=赞,-1=踩 | | `reason` | TEXT | 点踩原因 | | `user_id` | TEXT | 用户ID | | `created_at` | TIMESTAMP | 创建时间 | **索引**: - `idx_feedback_session(session_id)` - `idx_feedback_rating(rating)` - `idx_feedback_created(created_at)` ### 1.5 faqs 表 - FAQ表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `question` | TEXT | 问题 | | `answer` | TEXT | 答案 | | `source_documents` | TEXT | 来源文档(JSON数组) | | `frequency` | INTEGER | 出现频次 | | `avg_rating` | REAL | 平均评分 | | `status` | TEXT | 状态:draft / approved / disabled | | `created_at` | TIMESTAMP | 创建时间 | | `updated_at` | TIMESTAMP | 更新时间 | **索引**: - `idx_faq_status(status)` ### 1.6 faq_suggestions 表 - FAQ建议表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `query` | TEXT | 用户问题 | | `answer` | TEXT | 系统回答 | | `frequency` | INTEGER | 出现频次 | | `avg_rating` | REAL | 平均评分 | | `status` | TEXT | 状态:pending / approved / rejected | | `created_at` | TIMESTAMP | 创建时间 | **作用**:高频优质问题自动建议沉淀为FAQ,管理员审核后生效。 ### 1.7 quality_reports 表 - 质量报告表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `report_type` | TEXT | 报告类型:weekly / monthly | | `start_date` | DATE | 统计开始日期 | | `end_date` | DATE | 统计结束日期 | | `total_queries` | INTEGER | 总查询数 | | `total_feedback` | INTEGER | 总反馈数 | | `positive_count` | INTEGER | 正面反馈数 | | `negative_count` | INTEGER | 负面反馈数 | | `avg_rating` | REAL | 平均评分 | | `satisfaction_rate` | REAL | 满意度 | | `high_freq_queries` | TEXT | 高频问题(JSON) | | `low_rating_queries` | TEXT | 低分问题(JSON) | | `improvement_suggestions` | TEXT | 改进建议(JSON) | | `created_at` | TIMESTAMP | 创建时间 | --- ## 2. knowledge.db - 知识管理数据库 **所属模块**:`knowledge/sync.py`、`services/outline.py` ### 2.1 document_hashes 表 - 文档哈希表 | 字段 | 类型 | 说明 | |------|------|------| | `document_id` | TEXT | 文档ID(相对路径),主键 | | `document_name` | TEXT | 文件名 | | `content_hash` | TEXT | 文档内容MD5哈希 | | `file_size` | INTEGER | 文件大小(字节) | | `last_modified` | TIMESTAMP | 最后修改时间 | | `created_at` | TIMESTAMP | 创建时间 | | `updated_at` | TIMESTAMP | 更新时间 | **作用**:记录每个文档的当前状态,用于检测变更。 ### 2.2 change_logs 表 - 变更日志表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `document_id` | TEXT | 文档ID | | `document_name` | TEXT | 文件名 | | `change_type` | TEXT | 变更类型:added / modified / deleted | | `old_hash` | TEXT | 变更前哈希 | | `new_hash` | TEXT | 变更后哈希 | | `change_time` | TIMESTAMP | 变更时间 | | `processed` | INTEGER | 是否已处理(0/1) | | `error_message` | TEXT | 错误信息 | | `created_at` | TIMESTAMP | 创建时间 | **索引**: - `idx_change_logs_time(change_time)` - `idx_change_logs_processed(processed)` ### 2.3 subscriptions 表 - 用户订阅表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `user_id` | TEXT | 用户ID | | `document_id` | TEXT | 订阅的文档ID(NULL表示订阅全部) | | `document_name` | TEXT | 文档名称 | | `created_at` | TIMESTAMP | 订阅时间 | **唯一约束**:`(user_id, document_id)` **索引**: - `idx_subscriptions_user(user_id)` ### 2.4 notifications 表 - 通知记录表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `user_id` | TEXT | 用户ID | | `document_id` | TEXT | 文档ID | | `document_name` | TEXT | 文档名称 | | `change_type` | TEXT | 变更类型 | | `message` | TEXT | 通知消息 | | `read` | INTEGER | 是否已读(0/1) | | `created_at` | TIMESTAMP | 创建时间 | **索引**: - `idx_notifications_user(user_id)` - `idx_notifications_read(read)` ### 2.5 sync_status 表 - 同步状态表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `sync_type` | TEXT | 同步类型(incremental/full) | | `status` | TEXT | 状态:idle / running / completed / failed | | `start_time` | TIMESTAMP | 开始时间 | | `end_time` | TIMESTAMP | 结束时间 | | `documents_processed` | INTEGER | 处理文档数 | | `documents_added` | INTEGER | 新增文档数 | | `documents_modified` | INTEGER | 修改文档数 | | `documents_deleted` | INTEGER | 删除文档数 | | `error_message` | TEXT | 错误信息 | | `created_at` | TIMESTAMP | 创建时间 | ### 2.6 outline_cache 表 - 纲要缓存表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `document_id` | TEXT | 文档ID,唯一 | | `document_name` | TEXT | 文档名称 | | `total_pages` | INTEGER | 总页数 | | `content_hash` | TEXT | 文档内容哈希 | | `outline_json` | TEXT | 纲要结构(JSON) | | `generated_at` | TIMESTAMP | 生成时间 | **索引**: - `idx_outline_doc(document_id)` ### 2.7 document_vectors 表 - 文档向量缓存表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `document_id` | TEXT | 文档ID,唯一 | | `document_name` | TEXT | 文档名称 | | `vector_hash` | TEXT | 向量哈希 | | `vector_json` | TEXT | 向量数据(JSON) | | `tags_json` | TEXT | 标签(JSON) | | `updated_at` | TIMESTAMP | 更新时间 | **索引**: - `idx_vector_doc(document_id)` ### 2.8 recommendation_cache 表 - 推荐缓存表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `document_id` | TEXT | 文档ID | | `recommendations_json` | TEXT | 推荐结果(JSON) | | `generated_at` | TIMESTAMP | 生成时间 | ### 2.9 document_versions 表 - 文档版本表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `document_id` | TEXT | 文档ID | | `collection` | TEXT | 所属向量库 | | `version` | TEXT | 版本号,默认 'v1' | | `content_hash` | TEXT | 内容哈希 | | `status` | TEXT | 状态:active / deprecated | | `effective_date` | DATE | 生效日期 | | `expiry_date` | DATE | 失效日期 | | `deprecated_date` | DATETIME | 废止日期 | | `deprecated_reason` | TEXT | 废止原因 | | `deprecated_by` | TEXT | 废止操作人 | | `change_summary` | TEXT | 变更摘要 | | `changed_sections` | TEXT | 变更章节(JSON) | | `supersedes` | TEXT | 取代的版本 | | `chunk_count` | INTEGER | 片段数量 | | `created_at` | TIMESTAMP | 创建时间 | | `created_by` | TEXT | 创建人 | **唯一约束**:`(document_id, collection, version)` ### 2.10 version_change_logs 表 - 版本变更日志表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `document_id` | TEXT | 文档ID | | `collection` | TEXT | 所属向量库 | | `old_version` | TEXT | 旧版本 | | `new_version` | TEXT | 新版本 | | `old_status` | TEXT | 旧状态 | | `new_status` | TEXT | 新状态 | | `change_type` | TEXT | 变更类型 | | `reason` | TEXT | 原因 | | `changed_by` | TEXT | 操作人 | | `created_at` | TIMESTAMP | 创建时间 | --- ## 3. exam.db - 出题系统数据库 **所属模块**:`exam_pkg/manager.py`、`exam_pkg/local_db.py`、`exam_pkg/analysis.py` ### 3.1 questions 表 - 题目表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | TEXT | 题目ID(UUID),主键 | | `question_type` | TEXT | 题型:choice / blank / short_answer | | `content` | TEXT | 题干内容 | | `options` | TEXT | 选择题选项(JSON数组) | | `correct_answer` | TEXT | 正确答案 | | `analysis` | TEXT | 解析 | | `knowledge_points` | TEXT | 知识点(JSON数组) | | `difficulty` | INTEGER | 难度(1-5) | | `score` | INTEGER | 分值 | | `source_file` | TEXT | 来源文件路径 | | `source_collection` | TEXT | 来源向量库 | | `source_snippet` | TEXT | 来源知识片段 | | `source_hash` | TEXT | 文件哈希 | | `status` | TEXT | 状态:approved | | `created_at` | TIMESTAMP | 创建时间 | | `created_by` | TEXT | 创建人 | | `updated_at` | TIMESTAMP | 更新时间 | **索引**: - `idx_questions_source(source_file)` ### 3.2 exams 表 - 试卷表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | TEXT | 试卷ID,主键 | | `name` | TEXT | 试卷名称 | | `description` | TEXT | 描述 | | `total_score` | INTEGER | 总分 | | `total_count` | INTEGER | 题目总数 | | `duration` | INTEGER | 考试时长(分钟) | | `status` | TEXT | 状态:published | | `created_at` | TIMESTAMP | 创建时间 | | `created_by` | TEXT | 创建人 | ### 3.3 exam_questions 表 - 试卷题目关联表 | 字段 | 类型 | 说明 | |------|------|------| | `exam_id` | TEXT | 试卷ID | | `question_id` | TEXT | 题目ID | | `question_order` | INTEGER | 题目顺序 | **主键**:`(exam_id, question_id)` **外键**: - `exam_id` → exams(id) ON DELETE CASCADE - `question_id` → questions(id) ON DELETE CASCADE ### 3.4 student_answers 表 - 学生答卷表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | TEXT | 主键 | | `exam_id` | TEXT | 试卷ID | | `student_id` | TEXT | 学生ID | | `question_id` | TEXT | 题目ID | | `question_type` | TEXT | 题型 | | `student_answer` | TEXT | 学生答案 | | `score` | REAL | 得分 | | `max_score` | INTEGER | 满分 | | `feedback` | TEXT | 反馈 | | `score_details` | TEXT | 评分详情(JSON) | | `submitted_at` | TIMESTAMP | 提交时间 | | `graded_at` | TIMESTAMP | 批阅时间 | **索引**: - `idx_student_answers_exam(exam_id, student_id)` ### 3.5 grade_reports 表 - 批阅报告表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | TEXT | 主键 | | `exam_id` | TEXT | 试卷ID | | `student_id` | TEXT | 学生ID | | `total_score` | REAL | 总得分 | | `max_score` | REAL | 满分 | | `score_rate` | REAL | 得分率 | | `analysis` | TEXT | 分析(JSON) | | `graded_at` | TIMESTAMP | 批阅时间 | ### 3.6 question_document_links 表 - 题目-制度关联表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `question_id` | TEXT | 题目ID | | `question_type` | TEXT | 题型 | | `exam_id` | TEXT | 试卷ID | | `document_id` | TEXT | 制度文档ID | | `document_name` | TEXT | 制度文档名称 | | `chapter` | TEXT | 章节 | | `key_points` | TEXT | 关键知识点(JSON) | | `relevance_score` | REAL | 相关度分数 | | `created_at` | TIMESTAMP | 创建时间 | **索引**: - `idx_qdl_question(question_id)` - `idx_qdl_document(document_id)` ### 3.7 knowledge_points 表 - 知识点表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `name` | TEXT | 知识点名称,唯一 | | `category` | TEXT | 分类 | | `description` | TEXT | 描述 | | `parent_id` | INTEGER | 父知识点ID | | `created_at` | TIMESTAMP | 创建时间 | **外键**: - `parent_id` → knowledge_points(id) ### 3.8 question_knowledge_links 表 - 题目-知识点关联表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `question_id` | TEXT | 题目ID | | `question_type` | TEXT | 题型 | | `exam_id` | TEXT | 试卷ID | | `knowledge_point_id` | INTEGER | 知识点ID | | `knowledge_point_name` | TEXT | 知识点名称 | | `weight` | REAL | 权重 | | `created_at` | TIMESTAMP | 创建时间 | **索引**: - `idx_qkl_question(question_id)` - `idx_qkl_knowledge(knowledge_point_id)` ### 3.9 question_status 表 - 题目状态表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `question_id` | TEXT | 题目ID,唯一 | | `question_type` | TEXT | 题型 | | `exam_id` | TEXT | 试卷ID | | `status` | TEXT | 状态 | | `affected_by` | TEXT | 影响来源 | | `affect_reason` | TEXT | 影响原因 | | `updated_at` | TIMESTAMP | 更新时间 | **索引**: - `idx_qs_status(status)` ### 3.10 exam_analysis_reports 表 - 整卷分析报告表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `report_id` | TEXT | 报告ID,唯一 | | `exam_id` | TEXT | 试卷ID | | `exam_name` | TEXT | 试卷名称 | | `student_id` | TEXT | 学生ID | | `total_score` | REAL | 总得分 | | `max_score` | REAL | 满分 | | `score_rate` | REAL | 得分率 | | `type_scores` | TEXT | 各题型得分(JSON) | | `knowledge_analysis` | TEXT | 知识点分析(JSON) | | `weak_points` | TEXT | 薄弱知识点(JSON) | | `strong_points` | TEXT | 优势知识点(JSON) | | `ai_comment` | TEXT | AI评语 | | `study_suggestions` | TEXT | 学习建议(JSON) | | `created_at` | TIMESTAMP | 创建时间 | ### 3.11 question_suggestions 表 - 新题建议表 | 字段 | 类型 | 说明 | |------|------|------| | `id` | INTEGER | 自增主键 | | `document_id` | TEXT | 文档ID | | `suggestion` | TEXT | 建议内容 | | `status` | TEXT | 状态:pending | | `created_at` | TIMESTAMP | 创建时间 | --- ## 4. ChromaDB 向量数据库 **所属模块**:`knowledge/manager.py` ### 4.1 向量库结构 ``` knowledge/vector_store/chroma/ ├── chroma.sqlite3 # ChromaDB 主数据库 ├── kb_metadata.json # 向量库元数据 ├── public_kb/ # 公开知识库 ├── dept_finance/ # 财务部知识库 ├── dept_hr/ # 人事部知识库 ├── dept_tech/ # 技术部知识库 └── ... # 其他部门向量库 ``` ### 4.2 权限矩阵 | 角色 | 可访问向量库 | 可上传 | 可删除 | 可同步 | |------|------------|--------|--------|--------| | admin | 全部 | 全部 | 全部 | 全部 | | manager | public_kb + 本部门 | 本部门 | 本部门 | 本部门 | | user | public_kb + 本部门 | - | - | - | ### 4.3 文档元数据结构 每个文档 chunk 的元数据: | 字段 | 类型 | 说明 | |------|------|------| | `source` | TEXT | 文档来源文件名 | | `page` | INTEGER | PDF 页码(可选) | | `sheet` | TEXT | Excel 工作表(可选) | | `row` | INTEGER | Excel 行号(可选) | | `section` | TEXT | 章节(可选) | | `is_table` | BOOLEAN | 是否为表格 | | `is_excel` | BOOLEAN | 是否为 Excel 数据 | | `security_level` | TEXT | 安全级别 | | `collection` | TEXT | 所属向量库名称 | --- ## 数据库关系图 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 多向量库架构 │ ├─────────────────────────────────────────────────────────────────┤ │ knowledge/vector_store/chroma/ │ │ ├── public_kb/ │ │ ├── dept_finance/ │ │ ├── dept_hr/ │ │ └── ... │ │ │ │ knowledge/manager.py ─────────────────────────────────────┐ │ │ knowledge/router.py │ │ └─────────────────────────────────────────────────────────────┼───┘ │ user_id / document_id 关联 │ ▼ ┌──────────────────┐ │ rag_core.db │ │ (核心数据库) │ │ │ │ • sessions │ │ • messages │ │ • audit_logs │ │ • feedbacks │ │ • faqs │ │ • quality_reports│ └────────┬─────────┘ │ │ user_id / document_id 关联 │ ┌────────┴────────┐ ┌───────────────┐ │ knowledge.db │ │ exam.db │ │ │ │ │ │ • document_ │ │ • questions │ │ hashes │ │ • exams │ │ • change_logs │ │ • student_ │ │ • subscriptions │ │ answers │ │ • outline_cache │ │ • grade_ │ │ • document_ │ │ reports │ │ versions │ │ • knowledge_ │ └─────────────────┘ │ points │ └───────────────┘ ``` --- ## 数据库维护 ### 数据清理 ```bash # 清理过期会话(24小时未活跃) sqlite3 data/rag_core.db "DELETE FROM sessions WHERE last_active < datetime('now', '-24 hours');" sqlite3 data/rag_core.db "DELETE FROM messages WHERE session_id NOT IN (SELECT session_id FROM sessions);" # 清理旧审计日志(保留30天) sqlite3 data/rag_core.db "DELETE FROM audit_logs WHERE created_at < datetime('now', '-30 days');" # 清理已处理的通知(保留7天) sqlite3 data/knowledge.db "DELETE FROM notifications WHERE read = 1 AND created_at < datetime('now', '-7 days');" ``` ### 数据备份 ```bash # 备份 SQLite 数据库 cp data/*.db backup/ # 使用 SQLite 在线备份 sqlite3 data/rag_core.db ".backup backup/rag_core_backup.db" ``` ### 重置数据库 删除对应的文件,服务启动时会自动重建表结构: ```bash # 重置核心数据(会丢失会话和对话历史) rm data/rag_core.db # 重置知识管理数据(会丢失文档追踪和订阅) rm data/knowledge.db # 重置出题系统数据(会丢失题目和试卷) rm data/exam.db ``` --- ## 更新日志 | 日期 | 版本 | 更新内容 | |------|------|----------| | 2026-04-13 | 3.0 | 数据库架构重构:6 个独立数据库合并为 3 个 | | 2026-04-09 | 2.0 | 新增多向量库架构文档 | | 2026-04-07 | 1.0 | 初始版本 |