logo头像

技术引领生活!

数据库建表范式

本文于1220天之前发表,文中内容可能已经过时。

设计口诀:

  • 多对多:
    多对多三张表,关系表辆外键

  • 一对多:
    一对多两张表,多的表加外键

  • 一对一(一张表拆分, 一对多特殊形式,如用户详细信息和简要信息):

    • 主键共享
    • 外键唯一

范式的目的

按照三范式设计的表不会出现冗余

第一范式

任何一张表都应该有主键, 并且每个字段原子不可再分

学生学号 学生姓名 联系方式
1001 张三 zhangsan@xx.com, 13xxxxxxx
1002 李四 lisi@xx.com, 13xxxxxxx

联系方式可再分

更改后

学生学号 学生姓名 email 电话
1001 张三 zhangsan@xx.com 13xxxxxxx
1002 李四 lisi@xx.com 13xxxxxxx

第二范式

建立在第一范式之上,所有的非主键字段完全依赖主键,不能产生部分依赖

学生学号 学生姓名 教师编号 教师姓名
1001 张三 001 赵老师
1002 李四 002 陈老师
1001 张三 002 陈老师

满足第一范式吗? 不满足,因为没有主键
关系为 多对多

所以确定主键

学生学号(PK) 教师编号(PK) 学生姓名 教师姓名
1001 001 张三 赵老师
1002 002 李四 陈老师
1001 002 张三 陈老师

此时,复合主键已经满足第一范式,但是不满足第二范式,此时存在数据冗余

多对多:三张表,关系表辆外键

学生表

sNo(PK) 姓名
1 张胜
2 李四
3 王五

老师表

tNo(PK) 姓名
1 王老师
2 张老师
3 李老师

关系表

id(PK) sno(fk) tno(fk)
1 1 3
2 1 1
3 2 2
4 2 3
5 3 1
6 3 3

第三范式

建立在第二范式基础上,所有非主键字段直接依赖主键,不能产生传递依赖

如学生班级表 一对多关系

学生学号(PK) 学生姓名 班级编号 班级名称
1001 张三 1 一年一班
1002 李四 2 一年二班
1001 张三 3 一年三班
1001 张三 4 一年四班

班级名称依赖于班级编号,但是班级编号依然依赖于学生学号(因为是主键)

一对多? 两张表多的表加外键

班级表t_class

cno(pk) cname
1 一班
2 二班

学生表t_student

sno(pk) sname classno(fk)
1 张三 1
2 李四 1
3 王五 2
4 周六 2
5 马五 2

一对多表设计

t_user_login 用户登录表

sno(pk) sname classno(fk)
1 张三 1
2 李四 1

t_user_detail 用户详细信息表(主键共享 主键为t_user_login的主键)

id(pk+fk) realname tel
1 张三 138xxxxx
2 李四 138yyyyy

t_user_detail 用户详细信息表(外键唯一约束)

id(pk) realname tel userid(fk+unique)
1 张三 138xxxxx 2
2 李四 138yyyyy 1
支付宝打赏 微信打赏

您的支持是我前行的动力!