数据库设计规范
数据库范式
数据库范式是一套用于设计关系数据库的规范化标准,其目的是减少数据冗余并提高数据的完整性和一致性。范式化是一种将数据库表设计成符合一定级别的过程,每个级别称为一个范式。通过范式化,可以减少数据存储中的冗余,同时避免潜在的数据不一致问题。
数据库范式通常分为六个级别,其中最常用的是前三范式(1NF、2NF、3NF):
1. 第一范式 (1NF)
第一范式要求表中的每一列都是不可分割的原子值,即每个单元格中只包含一个值。这确保了表中的每一列都是单一的事实,而不是列表或集合。例如,如果有一个“联系方式”列包含了电话号码和电子邮件地址,则这样的设计就不符合第一范式。
不符合1NF的例子:
假设我们有一个学生
表,记录学生的姓名和他们所选的课程:
学号 | 姓名 | 课程 |
---|---|---|
S001 | 张三 | 数学, 物理 |
S002 | 李四 | 英语 |
这个表不是1NF,因为“课程”这一列包含了多个值(数学和物理),而1NF要求每一列都应该是原子的,即不可再分。
符合1NF的例子:
为了使上述表符合1NF,我们可以将其拆分成两个表:
- 学生表:
学号 | 姓名 |
---|---|
S001 | 张三 |
S002 | 李四 |
- 选课表:
学号 | 课程 |
---|---|
S001 | 数学 |
S001 | 物理 |
S002 | 英语 |
2. 第二范式 (2NF)
第二范式建立在第一范式的基础上,要求所有的非主键字段完全依赖于主键。这意味着表中的非主键字段不能部分依赖于主键的一部分。例如,如果主键是一个复合键,那么所有非主键字段都必须依赖于整个复合键,而不仅仅是部分主键。
不符合2NF的例子:
假设我们有一个员工
表,记录员工的基本信息以及部门信息:
员工ID | 名字 | 部门名称 | 部门地址 |
---|---|---|---|
E001 | 王五 | 销售 | 北京 |
E002 | 赵六 | 技术 | 上海 |
这里的问题在于,部门名称和部门地址是依赖于部门的,而不是单独依赖于员工ID。如果部门信息发生变化,就需要在每个员工记录中更新,这样容易导致数据不一致。
符合2NF的例子:
为了使上述表符合2NF,我们需要将部门信息提取出来:
- 员工表:
员工ID | 名字 | 部门ID |
---|---|---|
E001 | 王五 | D001 |
E002 | 赵六 | D002 |
- 部门表:
部门ID | 部门名称 | 部门地址 |
---|---|---|
D001 | 销售 | 北京 |
D002 | 技术 | 上海 |
3. 第三范式 (3NF)
第三范式进一步加强了第二范式的要求,它要求所有非主键字段直接依赖于主键,而不是通过另一个非主键字段间接依赖于主键(即避免传递依赖)。例如,如果存在一个表,其中一个非主键字段依赖于另一个非主键字段,那么就需要将它们分离到不同的表中。
不符合3NF的例子:
考虑以下一个学生-课程-教师的示例:
学号 | 课程编号 | 教师编号 | 教师姓名 |
---|---|---|---|
S001 | C001 | T001 | 刘老师 |
S002 | C002 | T002 | 陈老师 |
在这个表中,教师姓名直接与学生关联,而没有直接依赖于主键(学号),而是依赖于教师编号。这是一个传递依赖的例子,因此不符合3NF。
符合3NF的例子:
为了使上述表符合3NF,我们需要创建一个新的教师表:
- 学生表:
学号 | 课程编号 | 教师编号 |
---|---|---|
S001 | C001 | T001 |
S002 | C002 | T002 |
- 教师表:
教师编号 | 教师姓名 |
---|---|
T001 | 刘老师 |
T002 | 陈老师 |
除了这三个主要的范式之外,还有更高层次的范式:
4. BCNF (Boys-Codd范式)
BCNF范式要求每个决定因素都是一个超键。这意味着除了主键之外,没有任何其他字段可以决定任何非键字段。
不符合BCNF的例子:
假设我们有一个图书作者
表,记录书籍的信息以及作者的信息:
图书ID | 书名 | 作者ID | 作者名 | 作者国籍 |
---|---|---|---|---|
B001 | 梦幻森林 | A001 | 小明 | 中国 |
B002 | 星际旅行 | A002 | 小红 | 美国 |
B003 | 梦幻森林 | A001 | 小明 | 中国 |
在这个表中,作者名
和作者国籍
依赖于作者ID
,而不是直接依赖于图书ID
。此外,如果我们只改变某本书的作者信息,那么所有包含该作者的记录都需要更新。这表明存在部分依赖(作者名
和作者国籍
依赖于作者ID
)和传递依赖(作者国籍
依赖于作者ID
),这使得该表不符合BCNF的要求。
符合BCNF的例子:
为了使上述表符合BCNF,我们需要将作者信息分离到另一个表中:
- 图书表:
图书ID | 书名 | 作者ID |
---|---|---|
B001 | 梦幻森林 | A001 |
B002 | 星际旅行 | A002 |
B003 | 梦幻森林 | A001 |
- 作者表:
作者ID | 作者名 | 作者国籍 |
---|---|---|
A001 | 小明 | 中国 |
A002 | 小红 | 美国 |
现在,图书表
中的每一项都是基于图书ID
和作者ID
这两个组合键,而作者表
中的每一项都是基于作者ID
。在这种情况下,没有任何非平凡函数依赖涉及非候选键的情况,因此这两个表都符合BCNF的要求。
5. 第四范式 (4NF)
第四范式是在BCNF的基础上进一步消除非平凡的多值依赖。
6. 第五范式 (5NF):
第五范式,也被称为完美范式或PJ范式,关注的是关系模式在连接操作后的数据一致性。
范式化的过程通常涉及到将数据分解成多个相互关联的表,以确保每个表都有一个明确的主题或目的,并且表中的每个字段都直接依赖于主键。虽然遵循范式可以带来许多好处,但在实际应用中,有时候为了提高查询性能或其他原因,可能会选择不完全遵循这些范式,而是采用一定程度的反范式化(denormalization)。
关于键:
- 超键(super key): 在关系中能唯一标识元组的属性集称为关系模式的超键
只要含有“学号”或者“身份证号”两个属性的集合就叫超键,例如R1(学号 性别)、R2(身份证号 身高)、R3(学号 身份证号)等等都可以称为超键! - 候选键(candidate key): 不含有多余属性的超键称为候选键。也就是在候选键中,若再删除属性,就不是键了!
不含有多余的属性的超键,比如(学号)、(身份证号)都是候选键,又比如R1中学号这一个属性就可以唯一标识元组了,而有没有性别这一属性对是否唯一标识元组没有任何的影响! - 主键(primary key): 用户选作元组标识的一个候选键程序主键
就是用户从很多候选键选出来的一个键就是主键,比如你要求学号是主键,那么身份证号就不可以是主键了 - 外键(foreign key):如果关系模式R中属性K是其它模式的主键,那么k在模式R中称为外键。
宿舍号就是学生信息表的外键