编辑关系
关系通过画布右键菜单、画布工具栏、快速搜索或快捷键创建,参见开始编辑。
本页介绍关系创建之后可以进行的操作、如何通过映射列让关系连接到子表中已有的列上,以及关系所添加的外键列如何命名。
删除
可通过关系的右键菜单删除。

由于关系不像表或备注那样会被选中,因此没有对应的快捷键:用于删除选中内容的 Delete 和 Backspace 永远不会单独删除关系,参见删除表与备注。
关系还会随它连接的对象一起被删除:删除表会删除与该表相连的所有关系,删除列会删除使用该列的所有关系。
修改类型
可通过关系右键菜单中的 Relationship Type 修改。
提供以下四种类型,当前类型会带有勾选标记:
- Zero One
- Zero N
- One Only
- One N

这与创建关系时选择的四种类型相同,每种类型都有各自的快捷键,参见开始编辑。
ON DELETE 与 ON UPDATE
通过关系右键菜单中的 On Delete 与 On Update 设置,这两项位于 Relationship Type 与 Map Columns 之间。
两者提供相同的六个选项,当前选项会带有勾选标记:
- Not set
- NO ACTION
- CASCADE
- SET NULL
- SET DEFAULT
- RESTRICT
Not set 不会写出任何子句,因此由数据库自身的默认行为决定。新建的关系,无论是绘制的还是在映射列中创建的,两项均为 Not set,之后选择 Not set 即可清除已设置的操作。
两者互相独立:修改其中一项不会影响另一项。
连接线会显示已设置的内容,参见读懂连接线。
关系随其连接的表一起被复制粘贴或创建副本时,会保留这两项操作;导入 Schema SQL、DBML 或 AML 时,会带入文件中声明的操作,参见导入与导出文件。

无论使用哪种数据库,所有操作都可以选择。
所选数据库的 Schema SQL 不会写出的操作,旁边会带有一条淡色的说明,例如 not in MySQL。Not set 从不带有说明,切换数据库时说明会随之更新。
带有说明的操作仍会保存在关系上:连接线会显示它,JSON、DBML 和 AML 也会保留它,但该数据库的 Schema SQL 会省略这条子句,因此由数据库的默认行为决定。
Schema SQL 会写出以下操作,其余操作则会省略:
| 数据库 | ON DELETE | ON UPDATE |
|---|---|---|
| Databricks | NO ACTION | NO ACTION |
| MSSQL | NO ACTION, CASCADE, SET NULL, SET DEFAULT | NO ACTION, CASCADE, SET NULL, SET DEFAULT |
| MariaDB | NO ACTION, CASCADE, SET NULL, RESTRICT | NO ACTION, CASCADE, SET NULL, RESTRICT |
| MySQL | NO ACTION, CASCADE, SET NULL, RESTRICT | NO ACTION, CASCADE, SET NULL, RESTRICT |
| Oracle | CASCADE, SET NULL | 无 |
| PostgreSQL | 全部五种 | 全部五种 |
| Snowflake | NO ACTION | NO ACTION |
| SQLite | 全部五种 | 全部五种 |
Snowflake 的 Schema SQL 还会写出一条注释,列出它省略的每个操作,参见参照操作。
Code Generator 的 ORM 目标会写出哪些操作,不仅取决于所选的数据库,还取决于目标本身,参见代码生成。
映射列
映射列会将父表的键与子表的列配对,键的每一列对应一行。
每一行要么使用子表中已有的列,要么添加一个新的外键列,因此关系可以连接到已经存在的列上。

