关系数据库设计的目标:决策一个特定的关系模式R是否是“好”的范式。如果R不是好的范式,则将R分解为{R1, R2, …, Rn},使得每一个子模式都是好的模式,而且分解是无损链接分解。过程中涉及理论是函数依赖理论和多值依赖理论。我们这里只讨论函数依赖。
1、 Functional Dependencies
函数依赖是另一种完整性约束,对于消除数据冗余很重要,能够系统地改进数据库设计。
一个关系模式R上的函数依赖,表示为:A1, A2, …, An B,A1,A2,……,An以及B都是R的属性,这样表达的含义是属性集合(A1, A2, …, An) 的值唯一确定属性集合B的值。
很好理解,A中任意一个值不能唯一确定一个B中的值,那么函数依赖A——>B不成立,反之,B中任意一个值能唯一确定一个A中的值,所以B——>A成立。
继续函数依赖的例子:
已知关系模式EMP(ENAME, SSN, STARTDATE,ADDRESS, PHONE),SSN是key,可以看到
SSN → ENAME,SSN → STARTDATE,SSN → ADDRESS,SSN → PHONE都是成立的。因为SSN是key,唯一。
同样可以写成:
SSN → ENAME, STARTDATE, ADDRESS, PHONE
2、用函数依赖定义key
首先明白几个key的含义:
- 超键(super key):在关系中能唯一标识bai元组du的属性集称为关系模式zhi的超键
- 候选键(candidate key):不含有多dao余属性的超键称为候选键
- 主键(primary key):用户选作元组标识的一个候选键程序主键
比如一个小范围的所有人,没有重名的,考虑以下属性:身份证 姓名 性别 年龄
身份证唯一,所以是一个超键;
姓名唯一,所以是一个超键;
(姓名,性别)唯一,所以是一个超键;
(姓名,性别,年龄)唯一,所以是一个超键;
这里可以看出,超键的组合是唯一的,但可能不是最小唯一的;
身份证唯一,而且没有多余属性,所以是一个候选键;
姓名唯一,而且没有多余属性,所以是一个候选键
这里可以看出,候选键是没有多余属性的超键
一个关系的所有候选键中选择一个用来唯一确定关系的元组,这个候选键成为主键
如何用函数依赖来定义key呢?
- 如果K是superkey,当且仅当K ——> R成立。【注意】K ——>R中R表示关系模式,可以用属性集合来表示,即R={A1,A2,….,An}。
- candidate key:如果K是candidate key,当且仅当K ——> R 成立而且不存在α包含于 K,且 α ——> R成立(不存在K的一个子集α且α ——> R 成立)
函数依赖可以表达superkey无法表示的约束,例如下面的例子:关系模式inst_dept (ID, name, salary, dept_name, building, budget ),superkey 是(ID,dept_name)
我们可以期望函数依赖dept_name ——> budget和ID ——>building是成立的,但是dept_name ——>salary是否成立无法明确
这个例子更清晰表达有些约束无法用key来表达
例如某设计者设计的关系模式employee (SSN, Name, Rating, Hourly_Wage, Job_Desc),key为SSN,则SSN ——>Name, Rating,Hourly_Wage,Job_Decs。
但是有一个约束无法用key表达:不同级别的员工薪水不一样,比如阿里的员工岗位分为十个级别。一到三分为低端岗位,四等级的为初级专员,五等级的是高级工程师,六等级的为资深工程师,七等级的是技术专家,八等级为高级专家,九等级的是资深专家,最高等级的是研究员。(来自互联网,不一定准确),每个级别的工资不一样。这个约束可以表达为Rating ——> Hourly_Wage,但是rating不是key。三位员工,级别不同,小时薪水不同。(美国的支付方式)
3、函数依赖和冗余的关系
函数依赖和冗余的关系:函数依赖可以表达无法用superkey表达的约束,如前面的例子rating → hourly_wages。这时数据库中的数据会有冗余。
当我们发现关系模式中存在superkey无法表达的约束时,考虑将这个关系模式分解,例如employee (SSN, Name, Rating, Hourly_Wage, Job_Desc)。Key是SSN,存在函数依赖rating → hourly_wages,但是rating不是key。将这个关系模式分解为连个关系模式:employee (SSN, Name, Rating, Job_Desc)和Rating_Wage( Rating, Hourly_Wage)。数据没有冗余。
4、平凡函数依赖
一个函数依赖在所有的关系实例上都满足,称作平凡函数依赖。例如ID, name → ID,name → name
形式化表达:α → β is trivial if β ⊆ α 。函数依赖的右边是左边的子集。
5、 函数依赖的闭包
给定一个函数依赖集合F,能够从F逻辑推断的的所有函数依赖的集合称作F的闭包,,记做F+
6、总结
函数依赖与规范化设计的关系是什么?
函数依赖是精化和建立“好”关系模式的形式化方法,可以解决数据冗余问题、修改异常问题、Null问题
Normalization is a solved problem,所有的算法和证明都搞定了。