7、数据库的设计
1.多表之间的关系
①分类:
(1)一对一:
如:人和身份证
(2)一对多(多对一):
如:部门和员工
一个部门有多个员工,一个员工对应一个部门。
(3)多对多:
如:学生和课程
一个学生可以选择多个课程,一个课程可以被多个学生选择。
②实现:
(1)一对一:
实现方式:可以在任意一方添加唯一外键指向另一方的主键。
(2)一对多(多对一):
实现方式:在"多"的一方建立外键,指向"一"的一方的主键。
如:一个部门有多个员工,一个员工对应一个部门。(外键在员工表上--从表)
(3)多对多:
实现方式(联合主键):多对多的关系需要借助第三张中间表。
中间表至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键。
2.数据库设计的范式:
概念:设计数据库时,需要遵循的一些规范。要遵循后面的范式要求,必须先遵循前面的所有范式要求。
设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。
目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
分类:
1.第一范式:
每一列都是不可分割的原子数据项
例子:如图A中,第一范式的要求每一列都是不可分割的原子数据项不满足,即系中又分为系名和系主任列两项。
这时要把它拆成图B这样,才满足第一范式。
但是,此时仍然存在1.2.3的问题。就有了下面的第二范式。
A:
B:
2.第二范式:
在1NF的基础上,非码属性必须完全依赖于码属性[在1NF基础上消除非主属性对主码的部分函数依赖]
1)函数依赖:A-->B,如果通过A属性(属性组)的值,可以确定唯一B属性的值,则称B依赖于A。
例如:学号-->姓名。
2)完全函数依赖:A-->B,如果A是一个属性组,则B属性值的确定需要依赖于A属性组中所有的属性值。
例如:属性组:(学号,课程名称)-->分数
3)部分函数依赖:A-->B,如果A是一个属性组,则B属性值得确定只需要依赖于A属性组中某一些值即可。
例如:属性组:(学号,课程名称)-->姓名
4)传递函数依赖:A-->B,B-->C. 如果通过A属性(属性组)的值,可以确定唯一B属性的值,在通过B属性(属性组)的值可以确定唯一C属性的值,
则称C传递函数依赖于A。
例如:学号-->系名,系名-->系主任
5)码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码。
例如:该表中码为:(学号,课程名称)
概念:
主属性:码属性组中的所有属性
非主属性:除过码属性组的属性
所以,第二范式的意思就是说要消除部分依赖。
此时图C中就消除了部分依赖,这就是第二范式了,解决了数据冗余的问题。
但是还有2个问题没解决,看图D。
C:
D:
3.第三范式:
在1NF基础上,任何非主属性不依赖于其它非主属性[在2NF基础上消除传递依赖]
在第二范式的基础上,我们发现此时有传递依赖,即:学号–>系名,系名–>系主任。
解决方法:看图E
E:
总结:
第一范式,列名原子性。
第二范式,值存在的原子性。
第三范式,值不可拆分,只能把非依赖部分(传递依赖中A和C)的列再拆出来,形成一个单独的表。