一、先说说我为什么要做这个工具
说实话,这个工具是被逼出来的。画图永远是最烦最耗时的,相信每个开发同学都有遇到这个痛。表少、字段少还好,多了之后光是在画图软件里拖表、连线就能耗掉你半个下午,改一次表结构还得重新改图,慢慢地就直接放弃维护了。
用过一些网上工具都比较繁琐,最常用的还是文本绘图工具比如 PlantUML 和 Mermaid,但是经常会忘记语法,查语法、写代码也得搞个老半天。而且这些工具都要你重新描述一遍表结构——但我明明已经有 DDL 了啊,为什么还要再写一遍?
所以就有了这个工具:把你已有的 CREATE TABLE 语句粘进去,直接生成 ER 图,不需要学任何新语法。
需要 ER 图的场景还有很多:
- 写技术方案,光靠文字描述表结构,评审的人根本看不进去
- 向 leader 汇报数据库设计,没图说不清楚
- 新人接手老项目,几十张表没有 ER 图,只能靠猜
- 设计阶段想边写 DDL 边验证表关系,改来改去很麻烦
二、解决方案:粘贴 SQL,直接出图
我做了一个工具解决这个问题:Free ER Diagram
核心逻辑很简单:把你已有的 CREATE TABLE DDL 语句粘贴进去,自动解析生成 ER 图。
不需要重新学语法,不需要连数据库,不需要手动配置表关系。
三、主要功能详解
3.1 多 DDL 分区管理
实际项目的 DDL 往往很长,工具支持把 SQL 拆分到多个 Tab 里管理,按业务模块分区,清晰不混乱。
3.2 自动识别外键关系
解析 DDL 时会自动提取 FOREIGN KEY 约束,生成表之间的关系连线,不需要手动配置。
CREATE TABLE orders (
id BIGINT PRIMARY KEY,
user_id INT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) -- 自动识别,生成连线
);
3.3 自定义关系 & 关系类型
除了自动推断的外键关系,还可以手动添加自定义关系,支持 1:1、1:N、N:1、N:N 四种类型,并可以添加关系标签。
3.4 表分组(按业务模块划分颜色)
20+ 张表的大型系统,所有表堆在一起很难看。分组功能可以把表按业务模块划分,每组一个颜色,一眼就能看出业务边界。
3.5 支持 PlantUML 和 Mermaid 两种格式
两种主流 ER 图格式都支持,可以一键切换。Mermaid 还支持 Default / Dark / Forest / Neutral 四种主题。
- Plantuml
- Mermaid
3.6 一键分享链接
DDL 内容会被压缩编码到 URL 里,生成一个分享链接,发给其他人直接打开就能看到完整的 ER 图,不需要对方安装任何东西。
3.7 历史记录自动保存
每次解析后自动保存到本地,支持随时恢复历史版本,不用担心误操作丢失内容。
3.8 导出图片 / PDF
一键导出高清图片或 PDF,直接粘贴到技术文档、PPT 里。
四、技术实现
4.1 DDL 解析用 Web Worker,大型 DDL 不卡 UI
DDL 解析是 CPU 密集型操作,20+ 张表的大型 DDL 直接在主线程跑会导致 UI 卡顿。所以把解析逻辑放到了 Web Worker 里异步处理:
// parseDDLWorker.js
self.onmessage = ({ data }) => {
const { sql, requestId } = data;
const tables = parseDDL(sql);
self.postMessage({ tables, requestId });
};
// 主线程
workerRef.current.postMessage({ sql: allContent, requestId });
workerRef.current.onmessage = ({ data }) => {
if (data.requestId !== requestIdRef.current) return; // 忽略过期请求
setParsedTables(data.tables);
};
主线程只负责发消息和接收结果,解析过程中 UI 完全不阻塞,体验流畅。
4.2 分享链接用 deflate 压缩,URL 不爆长
DDL 内容直接放 URL 会很长,用 deflate-raw 压缩后再 base64url 编码,压缩率能到 70%+,一个包含 20 张表的 DDL 也能压缩到合理的 URL 长度:
// 编码:deflate 压缩 + base64url
function encodeShareState(state) {
const json = JSON.stringify(state);
const compressed = deflateRaw(json);
return btoa(String.fromCharCode(...compressed))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}
// 解码
function decodeShareState(encoded) {
const binary = atob(encoded.replace(/-/g, '+').replace(/_/g, '/'));
const bytes = Uint8Array.from(binary, c => c.charCodeAt(0));
return JSON.parse(inflateRaw(bytes, { to: 'string' }));
}
4.3 外键自动推断关系
解析 DDL 时提取 FOREIGN KEY 约束,自动生成表关系,用户不需要手动配置:
const inferredRelations = [];
const tableNames = new Set(tables.map(t => t.name));
for (const table of tables) {
for (const fk of (table.foreignKeys || [])) {
if (tableNames.has(fk.refTable)) {
inferredRelations.push({
sourceTable: table.name,
targetTable: fk.refTable,
sourceColumn: fk.column,
targetColumn: fk.refColumn,
type: 'many-to-one',
inferred: true, // 标记为自动推断,区别于用户手动添加的关系
});
}
}
}
五、隐私说明
所有数据完全在浏览器本地处理,DDL 内容不会上传到任何服务器。历史记录存储在 localStorage,关闭浏览器也不会丢失。
六、在线体验
- ✅ 完全免费
- ✅ 无需注册账号
- ✅ 支持中英文切换
- ✅ 数据本地处理,隐私安全 好的!根据当前工具的功能和技术架构,我来帮你补充一个合理的后续更新计划:
七、后续更新计划
这个工具目前已经覆盖了日常使用的核心功能,后续还有一些想法在规划中:
- 支持更多数据库方言:目前主要支持 MySQL 语法,后续计划支持 PostgreSQL、Oracle、SQL Server 等方言的 DDL 解析
- 从数据库直连逆向生成:支持填写数据库连接信息,直接从线上库拉取表结构生成 ER 图(当然,数据不会上传,连接在本地完成)
- AI 辅助建表:输入自然语言描述业务需求,自动生成 DDL 和 ER 图
- 更多导出格式:支持导出为 draw.io 格式、Markdown 表格、数据字典文档等
欢迎试用!如果你有其他想法或建议,欢迎评论区留言,一起交流~