Files
urbanLifeline/docs/数据库优化方案总结.md
2025-12-02 14:59:34 +08:00

9.1 KiB
Raw Blame History

城市生命线数据库优化方案总结

更新日期2025-12-02

一、核心优化内容

1. 知识库版本管理(简化方案)

设计原则

  • 不创建额外的历史表或快照表
  • 直接在现有表中添加版本字段
  • 使用乐观锁防止并发编辑冲突

文档表tb_knowledge_document新增字段

字段名 类型 默认值 说明
version INTEGER 1 版本号(整数递增)
root_doc_id VARCHAR(50) NULL 根文档ID版本组标识首次上传时等于doc_id
is_current BOOLEAN true 是否当前使用的版本

索引:

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

使用示例

创建新版本:

-- 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, ...
);

编辑分段(乐观锁):

UPDATE knowledge.tb_knowledge_chunk 
SET content = '新内容', version = version + 1
WHERE chunk_id = 'xxx' AND version = 1;  -- 版本检查

查询当前版本:

SELECT * FROM knowledge.tb_knowledge_document
WHERE root_doc_id = 'root_xxx' 
  AND is_current = true 
  AND deleted = false;

二、多服务数据隔离方案

设计原则

  • 使用 dept_path 实现部门/租户隔离(已有字段)
  • 添加 service_type 实现服务间隔离
  • 不使用 tenant_iddept_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 系统日志

查询示例

// 招投标服务查询
public List<Document> getBiddingDocuments(String deptPath) {
    return documentMapper.selectList(
        new QueryWrapper<Document>()
            .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

影响范围

  • 所有外键约束已更新
  • 所有索引已更新
  • 文档速查表已更新

四、智能体关联

知识库表新增字段

ALTER TABLE knowledge.tb_knowledge_base 
ADD COLUMN agent_id VARCHAR(50);  -- 关联智能体ID

说明

  • 一个知识库可以关联一个智能体
  • 智能体可以通过此字段快速查找其知识库
  • 智能体表tb_agent当前已注释暂不启用

五、数据库初始化脚本

initAll.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

使用方式

# 进入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

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/urbanlifeline_test
    username: postgres
    password: test123

application-prod.yml

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/urbanlifeline_prod
    username: postgres
    password: prod123

部署命令

# 测试服务器
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
最后更新: 知识库版本管理、多服务隔离、字段重命名