如何画 ER 图:完整教程 | text2diagram

ER 图的 6 个要素、4 种符号、3 种基数、9 条画法规范,以及怎么用 text2diagram 从一段领域描述直接生成。

发布于 ·13 分钟阅读
er-diagramtutorialdatabase-design

一、什么是 ER 图

ER 图 只需要认几个形状,再加一个念头:把现实世界描述成 事物事物之间的关系。ER 图(entity-relationship diagram,实体-联系图)画的是系统的数据结构 —— 有哪些东西、我们记录它们的哪些事实、它们之间怎么连。

这套模型是 Peter Chen 在 1976 年提出来的,五十年过去仍然是数据库设计的通用语言。在写 CREATE TABLE 之前先勾一张 ER 图,是因为表怎么建、外键怎么连、join 怎么写,形状都跟着这张图走。

ER 图由 6 个要素组成:实体属性实体集实体型联系。下面逐个讲,再讲怎么把它们拼成一张读得懂的图。

实体现实里你关心的、能区分开的一个具体东西 —— 某位顾客、某本书、某个订单。画成矩形。
属性实体的特征 —— 顾客的姓名、邮箱、生日。Chen 记法画成椭圆,现在常用的 crow's-foot / Mermaid 风格直接列在实体框里面。
实体集同一类实体的集合 —— 所有 顾客、所有 书。最后落到数据库里变成表的就是它。
能在实体集里唯一确定一个实体的属性(或者几个属性的组合)。不能为空,不能重复。Chen 记法加下划线,Mermaid 用 PK 标。
实体型实体的模式 —— 名字加上属性列表,写作 实体名(属性1, 属性2, __键__)。它是 类型,具体那一个实体是 实例
联系两个(或多个)实体之间有意义的连接 —— 顾客下单、学生选课。Chen 记法画菱形,crow's-foot / Mermaid 画一条带基数标记的线。

二、为什么要画 ER 图

3 个理由,每个都对应开发里的一个具体麻烦:

  • 在写代码之前把 schema 定下来。 一张画好的 ER 图能提前告诉你要建哪些表、每张表有哪些字段、外键怎么连 —— 在写第一条 migration 之前。图上改 schema 是几秒钟的事,代码里改是几小时。
  • 对照真实数据和你以为的样子。实际 流过系统的数据,画在 你以为会流过 的旁边,缺的连接和悬空的引用就露出来了。找孤儿记录和隐藏依赖,这是最快的办法。
  • 跟非技术的人沟通。 产品和业务看得懂矩形和连线,但不会去翻 schema.prisma。有了 ER 图,你可以拿同一张图跟 DBA 讲,也跟老板讲。

除了这 3 个理由,画 ER 图还有 3 个直接好处:

想法会被理清。 画图逼你给每个实体、每个属性、每种联系起名字。含糊的概念一进图就含糊不了 —— 「customer」和「user」是不是同一个东西?一个订单有一个收货地址还是多个?矩形和连线不接受含糊。

范式化的问题会提前暴露。 把 M:N 画成一条直线的时候,缺的中间实体一眼就看得见。一个实体扛了 40 个属性的时候,该拆的信号也很明显。在这里发现,比三个月后从一条慢 SQL 里发现便宜太多。

新人上手会变快。 一张 ER 图能顶一份二十页的 schema 文档。新同事、DBA、测试看同一张图,得到同一个结论,省掉每周一次的「这个字段什么意思」。

三、ER 图 4 大常用符号

ER 图的符号很少,而且是标准化的。认识下面 4 个形状,业界 90% 的 ER 图你都能读懂,也能自己画:

