数据库设计:三大范式与主外键
数据库设计:三大范式与主外键
函数依赖
理解范式的前提。如果知道 A 的值就能确定 B 的值,就说 B 依赖于 A。知道学号就能确定姓名 → 姓名依赖学号。主键能确定整行所有字段。
三大范式(逐级递进)
第一范式 1NF:字段不可再分
每个单元格只存一个原子值。"联系方式"列同时放手机和邮箱就违反 1NF,应拆成两列。标签如果以逗号字符串存在一个字段里,查询和维护都困难(是否拆分取决于业务,标签系统常用关联表)。
第二范式 2NF:在 1NF 基础上消除部分依赖
针对联合主键——非主键字段必须依赖整个主键,不能只依赖其中一部分。
经典的"学生选课"表 (学号, 课程号) 为主键,但"课程名"只依赖课程号,就应拆出课程表:
选课表(学号, 课程号, 成绩)
课程表(课程号, 课程名)
学生表(学号, 姓名)
第三范式 3NF:在 2NF 基础上消除传递依赖
非主键字段不能依赖另一个非主键字段。订单表里出现"商品分类名",而分类名依赖商品、商品依赖订单主键 → 传递依赖,拆出商品表、分类表。
主键与外键
- 主键 PRIMARY KEY:唯一标识一行,非空不重复。推荐用与业务无关的自增 id(或雪花算法/UUID,考虑分布式和索引特性)
- 外键 FOREIGN KEY:引用另一张表的主键,保证引用完整性——不能引用不存在的商品;删除被引用的行会被阻止(级联策略 RESTRICT/CASCADE/SET NULL 按需选)
CREATE TABLE posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
category_id INTEGER,
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE SET NULL
);
范式的目的与反范式
范式解决三个异常:插入异常(缺信息无法插入)、更新异常(冗余数据改不全)、删除异常(删数据连带丢失有用信息)。
但范式不是越高越好——拆表越多 JOIN 越多。为了查询性能,实际项目常故意反范式:冗余一些字段(如订单快照里的商品名,下单时的价格必须固化),用空间换时间、用历史快照保真实。
设计心法:先按范式设计出逻辑模型,再根据查询模式和性能要求做受控的冗余,并明确冗余字段的同步策略。
看到这里了?如果这篇文章帮到过你
请我喝瓶可乐就好 🥤

评论0 条
还没有评论,来抢沙发~