drawDB v1.8.2 进阶实战与运维
drawDB v1.8.2 进阶实战与运维:内置模板复用与自定义模板、图表 JSON 导入导出与跨设备迁移、SQL 反向工程深度实战、分享与版本管理(drawdb-server)、镜像与源码两种升级路径、备份恢复与排障清单,全部经实测验证。
drawDB v1.8.2 进阶实战与运维
目标:面向已完成部署的用户(安装见《drawDB v1.8.2 Ubuntu 22.04 安装指南》,Compose 部署见《drawDB v1.8.2 Docker Compose 部署指南》,入门操作见《drawDB v1.8.2 快速入门(绘制 ER 图到导出 SQL)》),解决模板复用、图表数据导入导出与跨设备迁移、SQL 反向工程、分享与版本管理(drawdb-server)、镜像与源码升级、备份恢复及日常运维的进阶实战问题。全部结论基于 v1.8.2(commit e4e696f)实测。已在 Ubuntu 22.04.5 LTS(x86_64)环境实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- drawDB 版本:v1.8.2(commit e4e696f),镜像 digest
sha256:9e370f4f6facf6da04b2576606fde3c0d2debdd56f479a4b5adb61fc2262fcab(实测拉取值) - 两种部署形态:Compose 镜像部署(配置
/opt/drawdb/docker-compose.yml,镜像ghcr.io/drawdb-io/drawdb:v1.8.2,宿主 3000 → 实例内 80);源码自托管(源码/root/drawdb,产物/var/www/drawdb,nginx 监听 80) - Node.js:v20(构建命令
npm ci && NODE_OPTIONS=--max-old-space-size=4096 npm run build) - 分享后端(可选):drawdb-server,地址经
VITE_BACKEND_URL/VITE_GIST_BACKEND_URL环境变量注入
二、模板体系实战
2.1 内置官方模板
v1.8.2 内置 6 套官方模板(源码 src/templates/ 实测清单):
| 模板 | 领域 | 适合学什么 |
|---|---|---|
| Blog database schema | 博客 | 文章/分类/标签多对多 |
| Human resources schema | 人力资源 | 员工/部门/职位层级 |
| E-commerce schema | 电商 | 订单/商品/购物车经典建模 |
| Library schema | 图书馆 | 借阅关系与状态字段 |
| Bank schema | 银行 | 账户/交易/约束设计 |
| University schema | 大学 | 学生/课程/成绩关系网 |
使用方式:首页或编辑器左侧「Templates」进入模板页 → 点目标模板的「Use this template」,整图复制进编辑器(含表、关系、区域、备注全部对象),改名即可开工。
2.2 存为自己的模板
把当前图存为个人模板:编辑器工具栏「Save as template」,图表存入浏览器本地。之后同样在「Templates」页可见并复用。
⚠️ 注意:个人模板与图表数据一样存浏览器 IndexedDB,换浏览器/清数据会丢。需要跨环境分发模板时,走 JSON 导入导出(第三章)。
2.3 用模板做"组织级建模规范"的实践建议
- 把组织内的命名规范(表前缀、主键命名
<表>_id)、公共字段(created_at/updated_at)做成一个基准模板,新项目从模板 Fork 起步; - 配合 Auto-connect foreign keys 的两条命名规则(表前缀+主键 / 同名主键列),建模一致性能显著降低连线成本;
- 模板 JSON 提交进代码仓库评审,版本演进走 Git 而不是口头约定。
三、图表数据的导入导出与迁移
3.1 三种数据通道总览
| 通道 | 入口 | 格式 | 用途 |
|---|---|---|---|
| 导出 JSON | 工具栏「Export as → JSON」 | drawDB 工程文件 | 备份/迁移/仓库化 |
| 导入 JSON | 工作台「Import diagram」或拖拽文件 | 同上 | 恢复/合并 |
| Export saved data | 设置面板 | JSON(本地全部图表) | 整体备份浏览器数据 |
3.2 JSON 工程文件结构(实测)
v1.8.2 导出的 JSON 顶层字段(实测清单):
{
"tables": [],
"relationships": [],
"notes": [],
"subjectAreas": [],
"views": [],
"database": "mysql"
}
tables内含每个表的name/comment/x/y/color/fields/indices等完整属性(字段含name/type/size/default/check/primary/unique/notNull/increment/unsigned/comment);relationships内含startTableId/startFieldId/endTableId/endFieldId/cardinality/updateConstraint/deleteConstraint;- 存在自定义类型/枚举的图额外带
types、enums;设置了 SQL 头注释的图带sqlHeader;图表名title。
3.3 跨设备迁移实操(A 浏览器 → B 浏览器)
- A 浏览器:编辑器「Export as → JSON」得到
demo.json; - 把文件拷到 B 环境(U盘/内网传输均可);
- B 浏览器:打开 drawDB 工作台,点「Import diagram」选择
demo.json(或直接把文件拖进页面); - 验证:B 环境编辑器中表数量、关系连线、注释与 A 一致。
💡 技术拓展:迁移粒度选择——单图迁移用「Export as → JSON」;整库迁移(本地所有图一次性搬走)用设置面板的「Export saved data」,导出的是全量本地数据包,在 B 环境导入即可整体接管。两者可按需选用,前者适合协作分发,后者适合设备更换/清理浏览器前的兜底备份。
3.4 图表 JSON 仓库化
把 JSON 存入 Git 仓库可获得版本历史与评审能力:
- 图表 JSON 是纯文本,diff 友好;
- 团队约定:每张图一个
.json文件 + 元信息(负责人、变更原因)写在 commit message; - 变更评审:GitHub/GitLab 的 PR diff 可直接看出表/字段增删。
这是不部署 drawdb-server 时最稳的团队协作替代方案。
四、SQL 反向工程深度实战
4.1 支持的方言与解析引擎(源码核实)
v1.8.2 的「Import from SQL」按目标方言选择解析器(实测源码链路:node-sql-parser 的 Parser.astify(src, { database }) → importSQL(ast, toDb, diagramDb)):
| 方言 | 解析引擎 | 说明 |
|---|---|---|
| MySQL | node-sql-parser | 最常用,实测最稳 |
| PostgreSQL | node-sql-parser | 支持 |
| MariaDB | node-sql-parser | 兼容 MySQL 语法 |
| SQLite | node-sql-parser | 支持 |
| SQL Server | node-sql-parser | 支持 |
| Oracle | oracle-sql-parser | 独立解析器 |
4.2 实操流程
- 从数据库导出 DDL(如
mysqldump --no-data db_name > schema.sql,或数据库客户端导出建表语句); - drawDB 工作台「Import from SQL」→ 粘贴或上传 SQL → 选择源方言 → 确认;
- 画布检查生成的表与关系;导出侧边栏核对字段属性;
- 需要时切换方言再导出(异构迁移场景)。
4.3 实测解析结果(MySQL 输入)
输入 DDL(快速入门 7.2 节同一段):
CREATE TABLE users (
id INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
username VARCHAR(64) NOT NULL UNIQUE,
email VARCHAR(128) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
CREATE TABLE orders (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
user_id INT UNSIGNED NOT NULL,
amount DECIMAL(10,2) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
);
实测解析输出:
TABLE users fields= id:INTEGER(PK)(AI), username:VARCHAR(UQ), email:VARCHAR, created_at:TIMESTAMP
TABLE orders fields= id:INTEGER(PK)(AI), user_id:INTEGER, amount:DECIMAL
{"start":"orders","end":"users","cardinality":"many_to_one","deleteConstraint":"Cascade"}
4.4 能力边界与踩坑(实测沉淀)
| 场景 | 结果 | 处理建议 |
|---|---|---|
INT UNSIGNED | ⚠️ unsigned 丢失,类型规范化为 INTEGER | round-trip 后手工核对整数列 |
INT | 规范化为 INTEGER | 无功能影响,仅名称变化 |
外键 ON DELETE CASCADE | ✅ 还原 | — |
字段 COMMENT | ✅ 还原为注释 | round-trip 后保留 |
UNIQUE 行内约束 | ✅ 还原为字段唯一属性 | 再导出时写法可能变(见 4.5) |
| 存储过程/触发器/分区子句 | ⚠️ 解析范围外 | 导入前剥离,只保留 CREATE TABLE/FOREIGN KEY |
| 多语句 DDL | ✅ 支持 | 逐条语句分号结尾 |
4.5 Round-trip 无损性实测
同一图「SQL → 图 → SQL」的再导出实测(MySQL,逐字原文):
CREATE TABLE IF NOT EXISTS `users` (
`id` INTEGER NOT NULL AUTO_INCREMENT COMMENT '主键',
`username` VARCHAR(64) NOT NULL UNIQUE,
`email` VARCHAR(128) NOT NULL,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(`id`)
);
CREATE TABLE IF NOT EXISTS `orders` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`user_id` INTEGER NOT NULL,
`amount` DECIMAL(10,2) NOT NULL,
PRIMARY KEY(`id`)
);
ALTER TABLE `orders`
ADD FOREIGN KEY(`user_id`) REFERENCES `users`(`id`)
ON UPDATE NO ACTION ON DELETE CASCADE;
与原始 DDL 的差异:INT→INTEGER、导出统一带 IF NOT EXISTS、行内 UNIQUE 在图内转为字段属性。结论:反向解析定位是"可视化与再设计",不是 DDL 无损转换工具;生产 DDL 变更请走数据库侧迁移工具。
💡 技术拓展:真正的 DDL 变更管理应使用数据库原生工具链——MySQL/PostgreSQL 用 Flyway/Liquibase 做版本化迁移脚本,PostgreSQL 还有 Alembic(Python 生态);drawDB 的价值在"看得见的再设计",两者配合:drawDB 出图评审 → 确认后由迁移工具落地。
五、分享与版本管理(drawdb-server)
5.1 能力与依赖
- 「Share」生成只读链接、版本历史、版本对比(含差异编辑器)、迁移 SQL 生成(
generateMigrationSQL,输出 up/down 两段 SQL)——这些能力依赖独立部署的 drawdb-server 后端; - 部署地址通过
VITE_BACKEND_URL/VITE_GIST_BACKEND_URL注入(见《drawDB v1.8.2 配置参数详解》第三、四章); - 未配置后端时,分享按钮点击会连接失败(回落地址
http://localhost:5000不可达),绘图与导出功能不受影响。
5.2 后端接口契约(源码 src/api/gists.js 核实)
前端实际调用的 REST 接口({gistBackendUrl} 为配置的后端基地址):
| 方法 | 路径 | 用途 |
|---|---|---|
| POST | /gists | 创建分享(body:public/filename/description/content),返回 id |
| GET | /gists/{id} | 读取分享内容 |
| PATCH | /gists/{id} | 更新分享 |
| DELETE | /gists/{id} | 删除分享 |
| GET | /gists/{id}/commits?per_page=20&page=1 | 版本提交列表(分页) |
| GET | /gists/{id}/{sha} | 读取指定版本 |
| GET | /gists/{id}/file-versions/{file}?limit=10 | 文件级版本列表(游标分页) |
| GET | /gists/{id}/file/{file}/compare/{verA}/{verB} | 两版本对比 |
分享文件名约定:分享用 share.json,版本历史用 versionned.json(源码常量 SHARE_FILENAME/VERSION_FILENAME)。自建后端按此契约实现即可(官方实现仓库 drawdb-io/drawdb-server)。
六、升级实战
6.1 Compose 镜像方式升级
目标:v1.8.2 → 新版本 tag(下文以 vX.Y.Z 指代,替换为你实际要升级到的 tag 号,如 v1.9.0)。
- 修改
/opt/drawdb/docker-compose.yml中image的 tag:
image: ghcr.io/drawdb-io/drawdb:vX.Y.Z
- 拉取并重建:
cd /opt/drawdb && docker compose pull && docker compose up -d
- 验证:
docker compose ps && curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/
- 回滚:把 tag 改回
v1.8.2重跑docker compose up -d(旧镜像仍在本地,秒级回滚)。
💡 技术拓展:镜像 tag 固定策略对比——
:latest自动跟新但版本不可控;:v1.8.2显式锁定、升级走流程,是生产基线做法;更严格的用 digest 固定(image@sha256:9e370f4f6facf6da04b2576606fde3c0d2debdd56f479a4b5adb61fc2262fcab,实测 v1.8.2 拉取时的 digest 原值),连同 tag 重建漏洞一起免疫。团队推荐:compose 文件锁 tag,CHANGELOG 记录每次升级。
6.2 源码自托管方式升级
cd /root/drawdb && git fetch --tags --depth 1 && git checkout vX.Y.Z
npm ci && NODE_OPTIONS=--max-old-space-size=4096 npm run build
覆盖部署(清旧产物再复制,避免遗留旧哈希文件):
rm -rf /var/www/drawdb/* && cp -r /root/drawdb/dist/* /var/www/drawdb/
验证:curl -sI http://localhost/ | head -1 应为 HTTP/1.1 200 OK;浏览器打开无控制台报错。
6.3 升级风险清单
- 用户图表数据不在服务器,升级不涉及数据迁移;但浏览器 IndexedDB 里的图表结构可能与新版内部格式有差异,drawDB 内置了版本迁移逻辑(源码
Migration.jsx及本地数据版本迁移),正常升级自动完成; - 升级前建议用户各自「Export saved data」做一次全量备份(30 秒操作,兜底);
- 新版若改了
config.js注入结构(window.__DRAWDB_CONFIG__字段),需同步检查第五章的自定义配置是否仍兼容; - 多实例环境先在测试实例验证新镜像,再逐台更新。
七、备份与恢复
7.1 服务器侧
drawDB 服务端无状态(静态文件 + nginx),需要备份的对象只有两类:
| 对象 | 路径/来源 | 方式 |
|---|---|---|
| 部署产物 | /var/www/drawdb(源码方式) | tar -czf 打包,或保留 dist-v版本号.tar.gz 原始包 |
| compose 配置 | /opt/drawdb/docker-compose.yml | 纳入配置仓库 |
7.2 用户侧(真正的数据)
图表数据全在用户浏览器(IndexedDB):
- 备份:设置面板「Export saved data」(全量)或每图「Export as → JSON」(单图);
- 恢复:「Import diagram」导入 JSON / 「Import saved data」恢复全量包;
- 团队基线:约定"重要图表必须导出 JSON 入仓库",浏览器数据仅当工作副本。
八、日常运维检查清单
| 检查项 | 命令 | 期望 |
|---|---|---|
| 服务存活 | curl -s -o /dev/null -w '%{http_code}' http://localhost:3000/(Compose)或 http://localhost/(自托管) | 200 |
| 实例状态 | docker compose ps | STATUS 为 Up |
| 配置注入 | curl -s http://localhost:3000/config.js | 内容与预期环境变量一致 |
| SPA 回退 | curl -s -o /dev/null -w '%{http_code}' http://localhost:3000/editor | 200 |
| 磁盘 | df -h / | 静态站点占用稳定,无增长型目录 |
| 日志 | docker compose logs --tail 50 drawdb | 无 error 级报错 |
drawDB 是静态站点,没有后台任务、数据库连接池等需要巡检的运行态;运维重心在"页面可访问 + 配置注入正确"两点。
九、常见问题(FAQ)
Q1:升级后浏览器里图表打不开/字段丢失? 先「Export saved data」导出留底,然后清一次站点数据(浏览器设置 → 清除该站点数据)后重新导入。v1.8.x 内的升级实测无此问题,跨大版本(如 1.x → 2.x)如遇内部格式变更需按新版提示走迁移。
Q2:两个浏览器绘的图怎么合并? drawDB 无原生合并。实操:B 图导出 JSON,A 环境导入后成为第二张图,需要同图合并时在 A 编辑器内参考 B 图手工补齐(或用 Python 脚本对两个 JSON 做表/关系级合并后导入)。
Q3:反向解析报解析错误?
检查三点:方言选择是否与 SQL 实际语法一致(如把 PostgreSQL 的 "双引号" SQL 用 MySQL 方言解析会失败);SQL 是否含解析范围外的对象(存储过程/触发器/分区);语句是否完整(粘贴截断会报 syntax error)。剥离到纯建表语句最稳。
Q4:分享链接打开 404 或连不上?
分享依赖 drawdb-server。curl http://192.168.1.100:5000/gists/1(示例地址,换成实际后端地址)验证后端可达;确认 config.js 注入的 backendUrl 与后端实际地址一致(含端口);跨域时后端需放行 CORS。
Q5:多实例共享模板/图表可行吗? 本地模板/图表按浏览器隔离,天然不共享。共享路径二选一:JSON 入 Git 仓库(无后端,推荐起步);部署 drawdb-server 后用分享链接 + 版本历史(有评审需求)。
Q6:如何在 CI 里把图表导出成 SQL 做评审? drawDB 无官方 CLI。可行路径:图表 JSON 入仓库,评审通过后由开发者用编辑器导出 SQL 提交;或基于 JSON 结构自写导出脚本(结构见 3.2,字段稳定)。避免在 CI 里跑无头浏览器渲染整站的重量级方案。