矩形实体。ER 图本质上就是一堆矩形加连线。名字用单数、首字母大写(Customer,不是 Customers)。双层矩形表示 弱实体,见第 6 节。
椭圆属性。椭圆用线挂在实体上。主键 属性下面要加下划线,这条视觉信号任何时候都不能省。现在的工具(Mermaid / dbdiagram)把椭圆折进实体框里变成字段列表,语义完全一样。
菱形联系。菱形画在两个实体 中间,写一个动词(下单、选课、拥有)。连线上必须标基数(1:1 / 1:N / M:N),见第 4 节。Mermaid 不画菱形,用连线加端点标记代替。
连线联系本身。Chen 记法在线上标 1 / N / M。crow's-foot / Mermaid 记法把符号放在线的 端点:|| 恰好一个、o| 零或一个、}| 一或多个、}o 零或多个。从实体那头往外读。

四、ER 图三大基数

再复杂的 ER 图,联系的基数也只有 3 种:

一对一(1:1)。 两边各一个。每位员工一张门禁卡,每张卡属于一位员工。实践中不多见 —— 1:1 通常直接合并成「给其中一个实体多加几列」就行了,除非有理由分开(隐私、存储、所有权边界)。

一对多(1:N)。 左边一个对应右边多个,右边每个只回连左边一个。一位顾客有多个订单,每个订单属于一位顾客。这是真实 schema 里 最常见 的形状,你画到的联系八成以上都是它。

多对多(M:N)。 两边都是多个。一位学生选多门课,一门课有多位学生。关系数据库表达不了 M:N,必须 引入一个 中间实体(比如 Enrollment),拆成两条 1:N。把 M:N 直接画成一条线是坏味道,它把真正要做的工作藏起来了。

选择很简单:两边真的有各自的生命周期或访问方式,才用 1:1;默认的父子关系用 1:N;两边都能独立存在、又能自由配对,用 M:N 加中间实体 —— 而且记住,中间实体自己常常也有属性(报名日期、成绩、角色)。

五、ER 图 9 条画法规范

一张 ER 图技术上没错,读起来还是可以很费劲。下面 9 条守住了,你的图会像 schema 文档一样清楚,而不是像谜题:

  • 实体名用单数,首字母大写。 Customer,不写 Customerscustomer。矩形代表的是 概念,写成复数会把类型和集合混在一起。
  • 每个实体都要有主键。 没有例外。如果你说不出它的主键,那它还不是实体,只是别的实体的一个属性。用 PK(Mermaid)或下划线(Chen)标出来。
  • 每条连线都标基数。 不要画没标注的连接。1:1 / 1:N / M:N,哪怕觉得显而易见也写上 —— 图是给不熟悉这套系统的人看的。
  • 联系用动词。 菱形(或连线)上写一个动作:下单、拥有、归属、引用。Order → Customer 没有信息量,Order 属于 Customer 才有。
  • M:N 不直连。 每个多对多都拆成一个中间实体加两条 1:N。画了 Student —M:N— Course,就重画成 Student —1:N— Enrollment —N:1— Course。中间实体自己也有主键,通常是复合键 (student_id, course_id)
  • 外键要标。 引用别的实体主键的字段,加 FK 标签。不标的话 join 关系就是隐形的,读者只能猜哪些字段最后会出现在 JOIN ... ON ... 里。
  • 属性都带类型。 每个属性写上数据类型(string / int / datetime / decimal 等)。同一张图里一半带类型一半不带,看着草率,也挡住后面用它生成代码。
  • 相关的实体摆在一起。 Order / OrderItem / Payment 放一堆,User / UserProfile / Session 放一堆。画布上的距离就是概念上的距离,主动用它。
  • 弱实体用双层矩形。 离开父实体就不成立的实体(没有 Order 就没有 OrderItem)是 弱实体,用双层边框的矩形,并标出识别性联系。见第 6 节。

六、复杂 ER 图的处理:弱实体与复合属性

实体超过 15 个左右,图就开始像地铁线路图。有两个办法能在不撑爆画布的前提下装下复杂度:

弱实体。 离开父实体就不成立的实体叫弱实体。典型例子是 OrderItem:脱开 Order 它没有意义,数据库里不可能存在一条「第 3 行,数量 2」却不知道属于 哪张 订单的记录。弱实体画成 双层边框矩形,用 双层菱形(识别性联系)连到父实体,它的键是 部分键 —— 只在父实体范围内唯一,比如 line_number 在一张 Order 里唯一。

