范式
范式,设计的越详细,对于某些实际操作可能更好,但是不一定都是好处,在实际应用中,应当具体情况具体分析
数据依赖
数据依赖有三种类型
函数依赖
设R(U)是一个属性集U上的关系模式,X和Y是U的子集,若对于R(U)的任意一个可能的关系r,r中不可能存在两个元组在X上的属性值相等,而在Y上的属性值不等
则称“X函数确定Y”或“Y函数依赖于X”,记作X→Y,X成为这个函数依赖的决定属性集
例:每个学校对应一个校长,当学校确定时,校长也确定了,则称“学校确定校长”,或者“校长依赖于学校”,记作学校→校长
平凡函数依赖
如果X→Y,但是X不属于Y,则称X→Y是非平凡的函数依赖
如果X→Y,但是X属于Y,则称X→Y是平凡的函数依赖
例:(学号,课程号)→ 成绩 是非平凡函数依赖
(学号,课程号)→ 学号 是平凡函数依赖
(学号,课程号)→ 课程号 是平凡函数依赖
完全函数依赖
如果单独一个函数能决定一个依赖,则称该依赖为完全函数依赖,如果一个函数的部分可以决定一个依赖,则称该依赖为部分函数依赖
例:学号→姓名 完全函数依赖
(学号,课程号)→ 姓名 部分函数依赖(学号自己就能决定姓名)
(学号,课程号)→ 成绩 完全函数依赖(由学号和课程号共同决定成绩)
传递函数依赖
如果X→Y,Y→Z,且Y不属于X,Y不决定X,则称Z传递函数依赖于X
如果Y→X,即X←→Y,则Z直接依赖于X
第一范式(1NF)
数据表中的字段都是不可分割的原子值
例如:中国四川省成都市武侯区武侯大道100号
这个地址可以拆分为国家、省、市等信息,不满足第一范式的不可分割的要求,因此这个地址不满足第一范式
第二范式(2NF)
必须在满足第一范式的前提下,第二范式要求,除主键外的每一列都必须完全依赖于主键
如果要出现不完全依赖,只可能发生在联合主键的情况下
通俗来说,主键必须能决定其他列(例:学校决定校长)
当出现除主键外的其他列,只依赖于主键的部分字段时,将不满足第二范式
此时可以拆表
例:新建一个订单表
这个表使用了联合主键(product_id,customer_id),但是product_name于customer都部分依赖于主键,因此不满足第二范式,此时应该将这个表拆开
create table myorder(
order_id int primary key,
product_id int,
customer_id int
);
create table product(
id int primary key,
name varchar(20)
);
create table customer(
id int primary key,
name varchar(20)
);
第三范式(3NF)
必须先满足第二范式,除开主键列的其他列之间不能有传递依赖关系
例:
create table myorder(
order_id int primary key,
product_id int,
customer_id int,
customer_phone varchar(15)
);
在这个例子中,customer_phone这个属性就和customer_id、order_id之间存在传递依赖,因此不满足第三范式
应该将上述例子拆分
create table myorder(
order_id int primary key,
product_id int,
customer_id int
);
create teble customer(
id int primary key,
name varchar(20),
phone varchar(15)
);
这样才满足第三范式