数据库概念:码 键 Key & 范式 Normal Form
参考资料
- 数据库管理系统原理与设计(Database Mangement System 3rd)
- 百度
- wiki
术语对照
- 码 = 键 = Key
- 码约束 = Key Constraints
码约束
码(key)
能够唯一区分关系中各个记录的最小字段集合称为码(Key)。
唯一性
要作为一个关系表的码那么它肯定是在所有记录中都唯一的,否则给出一个码就不能唯一的获得一条记录。由于字段意义是于实际业务强关联的,唯一性也需要根据实际进行分析定义。如一个学校可以根据每个人得学号唯一的找到学生,但是当系统扩展到多个学校时,学号就不具有唯一性了。
最小
码除了唯一性要求外还要求它是满足唯一性的最小的一个字段集合。这个表达起来可能有些歧义,这个最小是相对于已经能够体现唯一性的条件的字段集合来说的。即码中不能有对体现唯一性没有帮助的字段。举个例子在某个地区几个学校中确定一个学生可以使用(学校id,学生校内id)作为一个码,此时将什么班级编号加入其中并没什么用。或者说码中字段的子集肯定不具有唯一性。
对于上面的例子还可以把(学校id,校内年级序号,班级序号,班内学生序号)作为一个码,所以码的最小
这个约束是对已经具有唯一性的一个字段集合来讲的,而不是各个具有唯一性的码集合之间选择包含字段数最少的一个。因此码可以存在多个。
候选码(candidate key)
即关系上的所有码
主码(primary key)
从候选码里挑一个作为主要查询依据,是一个人为选择的结果。
超码 (super key)
包含码的一个字段集合
范式
范式就跟设计模式一样,是人为指定的规范形式。它主要用来消除数据库存储时的冗余和操作异常。一般数据库设计应该符合3NF,BCNF。
范式种类
1NF
第一范式要求关系模式R中的每个元素都是不可再分的,即数据表中的列已经是基本字段了。比如一个存储地址信息可以是将省市区街道连起来做为一个单一字段,也可以是把各个级别分别存储。这取决于系统中是否需要细粒度的区域地址信息,其实就是从使用需求上来看该字段是否可分。
另外一列中也不能出现同类型字段值组合的情况,而是应该分成多行进行记录。如关系take_course(name, course),不能出现
Mao, Math&Science
这样的情况而是应该存储为
Mao, Math
Mao, Science
不过许多系统会把某一个长整数类型的列用来存储权限,不同的bit代表不同的权限。权限列实际上存储了组合值,一定程度上违反了1NF。不过由于这样存储的权限值一般也不会用于连接或者做特定权限的选择(比如选出所有具有删除权限的用户)操作,是可以接受的。当系统内权限类型比较多且会动态添加或者改变时就不能使用这种方案了。
2NF
第二范式要求表中记录能被唯一的区分,且不存在部分依赖,且满足第一范式。
唯一区分
为了唯一区分关系表中的记录,可以选择一个码作为区分依据。
部分依赖
如果有依赖X->A,那么就是X决定A,相当于一个函数的关系,比如身份证号->姓名。X和A可以对应字段集合。关系表R中的部分依赖就是对于一个依赖X->A中的X仅仅是关系码中的部分字段。举个例子如果有关系(班级编号,班内学生编号,学生姓名,学生平均分,班主任),可以选择(班级编号,班内学生编号)作为码,但这个关系中存在一个部分依赖:班级编号->班主任。
可见如果有多少个学生,班主任这个字段就要被存储多少次。但实际上班主任字段被存储的次数应该只需好班级数目想匹配即可(毕竟一个班级一个班主任)。如果某个班级更换了班主任,则更新操作需要比分开存储多做许多(只需一次更新)。
3NF
第三范式要求满足2NF,且不存在多数传递依赖。对于关系R上的所有依赖X->A满足:
- A是X的一部分
- X是R的超码
- A是R的码的一部分
假设存在一个关系:take_course(student, course, book, price, press)就有依赖course->book(属于部分依赖违反2NF), book->price(属于传递依赖,book不是R的超码,price也不是码的一部分)。所以应该分为三个关系take_course(student, course),course_book(course, book),bookinfo(book, price, press)
BCNF (boyce-codd NF)
对于关系R上的所有依赖X->A满足:
- A是X的一部分
- X是R的超码
它的定义比3NF更严格一些。可以理解为每个属性都是在描述由码确定的当前实体或者关系。