我用 React + Web Worker 做了个免费 ER 图生成工具,粘贴 SQL 直接出图-Free ER Diagram

20 阅读5分钟

一、先说说我为什么要做这个工具

说实话,这个工具是被逼出来的。画图永远是最烦最耗时的,相信每个开发同学都有遇到这个痛。表少、字段少还好,多了之后光是在画图软件里拖表、连线就能耗掉你半个下午,改一次表结构还得重新改图,慢慢地就直接放弃维护了。

用过一些网上工具都比较繁琐,最常用的还是文本绘图工具比如 PlantUML 和 Mermaid,但是经常会忘记语法,查语法、写代码也得搞个老半天。而且这些工具都要你重新描述一遍表结构——但我明明已经有 DDL 了啊,为什么还要再写一遍?

所以就有了这个工具:把你已有的 CREATE TABLE 语句粘进去,直接生成 ER 图,不需要学任何新语法。

需要 ER 图的场景还有很多:

  • 写技术方案,光靠文字描述表结构,评审的人根本看不进去
  • 向 leader 汇报数据库设计,没图说不清楚
  • 新人接手老项目,几十张表没有 ER 图,只能靠猜
  • 设计阶段想边写 DDL 边验证表关系,改来改去很麻烦

二、解决方案:粘贴 SQL,直接出图

我做了一个工具解决这个问题:Free ER Diagram

核心逻辑很简单:把你已有的 CREATE TABLE DDL 语句粘贴进去,自动解析生成 ER 图。

不需要重新学语法,不需要连数据库,不需要手动配置表关系。

overview.png

三、主要功能详解

3.1 多 DDL 分区管理

实际项目的 DDL 往往很长,工具支持把 SQL 拆分到多个 Tab 里管理,按业务模块分区,清晰不混乱。

image.png

3.2 自动识别外键关系

解析 DDL 时会自动提取 FOREIGN KEY 约束,生成表之间的关系连线,不需要手动配置。

CREATE TABLE orders (
  id BIGINT PRIMARY KEY,
  user_id INT NOT NULL,
  FOREIGN KEY (user_id) REFERENCES users(id)  -- 自动识别,生成连线
);

image.png

3.3 自定义关系 & 关系类型

除了自动推断的外键关系,还可以手动添加自定义关系,支持 1:1、1:N、N:1、N:N 四种类型,并可以添加关系标签。

image.png

3.4 表分组(按业务模块划分颜色)

20+ 张表的大型系统,所有表堆在一起很难看。分组功能可以把表按业务模块划分,每组一个颜色,一眼就能看出业务边界。

image.png

3.5 支持 PlantUML 和 Mermaid 两种格式

两种主流 ER 图格式都支持,可以一键切换。Mermaid 还支持 Default / Dark / Forest / Neutral 四种主题。

  • Plantuml image.png
  • Mermaid image.png

3.6 一键分享链接

DDL 内容会被压缩编码到 URL 里,生成一个分享链接,发给其他人直接打开就能看到完整的 ER 图,不需要对方安装任何东西。

3.7 历史记录自动保存

每次解析后自动保存到本地,支持随时恢复历史版本,不用担心误操作丢失内容。

image.png

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,关闭浏览器也不会丢失。


六、在线体验

🔗 erdiagram.utoolab.com

  • ✅ 完全免费
  • ✅ 无需注册账号
  • ✅ 支持中英文切换
  • ✅ 数据本地处理,隐私安全 好的!根据当前工具的功能和技术架构,我来帮你补充一个合理的后续更新计划:

七、后续更新计划

这个工具目前已经覆盖了日常使用的核心功能,后续还有一些想法在规划中:

  • 支持更多数据库方言:目前主要支持 MySQL 语法,后续计划支持 PostgreSQL、Oracle、SQL Server 等方言的 DDL 解析
  • 从数据库直连逆向生成:支持填写数据库连接信息,直接从线上库拉取表结构生成 ER 图(当然,数据不会上传,连接在本地完成)
  • AI 辅助建表:输入自然语言描述业务需求,自动生成 DDL 和 ER 图
  • 更多导出格式:支持导出为 draw.io 格式、Markdown 表格、数据字典文档等

欢迎试用!如果你有其他想法或建议,欢迎评论区留言,一起交流~