有两种打开方式:
- 绘制关系时,通过子表旁边的
Map to existing columns打开,参见创建关系。此时Map会添加一条所绘制类型的关系。 - 通过关系右键菜单中的
Map Columns打开,用于修改已有关系的列。此时Save会写入修改。只读编辑器的菜单中没有这一项。
对话框的副标题会写出两个表和关系类型,例如 users → posts · One N。类型在这里只显示而不能修改,要修改请参见修改类型。
References 用于选择关系所指向的键:先是 Primary Key,其列按表中的顺序排列,然后是每个标记为 Unique 的列对应的 Unique: <column>。只有在可选项多于一个时才会显示。
唯一索引在这里不算作键,本身就是整个主键的 Unique 列也不会重复列出。
选择另一个键会重建各行。一行所选的列只要仍在子表中,该行就会保留这一选择。
在 Referenced column 与 Foreign key column 两个标题下,每一行显示键的一列及其数据类型,以及一个可与之配对的子表列的列表:
Pick a column会让该行保持为空。New column: <name>会添加一个新的外键列。显示的名称就是该列将得到的名称,命名方式参见外键列名,编号时会将子表的列以及其他添加新列的行一并考虑在内。名称为空时不提供这一项,例如键没有名称时。- 子表的每一列,显示为
<name> (<data type>)。已被另一行选中的列显示为<name> (<data type>) · in use,并且无法选择,因此不会有两行共用同一列。已被另一条关系使用的列仍然可以选择,因此像共用的tenant_id这样的列可以服务于多条关系。
使用 Map 时,只有当子表中恰好有一列的名称(不区分大小写)与为该行新建的外键列在加上 _2 等编号之前的名称相同时,该行一开始才会被填好,例如 users 上的 id 对应 users_id,member_id 对应 member_id。当 Bracket 为默认的 None 时,由带 schema 限定的表名中的表名部分构成的名称也计算在内,因此 public.users 上的 id 会与 public.users_id 或 users_id 配对。对于 Unique 键,键列自身的名称也计算在内,因此 vin 会与 vin 配对。其他各行一开始都为 Pick a column。
使用 Save 时,每一行一开始都是关系当前使用的列。无论哪种情况,在 References 中选择另一个键时,都会按相同的名称填充该键的空行。
当所选列的数据类型与父列赋予外键的数据类型不同时,该行下方会有一条说明指出这一点。
在关系数据类型同步开启且父列设有数据类型时,说明为 <column> becomes <type>,即映射将写入的类型。否则说明为 Types differ: <parent type> and <child type>,该列保留其原有类型。
存在阻碍时,Map 或 Save 会保持禁用,各行下方会有一行文字说明原因:
Pick a foreign key column for every referenced column:仍有某一行为空。At least one column must reference a different column:自引用关系中,每一行选择的都是其自身对应的父列。These columns are already linked by another relationship:同样这两个表之间的另一条关系连接的恰好就是这些列。<parent> has no key to reference:使用Map时,父表既没有主键,也没有Unique列。
在映射与关系当前的映射不同之前,Save 也会保持禁用。
使用 Save 时,某一行的列已离开其所在的表时,该行显示为 (removed)。此时请选择子表中的其他列;如果消失的是父列,则在 References 中选择一个键。使用 Map 时,所选列被删除的行会恢复为 Pick a column。
如果关系的父列并不恰好是父表的某个键,打开时会选中 References 末尾的一个额外选项 Current columns (not a key),它会保持这些列不变。父表完全没有键时,这是唯一的选项,References 不会显示。
此时出现的 The referenced columns are not a key of <parent> 这一行(父表完全没有键时为 <parent> has no key to reference)只是一条说明,而不是错误:Save 仍然可用,因此可以修改子表的列并保留原有的引用。
如果关系的两组列无法配对,例如两者长度不同,则会显示 (invalid) 行,并且 Save 会保持禁用,直到在 References 中选择一个键;如果父表没有主键或 Unique 列,则需先为其添加一个。
对话框打开期间会跟随图的变化,包括协作者或编码智能体所做的编辑,同时保留已做的选择。
如果在此期间关系的列或打开时所用的键发生变化,对话框会添加一行 This relationship changed while the dialog was open。
Map 与 Save 写入的内容:
Map添加的关系的On Delete与On Update均为Not set。Save只修改关系的列,使其父表一侧指向在References中选择的键,并保留其类型以及 ON DELETE 与 ON UPDATE。New column行会像绘制关系时一样,在子表末尾添加一列:该列为NOT NULL,以其对应的键命名,并沿用该键的数据类型、默认值和注释,参见识别关系。- 所选的列永远不会被重命名,其
Not Null、主键、Unique、默认值和注释也都保持不变。只有在Relationship DataType Sync开启且父列设有数据类型时,其数据类型才会改变:它会采用父列赋予外键的类型,serial 类型的键与新列一样对应其整数类型,并且该修改会像同步时一样沿着关系继续传递。 - 映射不再使用的列会保留在子表中,除非仍有另一条关系连接到它,否则它不再被标记为外键。
- 一次
Map或Save写入的所有内容,包括新列和类型修改,都只算一步 Undo。
与其他关系一样,关系是否为识别关系、其父表一端如何绘制,都由映射到的子表列决定。映射到子表的主键列会使其立即成为识别关系,映射到允许 NULL 的列则会在父表一端绘制圆环,参见读懂连接线。
Schema SQL 中的外键会引用所选择的键,例如 Unique 键对应 REFERENCES vehicle (vin)。
如果按下 Map 或 Save 时图中已经存在该映射,例如协作者或编码智能体已抢先完成,则不会写入任何内容。
如果图已发生变化,导致该映射不再适用,则不会写入任何内容,并会显示 Couldn't map columns: the diagram changed 提示。
按 Cancel、点击 x 按钮、按 Escape 或点击对话框外变暗的区域,都会关闭对话框而不写入任何内容。
打开查找与替换或快速搜索同样会将其关闭,离开 ERD 标签页或编辑器变为只读时也是如此。
如果在对话框打开期间其中某个表或该关系被删除,对话框会关闭并显示一条提示,例如 Map Columns closed: the relationship was removed。
对话框打开期间,画布快捷键、Undo 与 Redo 以及复制和粘贴都不起作用。
编码智能体没有与映射列对应的工具。它会在一个 erd_batch 中先用 erd_remove_relationship 删除关系(该工具会保留其外键列),再用 erd_link_columns 在已有的列上重新绘制该关系,以此重新映射关系,参见工具。
N:M 关系
由于编辑器基于物理模型,N:M 关系会如下图所示,用一张映射表来表达。

