Mermaid 实体关系图 #

实体关系图(Entity-Relationship Diagram,简称ER图)是数据库设计中用于表示实体、属性和它们之间关系的图表。

基本语法 #

1. 基本结构 #

mermaid
erDiagram
  实体1 ||--o{ 实体2 : "关系名称"
  实体1 {n}--|{ 实体3 : "另一个关系"

2. 实体定义 #

mermaid
erDiagram
  USER {
    int id PK
    string username
    string email
    string password
    date created_at
    date updated_at
  }

实体与属性 #

1. 实体 #

实体是具有相同属性的对象集合,通常用矩形表示:

mermaid
erDiagram
  USER {
    int id
    string username
    string email
  }
  
  ORDER {
    int id
    decimal total
    date order_date
  }

2. 属性类型 #

可以为属性指定类型:

mermaid
erDiagram
  PRODUCT {
    int id
    string name
    decimal price
    int stock
    boolean active
    date created_at
  }

3. 主键和外键 #

  • 使用 PK 标记主键
  • 使用 FK 标记外键
mermaid
erDiagram
  USER {
    int id PK
    string username
    string email
  }
  
  ORDER {
    int id PK
    int user_id FK
    decimal total
  }

关系类型 #

1. 一对一关系 (One-to-One) #

表示一个实体的实例最多对应另一个实体的一个实例:

mermaid
erDiagram
  USER ||--|| PROFILE : "拥有"
  
  USER {
    int id PK
    string username
  }
  
  PROFILE {
    int id PK
    string full_name
    string address
  }

2. 一对多关系 (One-to-Many) #

表示一个实体的实例可以对应另一个实体的多个实例:

mermaid
erDiagram
  USER ||--o{ ORDER : "下订单"
  
  USER {
    int id PK
    string username
  }
  
  ORDER {
    int id PK
    int user_id FK
    decimal total
  }

3. 多对多关系 (Many-to-Many) #

表示一个实体的多个实例可以对应另一个实体的多个实例:

mermaid
erDiagram
  ORDER ||--o{ ORDER_ITEM : "包含"
  PRODUCT ||--o{ ORDER_ITEM : "被包含"
  
  ORDER {
    int id PK
    decimal total
  }
  
  PRODUCT {
    int id PK
    string name
    decimal price
  }
  
  ORDER_ITEM {
    int id PK
    int order_id FK
    int product_id FK
    int quantity
    decimal price
  }

关系基数 #

基数表示关系中实体实例的数量限制:

符号组合 含义
`
`
}o--o{ 多对多
`}o–

1. 一对一关系示例 #

mermaid
erDiagram
  USER ||--|| ACCOUNT : "拥有"
  
  USER {
    int id PK
    string username
  }
  
  ACCOUNT {
    int id PK
    string account_number
    decimal balance
  }

2. 一对多关系示例 #

mermaid
erDiagram
  DEPARTMENT ||--o{ EMPLOYEE : "包含"
  
  DEPARTMENT {
    int id PK
    string name
  }
  
  EMPLOYEE {
    int id PK
    string name
    int department_id FK
  }

3. 多对多关系示例 #

mermaid
erDiagram
  STUDENT }o--o{ COURSE : "选修"
  
  STUDENT {
    int id PK
    string name
  }
  
  COURSE {
    int id PK
    string title
  }

关系名称 #

可以为关系添加名称,描述实体之间的关系:

mermaid
erDiagram
  CUSTOMER ||--o{ ORDER : "下订单"
  ORDER ||--o{ ORDER_ITEM : "包含"
  PRODUCT ||--o{ ORDER_ITEM : "被购买"
  CATEGORY ||--o{ PRODUCT : "分类"

高级功能 #

1. 复合主键 #

可以定义复合主键:

mermaid
erDiagram
  ORDER_ITEM {
    int order_id PK
    int product_id PK
    int quantity
    decimal price
  }

2. 可选属性 #

可以使用 ? 标记可选属性:

mermaid
erDiagram
  USER {
    int id PK
    string username
    string email
    string phone?
    string address?
  }

3. 唯一属性 #

可以使用 UK 标记唯一属性:

mermaid
erDiagram
  USER {
    int id PK
    string username UK
    string email UK
    string password
  }

4. 关系描述 #

可以在关系中添加描述:

mermaid
erDiagram
  USER ||--o{ ORDER : "一个用户可以下多个订单"
  ORDER ||--o{ ORDER_ITEM : "一个订单包含多个订单项"
  PRODUCT ||--o{ ORDER_ITEM : "一个产品可以出现在多个订单项中"

最佳实践 #

  1. 清晰的实体命名:使用单数名词,如USER而不是USERS
  2. 有意义的属性名称:使用描述性的名称,如created_at而不是date1
  3. 明确的关系类型:正确选择一对一、一对多或多对多关系
  4. 适当的主键设计:为每个实体设计合适的主键
  5. 合理的属性类型:选择合适的数据类型
  6. 避免循环依赖:尽量避免实体之间的循环依赖关系

常见问题 #

问题:关系箭头方向错误 #

解决方案:确保箭头指向正确,表示实体之间的关系方向

问题:多对多关系未正确表示 #

解决方案:在多对多关系中,需要创建中间表(连接表)

问题:属性类型不支持 #

解决方案:使用标准的数据类型,如intstringdecimal

完整示例 #

下面是一个完整的电子商务系统ER图示例:

mermaid
erDiagram
  USER {
    int id PK
    string username UK
    string email UK
    string password
    string full_name
    string address
    string phone
    date created_at
    date updated_at
  }
  
  CATEGORY {
    int id PK
    string name
    string description
    int parent_id FK
  }
  
  PRODUCT {
    int id PK
    string name
    string description
    decimal price
    int stock
    boolean active
    int category_id FK
    date created_at
    date updated_at
  }
  
  ORDER {
    int id PK
    int user_id FK
    string status
    decimal total_amount
    string shipping_address
    string payment_method
    date order_date
    date shipped_date
    date delivered_date
  }
  
  ORDER_ITEM {
    int id PK
    int order_id FK
    int product_id FK
    int quantity
    decimal unit_price
    decimal subtotal
  }
  
  REVIEW {
    int id PK
    int user_id FK
    int product_id FK
    int rating
    string comment
    date review_date
  }
  
  USER ||--o{ ORDER : "下订单"
  USER ||--o{ REVIEW : "写评论"
  CATEGORY ||--o{ PRODUCT : "分类"
  CATEGORY }|--|| CATEGORY : "子分类"
  PRODUCT ||--o{ ORDER_ITEM : "被包含"
  PRODUCT ||--o{ REVIEW : "被评论"
  ORDER ||--o{ ORDER_ITEM : "包含"
最后更新:2026-02-08