复合属性和多值属性。 有些属性自己有结构:Address 里面有 street / city / postal_code / country。别把它拍成 4 个椭圆挂在 Customer 上,用 复合属性 分组。同理,一个 Product 可能有多个 tags —— Chen 记法画成 多值属性(双层椭圆),现在更常见的做法是提升成一个独立实体 ProductTag,用 1:N 连过去。

什么时候该拆:(a)属性开始有自己的属性(tag 带了颜色和描述,就不再只是一个字符串),或者(b)你发现自己在查「所有带某某属性的 X」—— 这种查询需要索引,索引需要独立的行,独立的行值得一个独立实体。

这些规范没变,变的是画法

传统工具(MySQL Workbench、dbdiagram、Lucidchart、draw.io)把你当描图员:每个实体自己摆、每条联系线自己拖、每个 crow's-foot 端点自己选。20 个实体的 ER 图要点半小时鼠标,加一条新联系还得重排三个邻居。

AI 生成 ER 图 把顺序倒过来:你用文字把领域说清楚 —— 「一个电商平台,顾客下单,订单包含商品」—— 布局交给图引擎。你的时间花在 画什么(有哪些实体、各带哪些属性)上,怎么画(位置、连线、基数标记)归 AI。

代价是,不加约束的 AI 生成会把第 5 节的规范挨个违反一遍。text2diagram 整套设计就是为了解决这件事。

七、text2diagram 是什么:AI ER 图生成器

text2diagram 是一个 AI ER 图生成器,有两种模式:快速模式(一句话出一张图,适合领域清楚的场景)和 对话模式(AI 先问 2-3 个问题再画,适合实体超过 5 个、或者含 M:N 的 schema)。每张图生成后都会按第 5 节那 9 条规范校验:

  • 每个实体都会有主键。 没有主键的实体不会被输出,也就是上面第 2 条,由结构保证。领域描述里主键不清楚的时候,对话模式会在画之前先问。
  • M:N 自动拆成中间实体。 检测到多对多就自动引入中间实体(比如 StudentCourse 之间的 Enrollment),并且反问一句这个中间实体有没有自己的属性(成绩、角色、时间戳)—— 第 5 条规范变成了一个问句。
  • 基数一律标出来。 每条线都用正确的 Mermaid crow's-foot 标记(||--o{ / }o--o{ 等),没标注的联系不会通过后处理。这是第 3 条。

八、prompt 模板:怎么描述一个领域

想让 AI 画好 ER 图,关键是 prompt 有结构。下面这个模板复制到 text2diagram 的对话模式里,填空就行:

Please draw an ER diagram for: <the domain>

Entities:
  - <EntityName>:
      - PK: <primary key field + type>
      - <attribute name>: <type>
      - <attribute name>: <type>
  - <EntityName>:
      ...

Relationships:
  - <EntityA> <verb> <EntityB> (<cardinality>)
    e.g. Customer places Order (1:N)
    e.g. Student enrolls in Course (M:N — junction: Enrollment, carries: grade, enrolled_at)

Weak entities (optional):
  - <WeakEntity> depends on <ParentEntity>, partial key: <field>

