SQL DDL 导出指南 | 用 Dr.ERD 生成 PostgreSQL 18 建表脚本
本指南把免费 ERD 教程和 Mermaid 导入教程中创建的会员、订单、订单明细三表模型导出为 SQL DDL 文件。Dr.ERD 不执行 SQL,只生成文件,因此执行脚本需要你在自己信任的数据库中完成。
当前文章: 导出 SQL DDL
1. 准备三表模型与 PostgreSQL 18 目标
本教程沿用前两篇指南中创建的模型。请先确认目标数据库是 PostgreSQL 18:Dr.ERD 会按模型上保存的目标生成 DDL,目标不同,类型和约束也不同。
- 在文件列表中打开 first-erd,或新建模型并在“目标数据库”中选择 PostgreSQL 18。
- 在 Chrome 或 Edge 中选择工作文件夹,准备存放 .drerd 文件与导出文件的位置。无需账号。
- 确认画布上有三张表和两个关系。若还没有,请先完成免费 ERD 教程。
- 要导出的模型:members、orders、order_items。
- AI 对话是可选功能,导出 SQL DDL 不需要它;只有你发送的消息才会带上当前 ERD 上下文。
2. 在导出菜单中选择 SQL
在工具栏的导出菜单中选择 SQL 会打开导出窗口,SQL 预览中会显示生成的 DDL。文件名与保存位置在点击“导出”后弹出的浏览器保存窗口中选择。
- 在导出菜单中选择 SQL。条目名称为 SQL,扩展名为 .sql。
- 在导出窗口的 SQL 预览中检查 CREATE TABLE 与 ALTER TABLE 语句。
- 保持默认的“包含注释”和“包含外键”处于开启状态。关闭“包含外键”只会让外键消失,并不会解决校验错误。
- 点击“导出”,在浏览器保存窗口中选择文件名(模型名.sql)和保存位置。
- Dr.ERD 不执行 SQL,只把生成的 DDL 保存为文件。
- 预览中的文字可以在屏幕上选中后复制。
- “范围”可以只导出选中的表,配合“包含被引用的父表”还能把被引用的表一并包含进来。
3. 导出前需要确认的内容
DDL 会原样输出模型中保存的设置。导出前请检查字段的“允许 NULL”、主键以及关系映射。缺少设置时,Dr.ERD 不会生成 DDL,而是给出错误提示。
- 确认三张表的 10 个字段都已关闭“允许 NULL”。只有关闭的字段才会输出为 NOT NULL。
- 确认三个主键已指定:members.id、orders.id、order_items.id。
- 确认两个关系已设置引用键与 FK 对应(members.id → orders.member_id,orders.id → order_items.order_id)。通过 Mermaid 导入创建的关系只有 FK 标记,对应关系为空,必须自行设置。
- 本教程没有自增(Identity)字段,id 的值需要在 INSERT 时手动填写。
- 关系未配置时会提示“请设置关系的引用键与 FK 对应”。
- 如果父字段既不是主键也不是 UNIQUE,引用键对应无法成立,也就无法导出。
- N:M 关系不会自动生成中间表,请在输出 DDL 前自行拆成中间表。
4. 如何阅读生成的 DDL
PostgreSQL 18 的输出分为创建表的 CREATE TABLE 语句和添加外键的 ALTER TABLE 语句。Dr.ERD 先建表、再挂关系,因此从上到下执行时,外键引用的表一定已经存在。
- 在 CREATE TABLE 语句中确认字段名、类型、NOT NULL 与 PRIMARY KEY。
- 在 ALTER TABLE 语句中确认 FOREIGN KEY(子表字段)REFERENCES 父表(父表字段)。
- 确认约束名是由你自己的关系 UUID 生成的。
- 约束名是 fk_ 加上关系 UUID 的前缀。每个关系的 UUID 不同,因此名称与示例不同是正常的。
- ON DELETE NO ACTION ON UPDATE NO ACTION 表示:当子表仍有记录时,数据库会拒绝删除或修改对应的父表记录。
- 本教程的两个关系都是非标识关系,因此外键不会进入子表主键。
- 外键字段的类型必须与被引用字段一致,否则导出时会提示“类型为空或不受支持”。
5. 示例 DDL(PostgreSQL 18 输出)
下面是这个三表模型导出为 PostgreSQL 18 时的结果。约束名由关系 UUID 生成,所以在你的模型中 fk_ 后面的值不同,而表、字段、类型和引用关系相同。
- 语句顺序:3 条 CREATE TABLE → 2 条 ALTER TABLE 外键。
- 关闭“允许 NULL”的 10 个字段都会输出为 NOT NULL。
- 只要引用的字段与参照动作一致,即使约束名与示例不同,结构也是相同的。
CREATE TABLE "members" (
"id" BIGINT NOT NULL,
"name" VARCHAR(100) NOT NULL,
PRIMARY KEY ("id")
);
CREATE TABLE "orders" (
"id" BIGINT NOT NULL,
"member_id" BIGINT NOT NULL,
"created_at" TIMESTAMP NOT NULL,
PRIMARY KEY ("id")
);
CREATE TABLE "order_items" (
"id" BIGINT NOT NULL,
"order_id" BIGINT NOT NULL,
"product_name" VARCHAR(100) NOT NULL,
"quantity" INTEGER NOT NULL,
"unit_price" NUMERIC(12,2) NOT NULL,
PRIMARY KEY ("id")
);
ALTER TABLE "orders" ADD CONSTRAINT "fk_11111111222243338444" FOREIGN KEY ("member_id") REFERENCES "members" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
ALTER TABLE "order_items" ADD CONSTRAINT "fk_66666666777748888999" FOREIGN KEY ("order_id") REFERENCES "orders" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
6. MySQL 8.4 与 Oracle 19c 有什么不同
Dr.ERD 会按模型中选择的目标生成 SQL。同一个模型在不同目标下类型与语法都不同,因此 PostgreSQL 18 的示例不能原样在 MySQL 或 Oracle 上执行。主要差异如下。
- 以 MySQL 8.4(InnoDB)为目标时,数据字典中的金额域会建议 DECIMAL(18,2);在 MySQL 中 NUMERIC 是 DECIMAL 的同义词。
- MySQL 的 TIMESTAMP 范围只有 1970 年到 2038 年,因此日期时间域会建议 DATETIME。
- Oracle 19c 使用 NUMBER(19,0) 代替 BIGINT,文本使用带字节长度的 VARCHAR2(100 BYTE) 代替 VARCHAR,并且没有 BOOLEAN 类型,因此不提供布尔域。
- MySQL 输出用反引号(`)包裹标识符,在 CREATE TABLE 末尾加上 ENGINE=InnoDB DEFAULT CHARSET=utf8mb4,自增字段输出为 AUTO_INCREMENT。
- Oracle 输出用双引号包裹标识符。Oracle 没有 ON UPDATE 动作,因此外键不会输出 ON UPDATE 子句。
- 请只在生成的 DDL 所声明的目标上原样执行;迁移到其他数据库时需要重新确认类型。
7. 在数据库中验证保存的 DDL
Dr.ERD 不执行 SQL,因此需要你自己运行保存的文件。建议使用已有的测试数据库,或用单个事务包裹脚本,这样不会留下多余的库表。PostgreSQL 的安装与连接方式不在本指南范围内。
- 在临时测试数据库中执行,或用事务包裹并在确认后回滚。PostgreSQL 可以在 BEGIN; 与 ROLLBACK; 之间进行确认。
- 确认已创建三张表(members、orders、order_items)和两个外键。
- 尝试在没有父记录的情况下插入子记录:INSERT INTO orders (id, member_id, created_at) VALUES (1, 999, NOW()); 应被外键校验拒绝。
- 确认完成后用 ROLLBACK 回滚,或删除该临时数据库。
- 预期结果:3 条 CREATE TABLE、2 条 ALTER TABLE、2 个外键。
- id 不是自增字段,请像 1、2、3 一样手动插入值。
- 如果父记录不存在而子记录仍能写入,说明外键没有生效,请检查 DDL 是否与目标数据库一致。
8. 常见问题排查
从导出到执行之间最常遇到的五种情况及检查方法。
- 没有主键:父表没有主键就无法配置引用键对应。请先在 members.id、orders.id、order_items.id 上点击“指定 PK”,再检查关系。
- 关系未配置:通过 Mermaid 导入创建的关系只有 FK 标记,没有键对应。请在关系编辑中设置引用键与 FK 对应。
- 外键类型不一致:引用字段与外键字段的类型、长度、小数位必须一致。members.id 是 BIGINT 时,orders.member_id 也必须是 BIGINT。
- N:M 关系:中间表不会自动生成。请自行创建中间表,拆成两个 1:N 关系后再导出。
- 文件夹写入权限:如果保存窗口打不开或保存失败,请重新允许访问工作文件夹,或选择其他可写入的文件夹。
9. 下一步
让模型与 DDL 保持一致,评审和发布都会更轻松。
- 模型有改动时,保存 .drerd 文件并重新导出 SQL DDL,使两者保持一致。
- 文档和评审可使用 Mermaid 导出,表格类资料可使用 Excel 导出。