范式是关系数据库理论的基础,也是我们在设计数据库结构过程中应该遵循的规则和指导方法。数据库的设计范式是数据库设计需要满足的规范。只有了解了数据库的设计范式,才能设计出高效优雅的数据库,否则就可能设计出错误的数据库。目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、Bath-Kord范式(BCNF)、第四范式(4NF)和第五范式(5NF,也称为完美范式)。满足最低要求的称为第一范式,简称1NF。在第一范式的基础上,第二范式称为第二范式,简称2NF。其余的依此类推。各种范式呈现不合标准,范式越高,数据库冗余越小。通常只使用前三种范式,即:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)。FirstNormalForm(1NF):强调的是列的原子性,即该列不能再分为其他列。简而言之,======第一范式是没有重复列的======。第二范式(2NF):首先要满足它是1NF,还需要包含两部分:一是表必须有主键;==二是不包括在主键中的列必须完全依赖于主键,而不是只依赖于主键的一部分。==即要求实体的属性完全依赖主关键字。所谓完全依赖,就是不能有属性只依赖主键的一部分。第三范式(3NF):在1NF的基础上,任何非关键属性不依赖于其他非关键属性【在2NF的基础上消除传递依赖】。第三范式(3NF)是第二范式(2NF)的子集,即满足第三范式(3NF)必须满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个关系不包含其他关系中已经包含的非主键信息。例如,有一个部门信息表,其中每个部门都有部门编号(dept_id)、部门名称、部门简介等信息。那么部门编号在员工信息表中列出后,部门名称、部门简介等与部门相关的信息就不能添加到员工信息表中了。如果没有部门信息表,也应该按照第三范式(3NF)构造,否则会出现大量的数据冗余。==简而言之,第三范式就是属性不依赖于其他非主属性,即在满足2NF的基础上,任何非主属性都不得传递依赖于主属性。==关于范式的讨论第二范式和第三范式有什么区别?第二范式:非主键列是否依赖于主键(包括通过某列间接依赖于主键的列),如果存在依赖则为第二范式;第三范式:非主键列是否直接依赖于主键,而不是通过关系依赖的那种。如果符合这个,就是第三范式;使用范式的优点和缺点是什么?==Paradigm可以避免数据冗余,减少数据库空间,减少维护数据完整性的麻烦。==范式在给我们带来上述好处的同时,也伴随着一些缺点:==按照范式的规范设计表,范式的层次越高,设计的表就越多。==如果表可能按第一范式设计,可能只有一张表,按第二范式设计表时,可能会出来两张或更多张表。如果用第三范式或更高范式设计这张表时,表数会比第二范式多。表越多,当我们查询一些数据的时候,就必须查询多个表中的数据,所以查询的时间要比在一个表中查询的时间高很多。也就是说,我们使用的范式越高,数据操作的性能就越低。所以,我们在使用范式设计表的时候,要根据具体的需要权衡是否使用更高的范式来设计表。在一般项目中,我们使用最多的是第三范式,第三范式可以满足我们的项目需求,性能好,数据管理方便;当我们的业务涉及到很多表的时候,往往会有很多表之间存在关联,我们需要以最快的速度对表进行操作。这时候,我们可以考虑使用“反范式”。不满足关于反范式的范式的模型是反范式模型。反范式与范式的要求恰恰相反。在反范式设计模式中,我们可以允许适当的数据冗余,并利用这种冗余来缩短操作数据的时间。本质上就是用空间换取时间,多个表中的冗余数据,查询时减少或避免表之间的关联;在RDBMS模型设计过程中,我们经常使用范式来约束我们的模型,但是在NOSQL模型中,大量使用了反范式。正常和反范式模型的比较优缺点非规范化模型数据冗余会带来很好的读取性能(因为不需要连接很多表,通常反范式模型很少进行更新操作)需要维护冗余数据,从目前NoSQL的发展来看,磁盘空间的消耗是可以接受的。归一化后的模型数据没有冗余,易于更新。当表数很大,查询设计需要很多关联模型(join)时,查询性能会降低。书中给大家举了很多栗子,归结为3句话:1NF:Fieldsareindivisible;2NF:有主键,非主键字段依赖于主键;3NF:非主键字段不能相互依赖;解释:1NF:原子字段不能再点,否则不是关系型数据库;2NF:唯一性,一张表只描述一个事物;3NF:每一列都与主键有直接关系,不存在传递依赖;不符合第一范式的例子(关系型数据库中不能这样创建)表:表:字段1,字段2(字段2.1,字段2.2),字段3...问题:因为这样的表不能设计好了,没有问题;不符合第二范式的例子:表:学号、姓名、年龄、课程名称、成绩、学分;这个表清楚地显示了两个事务:学生信息,课程信息;存在的问题:数据冗余,每条记录包含相同的信息;删除例外:删除所有学生成绩会删除所有课程信息;插入异常:学生未选课,无法录入数据库;更新异常:调整课程学分,调整所有行。修改:学生:Student(学号、姓名、年龄);课程:课程(课程名称,学分);选课关系:SelectCourse(学号、课程名称、年级)。满足第二范式只会消除插入异常。不符合第三范式的例子:学号、姓名、年龄、所在院校、学院联系电话,关键字为单个关键字“学号”;存在依赖转移:(学号)→(学院)→(学院所在地,学院电话)存在问题:数据冗余:存在重复值;更新异常:存在重复冗余信息,修改时需要同时修改多条记录,否则会出现数据不一致。删除异常更正:学生:(学号、姓名、年龄、院校);学院:(学院、地点、电话)。