如果映射表中已经有了键列,例如 product_tags 上的 product_id 和 tag_id,请使用 Map to existing columns 绘制每条关系并选择这些列,而不是添加新列,参见映射列。如果这些列是映射表的主键,每条关系都会立即成为识别关系。
导入 GraphQL、DBML 或 AML 时会自动生成映射表。
多对多声明会生成名为 <left>_<right> 的表,并带有 Junction table inferred from <left> <-> <right> 注释,通过识别关系与两侧相连。
参见导入与导出文件。
识别关系
通过点击子表或使用 Create new columns 创建关系时,父表的每个主键都会以 NOT NULL 外键列的形式复制到子表上,因此新建的关系起初是非识别关系。
复制出的列会沿用该键的数据类型、默认值和注释,但不会沿用 Unique 或 Auto Increment,其命名方式参见外键列名。
serial 类型的键在数据类型上是例外:复制出的列会采用该 serial 所存储的整数类型。在任何数据库下,smallserial 和 serial2 都对应 smallint,serial4 对应 integer,bigserial 和 serial8 对应 bigint。单独的 serial 在 PostgreSQL 下对应 integer,在 MySQL 和 MariaDB 下对应 bigint unsigned,在其他任何数据库下则仍为 serial。
只有完整的类型名称才算数(不区分大小写),因此 serial(4) 会按原样复制。以大写字母写成的类型会得到大写的结果:在 PostgreSQL 下,SERIAL 对应 INTEGER。已保存的图中类型已为 serial 的外键列会保留该类型。
若要使关系成为识别关系,可将子表上的这些外键列设为主键:选中所有这些列后按一次 Alt + K (Windows/Linux) 或 ⌥ + K (Mac),或者在表右键菜单中选择 Primary Key,选中两列或更多列时该条目会显示为 Primary Key on selected columns,参见列主键。

编辑器会自动保持该状态同步。
子表一侧的所有列都是主键时为识别关系,其中任意一列不再是主键时就会变为非识别关系。
外键列名
创建关系时,所添加的每个外键列都会以它所复制的父表键命名:
- 由一个单词组成的键名,例如
id、ID或uuid,会在前面加上父表的名称和一个下划线:products上的id会变为products_id。 - 由多个单词组成的键名,例如
member_id、userId或UserID,保持不变。 - 由一个单词组成且与表名相同(不区分大小写)的键名同样保持不变:
currency上的currency仍为currency。仅仅包含表名的键仍会加上前缀:user上的username会变为user_username。
名称只包含字母和数字、且大小写没有发生切换时,视为一个单词。
其他任何字符都会将其拆分,因此 _id、order no 和 order-no 都由多个单词组成。
大小写的切换同样会将其拆分,判断方式与 camelCase 相同:小写字母后跟大写字母(userId),两个大写字母后跟小写字母(IDCard、IDs),或者韩文、假名、汉字等没有大小写之分的文字与有大小写之分的字母相邻(회원ID)。
数字不会拆分单词,因此 id2 和 SHA256 都是一个单词。以同一种大小写写成的复合词也是一个单词:members 上的 memberid 会变为 members_memberid。
表名除去首尾空格外按原样使用:保留其大小写、中间的空格和点,不会转为单数形式,Code Generator 的 Table Name Case 与 Column Name Case 也不起作用。键为 ID 的 Users 会得到 Users_ID。
复合键的每一列都单独命名:键为 (tenant_id, id) 的 orders 会添加 tenant_id 和 orders_id。
子表中已有的名称(不区分大小写)会加上 _2、_3 等编号,取第一个未被占用的编号。
从键为 id 的 users 向同一张表再创建一条关系时,会添加 users_id_2;在键为 member_id 的 members 上创建自引用关系时,会添加 member_id_2。
同一个复合键的各列之间也按同样的方式编号,并且保持原样的名称优先占位:键为 (id, user_id) 的 user 会为 user_id 添加 user_id,为 id 添加 user_id_2。
父表没有名称时,键名保持不变,发生冲突时与其他名称一样加上编号。
没有名称的键会生成没有名称的外键列。
这也包括编辑器为没有主键的父表添加的主键,除非在点击子表之前为其命名。
这些名称在创建关系时确定。之后重命名父表或其键,不会随之重命名这些列。
映射列中的 New column 行也按相同的规则命名,列表会在选择之前显示每个名称。
通过导入、粘贴、创建副本或在映射列中与已有的列配对得到的关系,其列已经存在,因此会保留这些列原有的名称。
编码智能体通过 erd_add_relationship 添加关系时,得到的名称和数据类型与此相同,参见工具。
读懂连接线
- 识别关系以实线绘制,非识别关系以虚线绘制。
- 子表一端带有关系类型对应的基数符号:Zero One 为圆环和竖线,Zero N 为圆环和鸦爪,One Only 为两条竖线,One N 为竖线和鸦爪。
- 当任意外键列允许
NULL时,父表一端与 Zero One 相同,为圆环和竖线;当所有外键列均为NOT NULL时则与 One Only 相同,为两条竖线。 - 鼠标悬停在连接线上时,会同时高亮该连接线以及它在两个表中连接的列。

