什么是数据库关系图(database diagram)?
数据库关系图是用图形方式描述数据库结构的一张“地图”:它把表(实体)画成方框,把字段(属性)列在方框内,再用连线表示表与表之间的主外键和一对多、多对多等关系。它适合在动手建表之前理清结构,也适合在团队评审、交接和写文档时作为共同参照。如果你只是要快速画出一张能沟通的关系图,用 DSL 文本描述再自动生成图形,通常比拖拽画图更快、更易维护。
数据库关系图和 ER 图是一回事吗
日常语境里两者经常混用,但侧重点略有不同:
| 叫法 | 侧重点 | 典型使用场景 |
|---|---|---|
| ER 图(实体-关系图) | 概念建模,强调实体、属性和业务关系 | 需求分析、领域建模 |
| 数据库关系图 | 物理建模,贴近真实表结构 | 建表、迁移、文档、评审 |
实际工作中,很多工具画出来的图同时具备两者特征:方框里是表名和字段,连线两端标注一对多或多对多。你不必纠结叫法,关键是图要能回答“有哪些表、每张表存什么、表之间怎么关联”。
图里通常包含哪些元素
- 实体(表):一个方框代表一张表,例如
users、orders。 - 属性(字段):方框内列出列名和类型,例如
id int、email varchar。 - 主键(PK):唯一标识一行,通常标
PK。 - 外键(FK):指向另一张表的主键,是关系的落点,通常标
FK。 - 关系与基数:连线表示关联,两端标注基数,如一对多(1:N)、多对多(M:N)、一对一(1:1)。
- 可选性:关系两端是否必须存在,例如一个订单必须属于某个用户,而一个用户可以有零个或多个订单。
多对多关系在物理建模时通常需要一张中间表(关联表)来承载,例如 user_roles 连接 users 和 roles。
常见的三种画法
用 DSL 文本描述后生成
以 dbdiagram.io 为例,它提供一种简单的 DSL 语言,你写表定义和关系,工具渲染成图。适合版本管理,因为文本可以进 Git、可以 diff。
Table users {
id int [pk]
email varchar
created_at timestamp
}
Table orders {
id int [pk]
user_id int [ref: > users.id]
total decimal
}
[ref: > users.id] 表示 orders.user_id 指向 users.id,即一个用户对应多个订单。改文本,图会同步更新。
用可视化工具拖拽
在画布上新建表、加字段、拉连线。上手直观,适合边讨论边改;缺点是结构复杂后手工维护成本高,改动容易漏。
从现有 SQL 反向生成
如果数据库已经存在,可以把建表语句导入支持反向工程的工具,自动生成关系图。适合接手老项目时快速看清现状,再据此补文档。
从零画一张关系图的步骤
- 列出核心实体:先写业务里最重要的名词,例如用户、订单、商品、支付。
- 给每张表定字段:至少确定主键;外键先留占位,等关系理清再补。
- 确定关系与基数:逐对问“一个 A 对应几个 B,一个 B 对应几个 A”,把答案标在连线上。
- 处理多对多:需要中间表时补上,并给它自己的主键或联合主键。
- 检查命名一致性:表名、字段名风格统一,外键命名能看出指向,例如
user_id指向users。 - 评审并迭代:拿图对照真实查询和业务规则,发现缺字段或错基数就改。
验证方法很直接:照着图写出建表 SQL,看能否表达出你需要的查询;或者拿几条真实业务问题去图上走一遍,看关系是否够用。
常见误区
- 只画表不标基数:连线没有 1:N 或 M:N,读者无法判断一条记录能对应几条。
- 忽略可选性:不区分“必须关联”和“可以没有”,会导致建表时 NOT NULL 判断错误。
- 命名不统一:同一含义在不同表里叫
user_id、uid、userID,后期维护和联表容易出错。 - 把图当一次性产物:结构改了图没改,文档很快失效。用 DSL 或反向生成能降低同步成本。
- 过早陷入物理细节:概念阶段就纠结索引和分区,反而拖慢关系梳理。
数据库关系图的价值不在画得漂亮,而在于让结构可讨论、可核对、可更新。选一种能跟上你改动节奏的方式,比选功能最多的工具更重要。