Files
SuperBizAgent-java/mvp/tables/diagnosis_record.md
zhuyongxin 60be51f4a5 docs: 重构文档结构,分离学习笔记和 MVP 架构设计
**变更概述:**
- 将 MVP 架构设计文档独立到项目根目录 `mvp/`
- 整理 `docs/` 为纯学习和分析文档目录
- 按类型分类:learning(学习)、analysis(分析)、reports(报告)、guides(指南)

**目录结构:**
```
mvp/                          # MVP 架构设计(独立)
├── README.md                 # 数据库设计总览
├── architecture/             # 架构文档
│   ├── agent-architecture-mvp.md
│   ├── implementation-plan.md
│   └── ...
└── tables/                   # 数据表设计

docs/                         # 学习和分析文档
├── learning/                 # 学习笔记(00-08 编号)
├── analysis/                 # 分析笔记 + 重构计划
├── reports/                  # 临时报告
└── guides/                   # 指南文档
```

**详细变更:**
- docs/README.md → mvp/README.md(数据库设计入口)
- docs/architecture/ → mvp/architecture/(架构设计)
- docs/tables/ → mvp/tables/(数据表设计)
- docs/学习笔记-*.md → docs/learning/07-*.md, 08-*.md
- docs/项目学习路径.md → docs/learning/00-*.md
- docs/功能分析报告.md → docs/analysis/
- docs/修复报告-*.md → docs/reports/
- docs/日志配置*.md → docs/guides/ 或 docs/reports/
- docs/design/ → docs/analysis/(问题分析和重构计划)
2026-06-23 14:14:51 +08:00

7.4 KiB
Raw Permalink Blame History

diagnosis_record - 诊断记录表

表定位

核心业务表:存储每次诊断任务的完整记录

设计理念

兼容多种故障类型

问题背景:

  • 初始设计过于聚焦"外部接口故障"
  • 实际故障类型更丰富:空指针异常、数据库死锁、缓存穿透、线程池耗尽等

解决方案:

  • 字段泛化:business_id 替代 order_id,fault_source 替代 province
  • 增加分类:fault_category 显式区分故障类别
  • 增强错误信息:error_message、stack_trace 支持内部错误

表结构(v2.0)

