# 城市生命线数据库优化方案总结 > 更新日期:2025-12-02 ## 一、核心优化内容 ### 1. 知识库版本管理(简化方案) #### 设计原则 - 不创建额外的历史表或快照表 - 直接在现有表中添加版本字段 - 使用乐观锁防止并发编辑冲突 #### 文档表(tb_knowledge_document)新增字段 | 字段名 | 类型 | 默认值 | 说明 | |--------|------|--------|------| | `version` | INTEGER | 1 | 版本号(整数递增) | | `root_doc_id` | VARCHAR(50) | NULL | 根文档ID(版本组标识,首次上传时等于doc_id) | | `is_current` | BOOLEAN | true | 是否当前使用的版本 | **索引:** ```sql CREATE INDEX idx_doc_root_current ON knowledge.tb_knowledge_document(root_doc_id, is_current) WHERE deleted = false; ``` #### 分段表(tb_knowledge_chunk)新增字段 | 字段名 | 类型 | 默认值 | 说明 | |--------|------|--------|------| | `version` | INTEGER | 1 | 分段版本号(用于乐观锁,每次编辑+1) | #### 使用示例 **创建新版本:** ```sql -- 1. 标记旧版本为非当前 UPDATE knowledge.tb_knowledge_document SET is_current = false WHERE root_doc_id = 'root_xxx'; -- 2. 插入新版本 INSERT INTO knowledge.tb_knowledge_document ( doc_id, root_doc_id, version, is_current, ... ) VALUES ( 'new_doc_id', 'root_xxx', 2, true, ... ); ``` **编辑分段(乐观锁):** ```sql UPDATE knowledge.tb_knowledge_chunk SET content = '新内容', version = version + 1 WHERE chunk_id = 'xxx' AND version = 1; -- 版本检查 ``` **查询当前版本:** ```sql SELECT * FROM knowledge.tb_knowledge_document WHERE root_doc_id = 'root_xxx' AND is_current = true AND deleted = false; ``` --- ## 二、多服务数据隔离方案 ### 设计原则 - 使用 `dept_path` 实现部门/租户隔离(已有字段) - 添加 `service_type` 实现服务间隔离 - **不使用 tenant_id**(dept_path 已足够) ### 隔离层级 | 隔离级别 | 字段 | 用途 | 示例 | |---------|------|------|------| | **服务级** | service_type | 区分不同业务服务 | bidding / customer_service / internal | | **部门级** | dept_path | 区分部门/租户 | /dept1/subdept1/ | ### 已添加 service_type 的表 | 表名 | 位置 | 说明 | |------|------|------| | `knowledge.tb_knowledge_base` | createTableKnowledge.sql | 知识库 | | `knowledge.tb_knowledge_document` | createTableKnowledge.sql | 知识文档 | | `file.tb_sys_file` | createTableFile.sql | 文件 | | `file.tb_file_relation` | createTableFile.sql | 文件关联 | | `message.tb_message` | createTableMessage.sql | 消息 | | `message.tb_message_template` | createTableMessage.sql | 消息模板 | | `log.tb_sys_log` | createTableLog.sql | 系统日志 | ### 查询示例 ```java // 招投标服务查询 public List getBiddingDocuments(String deptPath) { return documentMapper.selectList( new QueryWrapper() .eq("service_type", "bidding") // 服务隔离 .likeRight("dept_path", deptPath) // 部门隔离 .eq("is_current", true) // 当前版本 .eq("deleted", false) .orderByDesc("create_time") ); } ``` --- ## 三、知识库字段重命名 ### 变更内容 将所有 `kb_id` 改为 `knowledge_id`,提升语义清晰度。 | 表名 | 变更 | |------|------| | `knowledge.tb_knowledge_base` | 主键:kb_id → knowledge_id | | `knowledge.tb_knowledge_document` | 外键:kb_id → knowledge_id | | `knowledge.tb_knowledge_chunk` | 外键:kb_id → knowledge_id | | `knowledge.tb_knowledge_access_log` | 引用:kb_id → knowledge_id | | `customer_service.tb_faq` | 引用:kb_id → knowledge_id | ### 影响范围 - ✅ 所有外键约束已更新 - ✅ 所有索引已更新 - ✅ 文档速查表已更新 --- ## 四、智能体关联 ### 知识库表新增字段 ```sql ALTER TABLE knowledge.tb_knowledge_base ADD COLUMN agent_id VARCHAR(50); -- 关联智能体ID ``` ### 说明 - 一个知识库可以关联一个智能体 - 智能体可以通过此字段快速查找其知识库 - 智能体表(tb_agent)当前已注释(暂不启用) --- ## 五、数据库初始化脚本 ### initAll.sql(简化版) ```sql -- ============================= -- 城市生命线AI数智化平台 - 数据库初始化脚本 -- 按顺序执行各模块建表SQL -- ============================= \i createDB.sql -- 1. 系统基础模块 \i createTablePermission.sql \i createTableUser.sql -- 2. 文件管理模块 \i createTableFile.sql -- 3. 消息通知模块 \i createTableMessage.sql -- 4. 日志模块 \i createTableLog.sql -- 5. 配置管理模块 \i createTableConfig.sql -- 6. 知识库管理模块 \i createTableKnowledge.sql -- 7. 招投标业务模块 \i createTableBidding.sql -- 8. 智能客服业务模块 \i createTableCustomerService.sql -- 9. 智能体模块(暂不启用) -- \i createTableAgent.sql ``` ### 使用方式 ```bash # 进入PostgreSQL psql -U postgres # 执行初始化 \i /path/to/initAll.sql ``` --- ## 六、测试/生产环境隔离方案 ### 推荐方案:分别部署 ``` 测试环境: ├── 应用服务器:test-server:8080 ├── 数据库:urbanlifeline_test └── 配置:application-test.yml 生产环境: ├── 应用服务器:prod-server:8080 ├── 数据库:urbanlifeline_prod └── 配置:application-prod.yml ``` ### 配置文件 **application-test.yml** ```yaml spring: datasource: url: jdbc:postgresql://localhost:5432/urbanlifeline_test username: postgres password: test123 ``` **application-prod.yml** ```yaml spring: datasource: url: jdbc:postgresql://localhost:5432/urbanlifeline_prod username: postgres password: prod123 ``` ### 部署命令 ```bash # 测试服务器 java -jar urbanlifeline.jar --spring.profiles.active=test # 生产服务器 java -jar urbanlifeline.jar --spring.profiles.active=prod ``` ### 优势 ✅ **简单清晰**:物理隔离,无需代码改动 ✅ **安全可靠**:测试数据不会污染生产环境 ✅ **易于维护**:独立部署,互不影响 ✅ **性能独立**:测试压力不影响生产性能 --- ## 七、SQL语法修复 ### 修复内容 | 文件 | 问题 | 修复 | |------|------|------| | `createTableLog.sql` | 注释语句末尾使用逗号 | 改为分号 | | `createTableMessage.sql` | service_type字段缺少逗号 | 添加逗号 | --- ## 八、数据库表结构总览 ### 核心表关系 ``` knowledge.tb_knowledge_base (知识库) ├── agent_id → agent.tb_agent (智能体) └── knowledge_id ← knowledge.tb_knowledge_document (文档) ├── root_doc_id (版本组) ├── version (版本号) ├── is_current (当前版本) └── knowledge_id ← knowledge.tb_knowledge_chunk (分段) └── version (乐观锁版本) ``` ### 隔离字段应用 ``` 所有业务表 ├── service_type (服务隔离:bidding/customer_service/internal) └── dept_path (部门隔离:/dept1/subdept1/) ``` --- ## 九、最佳实践建议 ### 1. 版本管理 ✅ 每次上传新文档时设置 `root_doc_id = doc_id` ✅ 创建新版本前,标记旧版本 `is_current = false` ✅ 编辑分段时始终检查 `version` 字段(乐观锁) ### 2. 数据隔离 ✅ 查询时始终添加 `service_type` 过滤 ✅ 使用 MyBatis 拦截器自动注入隔离条件 ✅ 敏感操作添加 `dept_path` 权限检查 ### 3. 环境管理 ✅ 测试/生产分别部署,使用不同数据库 ✅ 配置文件使用 Spring Profile 管理 ✅ Controller/Service/Mapper 层无需修改 --- ## 十、待办事项 - [ ] 创建数据库迁移脚本(旧表 → 新表) - [ ] 编写单元测试验证版本管理功能 - [ ] 配置 MyBatis 拦截器自动注入 service_type - [ ] 准备生产环境部署文档 - [ ] 知识库数据导入/导出工具开发 --- ## 附录:完整字段对照表 ### tb_knowledge_document 字段清单 | 字段名 | 类型 | 必填 | 说明 | |--------|------|------|------| | doc_id | VARCHAR(50) | ✅ | 文档ID(主键) | | knowledge_id | VARCHAR(50) | ✅ | 知识库ID | | title | VARCHAR(500) | ✅ | 文档标题 | | **version** | **INTEGER** | ✅ | **版本号(新增)** | | **root_doc_id** | **VARCHAR(50)** | - | **根文档ID(新增)** | | **is_current** | **BOOLEAN** | ✅ | **是否当前版本(新增)** | | **service_type** | **VARCHAR(50)** | - | **服务类型(新增)** | | dept_path | VARCHAR(255) | - | 部门路径 | | deleted | BOOLEAN | ✅ | 软删除标记 | ### tb_knowledge_chunk 字段清单 | 字段名 | 类型 | 必填 | 说明 | |--------|------|------|------| | chunk_id | VARCHAR(50) | ✅ | 分段ID(主键) | | doc_id | VARCHAR(50) | ✅ | 文档ID | | knowledge_id | VARCHAR(50) | ✅ | 知识库ID | | content | TEXT | ✅ | 分段内容 | | **version** | **INTEGER** | ✅ | **版本号(乐观锁,新增)** | | embedding | vector(1536) | - | 向量嵌入 | | deleted | BOOLEAN | ✅ | 软删除标记 | --- **文档生成时间:** 2025-12-02 **最后更新:** 知识库版本管理、多服务隔离、字段重命名