设置了 ON DELETE 或 ON UPDATE 的关系,会在其子表一端旁边带有一个标签,例如 D:C U:R:先是 D: 和 ON DELETE 操作,然后是 U: 和 ON UPDATE 操作,每一项都只在已设置时显示。
操作的缩写沿用 erwin 的表示法:C 表示 CASCADE,R 表示 RESTRICT,SN 表示 SET NULL,SD 表示 SET DEFAULT,NA 表示 NO ACTION。两项都未设置的关系没有标签。
标签位于远离子表的一侧:连接线从该表的左侧或右侧引出时,标签在线的上方;从顶部或底部引出时,标签在线的右侧,并且不会与基数符号重叠。
标签以连接线的颜色绘制在一个画布背景色的小方框上,并与其连接线一起高亮。标签绘制在所有连接线之上,因此穿过标签的线会从其下方经过。
无论所选数据库会写出什么,标签显示的都是保存在关系上的操作,因此在 MySQL 下,ON DELETE SET DEFAULT 仍然显示为 D:SD。
悬停在设置了任一操作的连接线上时,还会显示一个提示,逐行写出完整的子句,例如 ON DELETE CASCADE 和 ON UPDATE RESTRICT。
即使标签被隐藏,该提示也会出现。
通过 Relationship 显示选项可以隐藏 ERD 画布上的连接线,通过默认开启的 Referential Actions 显示选项则可以只隐藏其标签,参见表显示选项。
在 70% 及以下,表会折叠为名称,此时不绘制标签。
导出图片时始终以 100% 绘制,因此无论画布的缩放级别如何都会绘制标签,除非显示选项将其隐藏。关闭 Background 时,每个标签背后的方框也是透明的。
Visualization 标签页的 Flow 模式即使在 Relationship 关闭时也会绘制连接线,每条都是一根平滑的灰色实线曲线,端点符号与 ERD 画布相同,因此本页介绍的虚线、标签、提示与正交路径只适用于 ERD 画布。在 Flow 中,从表连接到其自身的关系同样会以曲线绕过右上角,参见连接线路径。
连接线路径
连接线按正交方式布置。
路径会绕开位于两端之间的表,而不是从表上穿过,拐角为圆角。
每一端都会先从其所在的表笔直引出一小段,然后才转弯,因此相距不远、连接线两端对齐的两个表会以一条直线相连,而不会绕行。
从表的同一侧引出的路径会被分到各自独立的通道上,以免相互重叠。
只会绕开表:连接线可以穿过备注或表分组的框,并且绘制在表分组之上、表和备注之下。
从表连接到其自身的关系会绘制为一条绕过该表右上角的曲线,在父表一端从顶部引出,在子表一端从右侧进入。
同一张表上的其他自引用关系会依次嵌套在第一条的外侧,因此它们的曲线既不会相互交叉,也不会穿过该表。
没有可配置的项目。
画布上有任何元素移动或改变大小时,路径都会自动重新计算,因此无需手动调整。