CREATE TABLE diagnosis_record (
    -- 主键
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    diagnosis_id VARCHAR(64) UNIQUE NOT NULL COMMENT '诊断唯一ID(UUID)',
    
    -- 关联信息
    session_id VARCHAR(64) COMMENT '会话ID(关联Redis)',
    business_id VARCHAR(128) COMMENT '业务标识(订单号/请求ID/线程ID/任务ID...)',
    trace_id VARCHAR(64) COMMENT '链路追踪ID',
    
    -- 故障分类(泛化设计)
    fault_category VARCHAR(32) COMMENT '故障类别(EXTERNAL_API/INTERNAL_ERROR/DATABASE/CACHE/NETWORK/THREAD/MEMORY/CONFIG)',
    fault_source VARCHAR(128) COMMENT '故障源(省份/服务名/类名/数据库实例...)',
    fault_target VARCHAR(256) COMMENT '故障目标(接口URL/方法名/SQL语句/缓存键...)',
    
    -- 错误信息(通用)
    error_code VARCHAR(64) COMMENT '错误码(业务错误码/HTTP状态码/异常类名)',
    error_message TEXT COMMENT '错误消息',
    stack_trace TEXT COMMENT '堆栈信息(内部错误时记录)',
    
    -- 诊断结果
    problem_type VARCHAR(32) COMMENT '问题类型(参数/网络/权限/逻辑/空指针/死锁...)',
    root_cause TEXT COMMENT '根因分析',
    solution TEXT COMMENT '修复方案',
    report_markdown TEXT COMMENT '完整诊断报告(Markdown格式)',
    
    -- 评估指标
    status VARCHAR(16) DEFAULT 'PENDING' COMMENT '诊断状态(PENDING/RUNNING/SUCCESS/FAILED)',
    confidence INT COMMENT '诊断置信度(0-100)',
    duration INT COMMENT '诊断耗时(毫秒)',
    
    -- 用户反馈
    feedback VARCHAR(16) COMMENT '用户反馈(useful/not_useful/null)TODO: 后续可拆分为独立反馈表',
    
    -- 调试字段
    tool_calls JSON COMMENT '工具调用记录',
    
    -- 元数据
    created_by VARCHAR(64) COMMENT '创建人',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    
    -- 索引
    INDEX idx_business_id (business_id),
    INDEX idx_trace_id (trace_id),
    INDEX idx_session_id (session_id),
    INDEX idx_fault_category (fault_category),
    INDEX idx_fault_source_target (fault_source, fault_target(100)),
    INDEX idx_error_code (error_code),
    INDEX idx_created_at (created_at),
    INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='诊断记录表(v2.0 泛化版)';

字段说明

核心字段

字段 说明 示例
diagnosis_id 诊断唯一标识 diag-001
session_id 会话ID(支持追问) sess-abc
business_id 泛化:业务标识 订单号/请求ID/线程ID
trace_id 链路追踪ID trace-xyz

故障分类字段(泛化设计)

字段 说明 外部接口示例 内部错误示例
fault_category 故障类别 EXTERNAL_API INTERNAL_ERROR
fault_source 故障源 广东 order-service
fault_target 故障目标 /api/v1/social OrderController.create()
error_code 错误码 40003 NullPointerException

fault_category 枚举值

EXTERNAL_API    - 外部接口调用失败
INTERNAL_ERROR  - 系统内部错误(空指针、NPE)
DATABASE        - 数据库问题(死锁、慢查询)
CACHE           - 缓存问题(穿透、雪崩)
NETWORK         - 网络问题(超时、连接失败)
THREAD          - 线程问题(线程池满、死锁)
MEMORY          - 内存问题(OOM、内存泄漏)
CONFIG          - 配置问题(配置错误、缺失)

数据示例

示例1:外部接口故障

INSERT INTO diagnosis_record VALUES (
    NULL, 'diag-001', 'sess-abc', '202406150001', 'trace-001',
    'EXTERNAL_API', '广东', '/api/v1/guangdong/social-security', '40003',
    '参数缺失:idCard', NULL,
    '参数问题', 'idCard字段缺失', '补充前端校验', '完整报告...',
    'SUCCESS', 85, 5234, NULL,
    NULL, NOW(), NOW()
);

示例2:空指针异常

INSERT INTO diagnosis_record VALUES (
    NULL, 'diag-002', 'sess-def', 'req-xyz789', NULL,
    'INTERNAL_ERROR', 'order-service', 'OrderController.createOrder()', 'NullPointerException',
    'Cannot invoke "User.getName()" because "user" is null',
    'java.lang.NullPointerException: ...\n    at OrderController.java:45\n    ...',
    '空指针异常', 'createOrder方法中user对象为null', '添加空判断', '完整报告...',
    'SUCCESS', 90, 3456, NULL,
    NULL, NOW(), NOW()
);

示例3:数据库死锁

INSERT INTO diagnosis_record VALUES (
    NULL, 'diag-003', 'sess-ghi', 'txn-20240615-001', NULL,
    'DATABASE', 'mysql-master-01', 'UPDATE orders SET status=? WHERE order_id=?', '1213',
    'Deadlock found when trying to get lock', NULL,
    '数据库死锁', '两个事务互相等待对方释放锁', '调整事务加锁顺序', '完整报告...',
    'SUCCESS', 88, 4567, NULL,
    NULL, NOW(), NOW()
);

典型查询

按故障类别统计

SELECT 
  fault_category,
  COUNT(*) as count,
  ROUND(AVG(duration), 2) as avg_duration_ms,
  ROUND(AVG(confidence), 2) as avg_confidence
FROM diagnosis_record
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY fault_category
ORDER BY count DESC;

内部错误Top异常

SELECT 
  error_code,
  fault_target,
  COUNT(*) as count
FROM diagnosis_record
WHERE fault_category = 'INTERNAL_ERROR'
  AND created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY error_code, fault_target
ORDER BY count DESC
LIMIT 10;

诊断成功率

SELECT 
  COUNT(*) as total,
  SUM(CASE WHEN status = 'SUCCESS' THEN 1 ELSE 0 END) as success,
  ROUND(SUM(CASE WHEN status = 'SUCCESS' THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as success_rate
FROM diagnosis_record
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY);

核心设计决策

1. 一次诊断 = 一条记录

  • 用户发起一次诊断任务,创建一条记录
  • 不是聊天记录(不存多轮对话)
  • 追问对话上下文暂存 Redis(30分钟过期)

2. report_markdown 字段的必要性

  • 固化结果:Prompt变化不影响历史报告
  • 快速展示:不需要重新生成
  • 历史审计:可以看到当时的诊断结果

3. 字段泛化的好处

  • 支持多种故障类型(不限于外部接口)
  • 灵活填写(根据故障类型选择字段值)
  • 易于扩展(新增故障类型只需增加枚举值)

数据量预估

场景:中型企业运维团队
- 日均诊断:100 次
- 月均诊断:3000 次
- 年均诊断:36000 次

存储预估:
- 单条记录:约 5KB(含报告)
- 年存储量:36000 × 5KB = 180MB
- 三年存储:540MB

结论:数据量不大,可以全量保留

版本历史

版本 日期 变更内容
v1.0 2024-06-15 初版,基础字段
v2.0 2024-06-22 字段泛化,支持多种故障类型