数据库的一二三范式
- 格式:docx
- 大小:21.44 KB
- 文档页数:8
一二三范式判定方法嘿,朋友们!今天咱来聊聊这神奇的一二三范式判定方法呀!你说这一二三范式,就好像是整理房间一样。
第一范式呢,就像是把乱七八糟扔在地上的东西都先捡起来,别管啥类型,都先放一堆。
比如说一个表里面,每个字段都得有值,不能有啥都没有的情况,这就是最基本的整理啦!那第二范式呢,就好比把捡起来的东西开始分类啦!不能把毫不相干的东西还放在一起呀。
就像表中的字段,得和主键有直接关系,不能乱七八糟的啥都有,不然找东西的时候不就晕头转向啦?你想想看,如果你的房间里衣服、书、玩具都混在一起,找起来得多费劲呀!再说说这第三范式,那就更精细啦!分类好了,还得把那些多余的、可以通过其他方式推导出来的东西给清理掉。
就好比房间里已经分好类了,可有些东西其实通过其他东西就能知道,那就没必要留着占地方啦!表中也是一样,不能有那些可以通过其他字段推出来的冗余信息呀。
咱举个例子哈,比如说一个学生信息表,有学生姓名、学号、班级这些字段。
第一范式就是保证每个字段都有值呀,不能有个学生姓名是空白的。
第二范式呢,就是班级这个字段得和学号有直接关系呀,不能随便塞个班级进去。
第三范式呢,就像不能有个字段是通过学号和其他字段能算出来的,那就没必要留着啦!这一二三范式多重要啊,就像盖房子打基础一样,基础不牢,房子能稳吗?要是不遵守这些范式,那数据不就乱成一团麻啦!到时候找个信息都找不着,那不就麻烦大啦!你说要是数据不规范,就好像走路没走稳,能走得远吗?肯定不行呀!所以咱得重视这一二三范式,把数据整理得井井有条的,这样用起来才顺手呀!这就好像做饭一样,食材得准备好,步骤得清楚,才能做出美味的菜肴。
数据也是一样,得按照规则来,才能发挥出它最大的作用。
朋友们,可别小瞧了这一二三范式呀!它们可是能让我们的数据世界变得清晰明了的法宝呢!让我们都好好运用起来,把数据整理得妥妥当当的,让我们的工作和生活都更加顺畅呀!怎么样,是不是觉得这一二三范式很有意思呀?赶紧去试试吧!。
什么是数据库三⼤范式,它们是做什么的?设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越⾼的范式数据库冗余越⼩。
关系数据库有六种范式:第⼀范式(1NF)、第⼆范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,⼜称完美范式)。
满⾜最低要求的范式是第⼀范式(1NF)。
在第⼀范式的基础上进⼀步满⾜更多规范要求的称为第⼆范式(2NF),其余范式以次类推。
⼀般来说,数据库只需满⾜第三范式(3NF)就⾏了。
1、第⼀范式(1NF):所谓第⼀范式(1NF)是指在关系模型中,对于添加的⼀个规范要求,所有的域都应该是原⼦性的,即数据库表的每⼀列都是不可分割的原⼦数据项,⽽不能是集合,数组,记录等⾮原⼦数据项。
即实体中的某个属性有多个值时,必须拆分为不同的属性。
在符合第⼀范式(1NF)表中的每个域值只能是实体的⼀个属性或⼀个属性的⼀部分。
简⽽⾔之,第⼀范式就是⽆重复的域。
2、第⼆范式(2NF)在1NF的基础上,⾮码属性必须完全依赖于候选码(在1NF基础上消除⾮主属性对主码的部分函数依赖)第⼆范式(2NF)是在第⼀范式(1NF)的基础上建⽴起来的,即满⾜第⼆范式(2NF)必须先满⾜第⼀范式(1NF)。
第⼆范式(2NF)要求数据库表中的每个实例或记录必须可以被唯⼀地区分。
选取⼀个能区分每个实体的属性或属性组,作为实体的唯⼀标识。
例如在员⼯表中的⾝份证号码即可实现每个⼀员⼯的区分,该⾝份证号码即为候选键,任何⼀个候选键都可以被选作主键。
在找不到候选键时,可额外增加属性以实现区分,如果在员⼯关系中,没有对其⾝份证号进⾏存储,⽽姓名可能会在数据库运⾏的某个时间重复,⽆法区分出实体时,设计辟如ID等不重复的编号以实现区分,被添加的编号或ID选作主键。
(该主键的添加是在ER设计时添加,不是建库时随意添加),第⼆范式(2NF)要求实体的属性完全依赖于主关键字。
数据库的一二三范式数据库的一二三范式是关系数据库设计中的重要概念,它们是用来规范数据库表的结构,确保数据的一致性和完整性。
本文将分别介绍一二三范式的定义和应用。
一范式(1NF):消除重复的数据一范式要求数据库表的每个字段都是原子性的,即不可再分。
也就是说,一个字段不能包含多个值。
如果一个字段需要包含多个值,就需要将其拆分成多个独立的字段。
这样可以避免数据冗余和更新异常。
例如,我们有一个学生表,其中的一个字段是“课程”,如果一个学生选修了多门课程,我们可以将“课程”字段拆分成多个字段,比如“课程1”,“课程2”等。
二范式(2NF):消除非主属性对主键的部分依赖二范式要求数据库表中的非主属性都完全依赖于主键,而不是依赖于主键的一部分。
如果一个表存在非主属性对主键的部分依赖,就需要将其拆分成多个表,以消除数据冗余和更新异常。
例如,我们有一个订单表,其中的字段有“订单号”、“产品名称”、“产品价格”和“产品数量”。
订单号是主键,产品名称、产品价格和产品数量都依赖于订单号。
但是,产品名称和产品价格之间存在函数依赖关系,即产品名称确定了产品价格。
为了满足二范式,我们可以将产品名称和产品价格拆分成一个独立的表。
三范式(3NF):消除传递依赖三范式要求数据库表中的非主属性不依赖于其他非主属性,而是直接依赖于主键。
如果一个表存在传递依赖,就需要将其拆分成多个表,以消除数据冗余和更新异常。
例如,我们有一个员工表,其中的字段有“员工号”、“员工姓名”、“部门号”和“部门名称”。
员工号是主键,员工姓名依赖于员工号,部门名称依赖于部门号。
但是,员工姓名和部门名称之间存在传递依赖,即员工号确定了部门号,部门号确定了部门名称。
为了满足三范式,我们可以将部门名称拆分成一个独立的表。
总结:数据库的一二三范式是关系数据库设计中的基本规范,用于规范数据库表的结构,保证数据的一致性和完整性。
一范式消除重复的数据,二范式消除非主属性对主键的部分依赖,三范式消除传递依赖。
第二范式和第三范式的区别第二范式和第三范式是设计数据库应用程序时,必不可少的设计原则,被广泛用于处理和存储在多个表之间的数据的方式之一。
集中在这两个范式的主要区别之处,就是它们的实现方式以及它们的数据解耦能力,提高了程序的可读性,并提高了数据库的性能。
首先,让我们来谈谈第二范式(2NF)。
第二范式是第一范式(1NF)的延伸,主要是为了确保表仅包含单个表内的属性,而不会混合两个表中的概念。
它要求每个表都必须有一个主键,且在表中其余的列必须完全依赖于主键。
如果这原则得到了满足,则表将被认为是第二范式的结果,这样可以避免冗余数据的复制,也可以降低数据库中的冗余信息。
然而,第三范式(3NF)则是在第二范式的基础上发展而来的。
它要求表中每一个字段都必须与主键或其他字段在数据库中有直接关联。
一个表如果满足第三范式,意味着每一个属性都与主键直接相关,没有任何次要功能。
而且,它可以帮助开发者创建一个紧凑的数据库,并最大限度减少重复数据,提升数据的一致性。
总的来说,第二范式和第三范式在实现上有很大的不同。
第二范式(2NF)主要是为了防止表中存在混合属性,而第三范式(3NF)则是为了最大程度减少重复数据的出现,提升数据的一致性。
在实际的开发中,不同的项目需求可能需要不同范式的支持,如何判断在哪种范式下优化数据库才是正确的,一般可以从表结构和关联,数据抽取、数据安全、数据库行为和存储引擎等几个方面来考虑这个问题。
在具体的实施过程中,数据库管理员应考虑各种情况,设计出一个结构良好的数据库结构,符合第二范式和第三范式的要求,以避免数据的冗余,从而提高数据库的运行性能,保证数据的完整性和一致性。
综上所述,第二范式(2NF)和第三范式(3NF)在设计数据库时都具有重要意义。
它们之间的主要区别在于,第二范式旨在禁止表中混淆属性,而第三范式则旨在将每个属性直接相关联到主键,以减少数据的冗余,增强数据的一致性。
在数据库设计中,开发者应根据具体需求来确定使用哪种范式才是正确的,以优化数据库结构,从而提高程序的可读性,并有效提升数据库的性能。
数据库设计是指按照特定的规范和要求,对数据库的数据存储和管理进行规划和设计的过程。
数据库设计的三个范式是指数据库设计中的基本规范,其中第一范式(1NF)、第二范式(2NF)和第三范式(3NF)分别规定了数据库中的数据应该满足的标准和要求。
下面我们将简要介绍数据库设计的三个范式的含义。
一、第一范式(1NF)1. 第一范式是指数据库表中的所有字段都是不可再分的最小单元,即每个数据项都是不可再分的,不能再被分割为更小的数据项。
2. 数据库表中的每一列都是单一的值,不可再分。
3. 所有的字段都应该是原子性的,即不能再分。
4. 如果数据库表中的字段不满足第一范式的要求,就需要进行适当的调整和修改,使之满足第一范式的要求。
二、第二范式(2NF)1. 第二范式是指数据库表中的所有非主属性都完全依赖于全部主键。
2. 所谓主属性是指唯一标识一个记录的属性,而非主属性是指与主键相关的其他属性。
3. 如果一个表中的某些字段与主键没有直接关系,而是依赖于其他字段,则需要将这些字段拆分到另一个表中。
4. 通过将非主属性与主键分离,可以避免数据冗余和更新异常。
5. 第二范式要求数据库表中的数据项应该是唯一的,不可再分,且完全依赖于全部主键。
三、第三范式(3NF)1. 第三范式是指数据库表中的所有字段都不依赖于其他非主字段。
2. 也就是说,一个表中的字段之间应该相互独立,不应该存在字段之间的传递依赖关系。
3. 如果一个字段依赖于其他非主字段,则应该将其拆分到另一张表中,以避免数据冗余和更新异常。
4. 第三范式要求数据库表中的字段之间应该是独立的,不应该存在传递依赖关系。
数据库设计的三个范式分别规范了数据库表中数据的原子性、依赖性和独立性。
遵循这些范式可以有效地减少数据冗余和更新异常,提高数据库的数据完整性和稳定性。
在进行数据库设计时,设计人员应该严格遵循这些范式的要求,以确保数据库的高效性和可靠性。
众所周知,数据库设计的三个范式是设计和维护关系型数据库时非常重要的标准和指导原则。
数据库第一范式,第二范式和第三范式
数据库是以某种数据模型为基础,组织数据的集合。
而数据库范式是指满足不同依赖
关系的要求。
目前有多种范式,其中较为常见的是第一范式、第二范式和第三范式,其分
别对数据集的性质进行了不同程度的要求,下面我们详细介绍这三种范式。
一、第一范式(1NF)
第一范式是所有范式中最基本且最重要的一种。
它要求数据库中的每个字段都是原子
性的,即每个字段只包含一个数据。
如果一个字段包含多个数据,则应该将其拆分成多个
字段。
这样可以方便数据的管理和维护,而且还能保证数据的唯一性,避免冗余数据。
例如,如果有一个学生表,包含了学生姓名和所选课程,如果一条记录中同时包含多
个课程,则应该将其拆分成多个记录,每个记录只包含一个课程。
第二范式是在第一范式的基础上进一步规范化的范式。
它要求数据库中的表必须满足
如下两个条件:
1.表的每个非主键字段必须完全依赖于主键。
2.表中不能存在部分依赖关系。
这样可以使得数据库表结构更加规范,同时也可以避免数据的冗余,提高数据的存取
效率。
例如,如果有一个订单表,包含了订单号、商品名、商品数量和单价四个字段。
其中,订单号是主键,商品名是非主键字段。
如果一个商品对应多个单价,则存在部分依赖关系。
这种情况下,应该将商品名和单价分别存储在两个表中,建立一对多的关系。
总的来说,不同的范式适用于不同的业务需求。
正确使用范式可以规范化数据,提高
数据管理的效率,同时也会降低数据冗余的程度,避免数据的不一致性。
第一范式第二范式第三范式的定义
第一范式:是对关系模式的基本要求。
不满足第一范式的关系,不能称为关系型数据库。
符合第一范式的关系,每个属性都不可以再分割。
但是如果仅仅满足第一范式:仍然存在数据冗余过大、插入异常、删除异常、修改异常等的问题。
第二范式:建立在第一范式的基础上,首先满足第一范式。
消除了非主属性对码的部分函数依赖。
第三范式:必须先满足第二范式,要求表中的每一列只与主键直接相关而不是间接相关。
第⼀范式第⼆范式第三范式BC范式第四范式1.第⼀范式(确保每列保持原⼦性)第⼀范式是最基本的范式。
如果数据库表中的所有字段值都是不可分解的原⼦值,就说明该数据库表满⾜了第⼀范式。
第⼀范式的合理遵循需要根据系统的实际需求来定。
⽐如某些数据库系统中需要⽤到“地址”这个属性,本来直接将“地址”属性设计成⼀个数据库表的字段就⾏。
但是如果系统经常会访问“地址”属性中的“城市”部分,那么就⾮要将“地址”这个属性重新拆分为省份、城市、详细地址等多个部分进⾏存储,这样在对地址中某⼀部分操作的时候将⾮常⽅便。
这样设计才算满⾜了数据库的第⼀范式,如下表所⽰。
上表所⽰的⽤户信息遵循了第⼀范式的要求,这样在对⽤户使⽤城市进⾏分类的时候就⾮常⽅便,也提⾼了数据库的性能。
2.第⼆范式(确保表中的每列都和主键相关)第⼆范式在第⼀范式的基础之上更进⼀层。
第⼆范式需要确保数据库表中的每⼀列都和主键相关,⽽不能只与主键的某⼀部分相关(主要针对联合主键⽽⾔)。
也就是说在⼀个数据库表中,⼀个表中只能保存⼀种数据,不可以把多种数据保存在同⼀张数据库表中。
⽐如要设计⼀个订单信息表,因为订单中可能会有多种商品,所以要将订单编号和商品编号作为数据库表的联合主键,如下表所⽰。
订单信息表这样就产⽣⼀个问题:这个表中是以订单编号和商品编号作为联合主键。
这样在该表中商品名称、单位、商品价格等信息不与该表的主键相关,⽽仅仅是与商品编号相关。
所以在这⾥违反了第⼆范式的设计原则。
⽽如果把这个订单信息表进⾏拆分,把商品信息分离到另⼀个表中,把订单项⽬表也分离到另⼀个表中,就⾮常完美了。
如下所⽰。
这样设计,在很⼤程度上减⼩了数据库的冗余。
如果要获取订单的商品信息,使⽤商品编号到商品信息表中查询即可。
3.第三范式(确保每列都和主键列直接相关,⽽不是间接相关)第三范式需要确保数据表中的每⼀列数据都和主键直接相关,⽽不能间接相关。
⽐如在设计⼀个订单数据表的时候,可以将客户编号作为⼀个外键和订单表建⽴相应的关系。
简述数据库的三大范式数据库的三大范式是指第一范式、第二范式和第三范式,它们是数据处理的三个重要的基本规范,用于解决数据库设计中的逻辑冗余问题,其目的是简化数据库表结构,使其更加合乎规律,并减少数据的冗余和重复。
第一范式(1NF)是一个属性(比如姓名)在一个行中只能出现一次,并且每个字段必须互相独立,不允许存储多个值。
例如,在一个数据库表中,保存每个学生的姓名和学号,那么在每行中只能保存一个学生的一个学号,而不能存储多个学号。
第二范式(2NF)在第一范式的基础上引入了“非主属性”的概念,即每个表中包含若干个主属性和若干个非主属性。
主属性是构成表的唯一标识,而非主属性是表中每行数据中只有一部分属性会参与其组成,通常用于提供其它属性的参照物。
在一个符合2NF的表中,所有的非主属性都必须直接参考到表中每一行的主属性,而不能间接参考。
第三范式(3NF)在第二范式的基础上引入了“传递依赖”的概念,它要求表中的每个非主属性必须只依赖于每行的主属性,而不能存在间接依赖其它属性的情况,即表中不存在任何非主属性只依赖于另一个非主属性,而不依赖于表中任何一行的主属性。
数据库设计中使用三大范式的最大好处是,它可以避免数据库表结构的“冗余现象”。
同一条数据可能会被存储多次,在数据处理的过程中会浪费大量的磁盘空间,并且由于不同的数据可能在不同的地方存储,在进行查询的时候也会造成极大的麻烦。
使用三大范式对数据库表进行规范,有效地消除了不必要的冗余,使数据库在查询和操作的效率大大提升。
此外,三大范式还可以让数据库表更加合乎规律,易于维护和控制。
在数据库设计中,只有在遵循三大范式的原则下才能保证数据的一致性,从而方便对其进行维护和更新。
三大范式对于数据库的优化和改进至关重要,它可以帮助数据库管理员构建出一个高效、规范、安全的数据库系统,以提供更好的数据服务。
因此,在进行数据库设计时,一定要按照三大范式的原则来进行,以确保数据库设计的正确性,从而提升数据库的性能。
数据库的第一,二,三范式博客分类:数据库数据库的设计范式是数据库设计所需要满足的规范,满足这些规范的数据库是简洁的、结构明晰的,同时,不会发生插入(insert)、删除(delete)和更新(update)操作异常。
反之则是乱七八糟,不仅给数据库的编程人员制造麻烦,而且面目可憎,可能存储了大量不需要的冗余信息。
设计范式是不是很难懂呢?非也,大学教材上给我们一堆数学公式我们当然看不懂,也记不住。
所以我们很多人就根本不按照范式来设计数据库。
实质上,设计范式用很形象、很简洁的话语就能说清楚,道明白。
本文将对范式进行通俗地说明,并以笔者曾经设计的一个简单论坛的数据库为例来讲解怎样将这些范式应用于实际工程。
范式说明第一范式(1NF):数据库表中的字段都是单一属性的,不可再分。
这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。
例如,如下的数据库表是符合第一范式的:字段1 字段2 字段3 字段4而这样的数据库表是不符合第一范式的:字段1 字段2 字段3 字段4字段3.1 字段3.2很显然,在当前的任何关系数据库管理系统(DBMS)中,傻瓜也不可能做出不符合第一范式的数据库,因为这些DBMS不允许你把数据库表的一列再分成二列或多列。
因此,你想在现有的DBMS中设计出不符合第一范式的数据库都是不可能的。
第二范式(2NF):数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖(部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况),也即所有非关键字段都完全依赖于任意一组候选关键字。
假定选课关系表为SelectCourse(学号, 姓名, 年龄, 课程名称, 成绩, 学分),关键字为组合关键字(学号, 课程名称),因为存在如下决定关系:(学号, 课程名称) → (姓名, 年龄, 成绩, 学分)这个数据库表不满足第二范式,因为存在如下决定关系:(课程名称) → (学分)(学号) → (姓名, 年龄)即存在组合关键字中的字段决定非关键字的情况。
由于不符合2NF,这个选课关系表会存在如下问题:(1) 数据冗余:同一门课程由n个学生选修,"学分"就重复n-1次;同一个学生选修了m门课程,姓名和年龄就重复了m-1次。
(2) 更新异常:若调整了某门课程的学分,数据表中所有行的"学分"值都要更新,否则会出现同一门课程学分不同的情况。
(3) 插入异常:假设要开设一门新的课程,暂时还没有人选修。
这样,由于还没有"学号"关键字,课程名称和学分也无法记录入数据库。
(4) 删除异常:假设一批学生已经完成课程的选修,这些选修记录就应该从数据库表中删除。
但是,与此同时,课程名称和学分信息也被删除了。
很显然,这也会导致插入异常。
把选课关系表SelectCourse改为如下三个表:学生:Student(学号, 姓名, 年龄);课程:Course(课程名称, 学分);选课关系:SelectCourse(学号, 课程名称, 成绩)。
这样的数据库表是符合第二范式的,消除了数据冗余、更新异常、插入异常和删除异常。
另外,所有单关键字的数据库表都符合第二范式,因为不可能存在组合关键字。
第三范式(3NF):在第二范式的基础上,数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。
所谓传递函数依赖,指的是如果存在"A → B → C"的决定关系,则C 传递函数依赖于A。
因此,满足第三范式的数据库表应该不存在如下依赖关系:关键字段→ 非关键字段x → 非关键字段y假定学生关系表为Student(学号, 姓名, 年龄, 所在学院, 学院地点, 学院电话),关键字为单一关键字"学号",因为存在如下决定关系:(学号) → (姓名, 年龄, 所在学院, 学院地点, 学院电话)这个数据库是符合2NF的,但是不符合3NF,因为存在如下决定关系:(学号) → (所在学院) → (学院地点, 学院电话)即存在非关键字段"学院地点"、"学院电话"对关键字段"学号"的传递函数依赖。
它也会存在数据冗余、更新异常、插入异常和删除异常的情况,读者可自行分析得知。
把学生关系表分为如下两个表:学生:(学号, 姓名, 年龄, 所在学院);学院:(学院, 地点, 电话)。
这样的数据库表是符合第三范式的,消除了数据冗余、更新异常、插入异常和删除异常。
鲍依斯-科得范式(BCNF):在第三范式的基础上,数据库表中如果不存在任何字段对任一候选关键字段的传递函数依赖则符合第三范式。
假设仓库管理关系表为StorehouseManage(仓库ID, 存储物品ID, 管理员ID, 数量),且有一个管理员只在一个仓库工作;一个仓库可以存储多种物品。
这个数据库表中存在如下决定关系:(仓库ID, 存储物品ID) →(管理员ID, 数量)(管理员ID, 存储物品ID) → (仓库ID, 数量)所以,(仓库ID, 存储物品ID)和(管理员ID, 存储物品ID)都是StorehouseManage的候选关键字,表中的唯一非关键字段为数量,它是符合第三范式的。
但是,由于存在如下决定关系:(仓库ID) → (管理员ID)(管理员ID) → (仓库ID)即存在关键字段决定关键字段的情况,所以其不符合BCNF范式。
它会出现如下异常情况:(1) 删除异常:当仓库被清空后,所有"存储物品ID"和"数量"信息被删除的同时,"仓库ID"和"管理员ID"信息也被删除了。
(2) 插入异常:当仓库没有存储任何物品时,无法给仓库分配管理员。
(3) 更新异常:如果仓库换了管理员,则表中所有行的管理员ID都要修改。
把仓库管理关系表分解为二个关系表:仓库管理:StorehouseManage(仓库ID, 管理员ID);仓库:Storehouse(仓库ID, 存储物品ID, 数量)。
这样的数据库表是符合BCNF范式的,消除了删除异常、插入异常和更新异常。
范式应用我们来逐步搞定一个论坛的数据库,有如下信息:(1)用户:用户名,email,主页,电话,联系地址(2)帖子:发帖标题,发帖内容,回复标题,回复内容第一次我们将数据库设计为仅仅存在表:用户名email 主页电话联系地址发帖标题发帖内容回复标题回复内容这个数据库表符合第一范式,但是没有任何一组候选关键字能决定数据库表的整行,唯一的关键字段用户名也不能完全决定整个元组。
我们需要增加"发帖ID"、"回复ID"字段,即将表修改为:用户名email 主页电话联系地址发帖ID 发帖标题发帖内容回复ID 回复标题回复内容这样数据表中的关键字(用户名,发帖ID,回复ID)能决定整行:(用户名,发帖ID,回复ID) → (email,主页,电话,联系地址,发帖标题,发帖内容,回复标题,回复内容)但是,这样的设计不符合第二范式,因为存在如下决定关系:(用户名) → (email,主页,电话,联系地址)(发帖ID) → (发帖标题,发帖内容)(回复ID) → (回复标题,回复内容)即非关键字段部分函数依赖于候选关键字段,很明显,这个设计会导致大量的数据冗余和操作异常。
我们将数据库表分解为(带下划线的为关键字):(1)用户信息:用户名,email,主页,电话,联系地址(2)帖子信息:发帖ID,标题,内容(3)回复信息:回复ID,标题,内容(4)发贴:用户名,发帖ID(5)回复:发帖ID,回复ID这样的设计是满足第1、2、3范式和BCNF范式要求的,但是这样的设计是不是最好的呢?不一定。
观察可知,第4项"发帖"中的"用户名"和"发帖ID"之间是1:N的关系,因此我们可以把"发帖"合并到第2项的"帖子信息"中;第5项"回复"中的"发帖ID"和"回复ID"之间也是1:N的关系,因此我们可以把"回复"合并到第3项的"回复信息"中。
这样可以一定量地减少数据冗余,新的设计为:(1)用户信息:用户名,email,主页,电话,联系地址(2)帖子信息:用户名,发帖ID,标题,内容(3)回复信息:发帖ID,回复ID,标题,内容数据库表1显然满足所有范式的要求;数据库表2中存在非关键字段"标题"、"内容"对关键字段"发帖ID"的部分函数依赖,即不满足第二范式的要求,但是这一设计并不会导致数据冗余和操作异常;数据库表3中也存在非关键字段"标题"、"内容"对关键字段"回复ID"的部分函数依赖,也不满足第二范式的要求,但是与数据库表2相似,这一设计也不会导致数据冗余和操作异常。
由此可以看出,并不一定要强行满足范式的要求,对于1:N关系,当1的一边合并到N的那边后,N的那边就不再满足第二范式了,但是这种设计反而比较好!对于M:N的关系,不能将M一边或N一边合并到另一边去,这样会导致不符合范式要求,同时导致操作异常和数据冗余。
对于1:1的关系,我们可以将左边的1或者右边的1合并到另一边去,设计导致不符合范式要求,但是并不会导致操作异常和数据冗余。
结论满足范式要求的数据库设计是结构清晰的,同时可避免数据冗余和操作异常。
这并意味着不符合范式要求的设计一定是错误的,在数据库表中存在1:1或1:N关系这种较特殊的情况下,合并导致的不符合范式要求反而是合理的。
在我们设计数据库的时候,一定要时刻考虑范式的要求。