实体关系图(ER Diagram)
users
用户表
PK
id
BIGINT
username
VARCHAR(50)
email
VARCHAR(100)
created_at
TIMESTAMP
1
———⟡
N
一个用户可以有多个订单
orders
订单表
PK
id
BIGINT
FK
user_id
BIGINT
total_amount
DECIMAL(10,2)
status
VARCHAR(20)
PK
主键 (Primary Key)
FK
外键 (Foreign Key)
1 ———⟡ N
一对多关系
三种基本关系类型
一对一 (One-to-One)
users → user_profiles
一个用户只有一个详细资料
user_id UNIQUE
一对多 (One-to-Many)
users → orders
一个用户可以有多个订单
user_id FOREIGN KEY
多对多 (Many-to-Many)
students ↔ courses
一个学生可以选多门课,一门课可以有多个学生
中间表: enrollments - student_id FK - course_id FK
范式理论:从混乱到有序
{{ currentNorm.name }}
{{ currentNorm.desc }}
❌ {{ currentNorm.beforeTitle || '不符合' }}
{{ currentNorm.before }}
✅ {{ currentNorm.afterTitle || '符合' }}
{{ currentNorm.after }}
{{ currentNorm.note }}
反范式化:用空间换时间
场景:电商订单查询
范式化设计
orders: users:
- id - id
- user_id ⟐ - name
- total - email
- status
查询 SQL:
SELECT o.*, u.name, u.email FROM orders o JOIN users u ON o.user_id = u.id WHERE o.id = 123;
结果:
需要 JOIN,查询慢
→
反范式化设计
orders: - id - user_id - user_name ← 冗余 - user_email ← 冗余 - total - status
查询 SQL:
SELECT * FROM orders WHERE id = 123;
结果:
单表查询,速度快
查询性能提升,减少 JOIN
数据冗余,占用更多存储
更新时需同步冗余字段
实战:电商系统数据模型
用户模块
users
user_addresses
user_profiles
商品模块
categories
products
product_skus
product_inventory
订单模块
orders
order_items
payments
营销模块
coupons
user_coupons
promotions
users
1:N
orders
orders
1:N
order_items
products
1:N
product_skus
users & coupons
M:N
user_coupons
适度范式
核心业务表遵循 3NF,查询表适当反范式化
明确关系
通过外键约束保证数据完整性
预留扩展
使用 JSON 字段存储非结构化扩展数据
常见反模式及改进
{{ anti.title }}
❌ 问题
{{ anti.problem }}
✅ 改进
{{ anti.solution }}
{{ anti.impact }}