DBView 开发日志 ③ — SQL 日志系统、交互体验打磨与查询页面优化
日期: 2026-06-09
项目: DBView — Database Visual Explorer(数据库可视化工具)
状态: v1.0 功能完善与修复阶段
一、本期概要
本期主要完成四件事:
- SQL 日志系统 — 新增底部日志面板,实时记录所有数据库操作,分类展示
- MySQL 系统库修复 — 修复了系统库(
information_schema等)无法加载表/索引的问题 - 侧边栏交互体验打磨 — 双击连接、自动展开、断开清理等细节优化
- 查询页面优化 & P0 修复 — 存储过程查看定义、分组管理、编辑器拖拽等高优问题
本期涉及 15 个文件,新增约 1,000 行代码,总源文件数达到 50 个。
二、SQL 日志系统
2.1 设计思路
在开发过程中,我们逐渐发现两个痛点:
- 调试困难: 数据库操作分散在各个驱动和 IPC handler 中,出了问题很难追溯到底执行了什么 SQL
- 透明度不足: 用户看不到应用在后台悄悄跑了哪些查询,尤其是在自动展开树和加载元数据时
需求: 一个贯穿所有数据库操作的日志系统,实时展示每一条 SQL,按用途分类,支持筛选和查看详情。
2.2 架构:三层传递
1 | [DatabaseDriver] ← 驱动层:实际执行 SQL |
2.3 DriverLogger — 装饰器模式
核心设计是 DriverLogger 装饰器:它实现了 DatabaseDriver 接口,内部持有真实驱动实例,在每次方法调用前后插入日志逻辑:
1 | export class DriverLogger implements DatabaseDriver { |
日志类别划分:
| 类别 | 场景 | 示例 |
|---|---|---|
user |
用户主动执行的 SQL | SQL 编辑器执行的查询、内联编辑的 INSERT/UPDATE/DELETE |
system |
系统自动操作 | 连接自动断开、连接池管理 |
metadata |
元数据加载 | getTables、getColumns、getDatabases 等 |
2.4 SqlLogService — 主进程服务
主进程服务管理最多 500 条日志,通过 IPC 通道向渲染进程推送新条目:
1 | export class SqlLogService { |
注意这是项目中 第一个从主进程主动推送事件到渲染进程 的模块——之前所有 IPC 都是 request/response 模式。
2.5 SqlLogPanel — 底部面板
SqlLogPanel.tsx(297 行)是一个可折叠、可调整高度的底部面板,主要功能:
- 折叠/展开 — 状态栏按钮切换
- 高度拖拽 — 100~500px 可调
- 分类筛选 — All / User SQL / System / Metadata 四种
- 状态标识 — 绿色(成功)、红色(失败)
- 展开详情 — 点击日志项查看完整 SQL
- 暗色主题适配 — 面板背景、文字颜色全跟随主题
1 | ┌──────────────────────────────────────────────┐ |
2.6 logStore — Zustand 状态
1 | interface LogState { |
2.7 驱动程序注册
在 ConnectionManager 中,创建驱动实例后立即用 DriverLogger 包装:
1 | // connection-manager.ts |
这样所有通过 ConnectionManager 获取的驱动调用都会自动记录日志,无需修改任何驱动或业务代码。
三、MySQL 系统库加载修复
3.1 问题描述
用户连接 MySQL 后,展开 information_schema 或 mysql 等系统库时:
getTables()返回空(过滤了SYSTEM VIEW类型)getIndexes()报错(非表对象不支持SHOW INDEX)getDDL()报错(视图不支持SHOW CREATE TABLE)
3.2 修复方案
getDatabases() — 排序而非过滤:
之前的做法是过滤掉系统库,导致用户想看系统表时无法展开。改为排序——用户库在前、系统库在后,既不影响正常使用,也保留了对系统库的访问能力。
getTables() — 包含 SYSTEM VIEW:
MySQL 的 information_schema 中表类型包括 SYSTEM VIEW,之前 TABLE_TYPE IN ('BASE TABLE', 'VIEW') 没有包含它。修改后支持所有类型。
getIndexes() / getDDL() — try/catch 容错:
系统视图不支持 SHOW INDEX 和 SHOW CREATE TABLE,加入 try/catch 后优雅降级返回空或 Create View 回退。
1 | // mysql-driver.ts |
四、侧边栏交互体验打磨
基于 Navicat 风格的侧边栏,本次进一步优化了交互细节:
4.1 双击连接节点
| 状态 | 行为 |
|---|---|
| 未连接 | 自动连接并展开 |
| 已连接 | 切换展开/收起 |
| 断开时 | 自动收起箭头并清除子节点 |
4.2 箭头点击自动连接
之前点连接节点旁的展开箭头时,如果未连接,树节点会卡在”加载中”状态。现在:
1 | // DatabaseTree.tsx — onLoadData |
loadChildren 在检测到 conn 类型且未连接时,自动调用 connectionApi.connect(connId)。
4.3 其他细节
- 文字不可选中 —
user-select: none,避免双击时误选文本 - 超长省略号 — 连接名过长时自动截断
- 间距调整 — 减小箭头/图标/文字之间的间距,更紧凑
- 背景统一白 — 侧边栏背景颜色统一为白色,不再分层
- 暗色主题适配 — 树节点背景透明,跟随主题
五、P0 问题修复与查询页面优化
5.1 存储过程/函数”查看定义”
问题: 右键存储过程 → 查看定义 → 打开空白编辑器。原因是定义内容是异步加载的,但编辑器在加载完成前就显示了。
修复: 先显示”正在加载…”状态,等 getRoutineDefinition 返回后再填入编辑器内容。
5.2 连接分组管理集成
之前分组管理只能通过专门的 API 接口操作,没有 UI。现在在侧边栏右键菜单中加入了分组管理 Modal,支持:
- 查看所有分组
- 新建分组
- 重命名分组
- 删除分组(组内连接自动变为未分组)
5.3 分组内连接右键菜单
问题: 分组节点内的连接没有右键菜单。原因是 renderTitle 只在根层应用,没有递归到子节点。
修复: treeData.map 改为递归应用 renderTitle 到所有层级的节点。
5.4 连接表单弹窗布局
问题: 表单内容过长时,弹窗底部按钮被推出可见区域,需要滚动才能点击”确定”。
修复: 弹窗内容区设为 max-height: 60vh; overflow-y: auto,标题和按钮始终固定。
5.5 查询页面工具栏 & 编辑器
- 工具栏主题跟随 — 之前工具栏背景色硬编码为深色,在亮色主题下突兀。改为使用 Ant Design 主题变量
- 编辑器高度可拖拽 — SQL 编辑器底部添加拖拽手柄,高度可在 80~600px 范围内调整
六、CLAUDE.md 项目指引
新增了 CLAUDE.md(102 行)作为 Claude Code 的上下文文件,内容包括:
- 项目概述与技术栈
- 开发命令(
pnpm dev/pnpm build) - 进程模型(Main / Preload / Renderer)
- IPC 通道命名规范
- 数据库驱动架构(Strategy Pattern)
- 状态管理(三个 Zustand Store)
- Tab 系统说明
- 构建配置要点
- 已知局限
这使得后续 Claude Code 在该项目中的工作更加准确高效。
七、项目数据
| 指标 | 数值 |
|---|---|
| 总提交数 | 11 |
| 源文件数 | 50(.ts/.tsx) |
| 本期新增 | SQL 日志系统(4 个新文件) |
| 本期新增/修改文件 | 15 个 |
| 本期新增代码 | +1,003 行 |
| 本期删除代码 | -67 行 |
| 最大新文件 | SqlLogPanel.tsx(297 行) |
| 最大单次提交 | 370b00d — 日志模块(+685/-43,11 个文件) |
八、经验与反思
做得好的
- 装饰器模式的应用 —
DriverLogger零侵入地给所有驱动添加了日志能力,不改任何驱动代码 - 首个推送式 IPC — 打破纯 request/response 模式,为后续实时功能(如查询进度通知)铺平了路
- MySQL 降级策略 — 用 try/catch 优雅处理系统库的不同行为,而不是粗暴过滤或一刀切
可以改进的
- SQL 日志持久化 — 目前日志只在内存中,会话结束后丢失。后续可考虑持久化到文件
- 日志筛选粒度 — 目前只有四类筛选,可以增加按连接、按表名等更细粒度的过滤
- MySQL 系统库探索 — 对
information_schema的表结构展示还可以更丰富
九、下期预告
下一期将深入讲解 数据库驱动架构设计与实现,包括:
DatabaseDriver接口的设计考量与演化- 四种数据库驱动的实现对比(MySQL / PostgreSQL / SQLite / Oracle)
- 查询取消机制的跨驱动实现
- 驱动测试策略
敬请期待!
DBView 开发日志系列 — 记录一个数据库可视化工具从 0 到 1 的完整历程