Notation: Mermaid ER (crow's-foot)

模板对应本文第 3-6 节。这 4 个字段填完,text2diagram 就有足够信息一次生成一张符合全部 9 条规范的图,不用来回问。

九、例子 1:一个简单的电商 schema

走一遍真实的 prompt,复制到 text2diagram 的对话模式:

Please draw an ER diagram for a small e-commerce site.

Entities:
  - Customer:
      - PK: id (uuid)
      - email: string
      - name: string
      - created_at: datetime
  - Order:
      - PK: id (uuid)
      - FK: customer_id (uuid)
      - total: decimal
      - status: string
      - placed_at: datetime
  - Product:
      - PK: id (uuid)
      - name: string
      - price: decimal
      - stock: int

Relationships:
  - Customer places Order (1:N)
  - Order contains Product (M:N — junction: OrderItem, carries: quantity, unit_price)

Notation: Mermaid ER

按下发送之后:

1. 先判断图的类型,识别出这是 ER 图,不是流程图也不是时序图。 2. 从描述里抽出 3 个实体、2 条联系,并且注意到有一处 M:N 需要中间实体。没有歧义,不用再问。 3. 必需的信息都齐了,直接开始生成。 4. 生成的 Mermaid ER 源码里有: - 4 个实体块:Customer / Order / Product,加上自动补出来的中间实体 OrderItem(第 5 条,M:N 拆分) - 每个实体的主键都显式标出(第 2 条) - Ordercustomer_idOrderItem 里的两个外键,都带 FK 标签(第 6 条) - 基数:Customer ||--o{ Order : "places"Order ||--o{ OrderItem : "contains"Product ||--o{ OrderItem : "listed in"(第 3、4 条) 5. 语义校验可能再问一句,比如「OrderItem 用一个合成主键,还是 (order_id, product_id) 复合主键?」,你确认或者改掉都行。

十、例子 2:带弱实体的选课系统

复杂一点的例子 —— 大学选课系统,有 M:N 的选课关系,讲次是弱实体,还有复合主键。Prompt:

Please draw an ER diagram for a university course registration system.

Entities:
  - Student:
      - PK: student_id (string)
      - name: string
      - major: string
      - year: int
  - Course:
      - PK: course_code (string, e.g. "CS101")
      - title: string
      - credits: int
      - department: string
  - Instructor:
      - PK: instructor_id (string)
      - name: string
      - email: string

Relationships:
  - Student enrolls in Course (M:N — junction: Enrollment, carries: enrolled_at, grade, status)
  - Instructor teaches Course (M:N — junction: TeachingAssignment, carries: semester, section_number)

Weak entities:
  - Session depends on Course (partial key: session_number)
    A Course has multiple Sessions across a semester (Session 1, 2, 3, ...).
    Session attributes: topic (string), scheduled_at (datetime), room (string).

Notation: Mermaid ER (crow's-foot)

生成结果里值得注意的地方:

- 主图 7 个实体左右(3 个核心 + 2 个中间 + 1 个弱实体),一眼能扫完。 - EnrollmentTeachingAssignment 是带自己属性的 中间实体(第 5 条)。 - Session 画成 双层边框矩形,用 双层识别性联系 连到 Course(第 9 条)。 - 所有主键和外键都显式标出(第 2、6 条)。 - 实体名单数、首字母大写(第 1 条);每个属性带类型(第 7 条)。 - 相关实体摆在一起 —— Course 放在 Enrollment / TeachingAssignment / Session 中间,因为它们都连到它(第 8 条)。

对话模式这时可能会问你一句:Session 的部分键是单独一个 session_number(只在一门课里唯一),还是要加上 semester?」 —— 因为 prompt 里没说讲次跨不跨学期。这正是对话模式的用处:把你自己没注意到的歧义先问出来。

十一、总结:2026 年如何画 ER 图

2026 年 如何画 ER 图,拆成两件事:

1. 把领域想清楚 —— 6 个要素(实体 / 属性 / 实体集 / 键 / 实体型 / 联系)、4 种符号、3 种基数、9 条规范、弱实体。这部分从 1976 年到现在没变过。 2. 布局交给 AI —— 用有结构的 prompt 描述领域,让 text2diagram 把每条规范落实、把每个 M:N 拆成中间实体,几秒钟出图。

会不会描图已经不重要了,能不能把领域说清楚才重要。prompt 写对,schema 自己就画好了。

拿一个你一直拖着没建模的领域试一遍 —— 一分钟之后,你对它的理解会清楚很多。这就是现在 如何画 ER 图 的做法,不用打开 MySQL Workbench。

常见问题

接着读

去试试 text2diagram

打开工具
← 回到全部教程