设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。
目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以此类推。一般说来,数据库只需满足第三范式(3NF)就行了。未经规范化的数据库一般都有下述缺点:较大的数据冗余,数据一致性差,数据修改复杂,对表进行插入删除时会产生异常。规范化的作用就在于尽量去除冗余,使数据保持一致,使数据修改简单,除去在表中进行插入删除时产生的异常。规范化后的表一般都较小,小的表意味着一个数据页中可以包含较多的记录,这样客户端用户就可在同样的时间内获得所需的更多数据记录,从而减少客户端与服务器端的物理I/O,减轻网络的负担。
1.零状态形式
这里假定我们要建立一个用户信息的表格,其中要存储用户的名字、公司、公司地址和一些个人的收藏夹或url。在开始时,定义一个如下的表格结构:
表6-1 users(零状态形式表结构)
由于没有进行任何的正规化处理,我们将这种形式的表称为零状态形式的表。留意其中的url1和url2字段,如果我们在应用中需要第三个url呢?这样就要在表格中多加一列,很明显,这不是一个好办法。如果要创建一个富有扩展性的系统,就要考虑使用第一范式的形式,并且应用到该表格中。
2.第一范式(1NF)
定义:如果关系R中所有属性的值域都是单纯域,那么关系模式R是第一范式的,记作R∈1NF。
具体要求为:1)消除每个表格中重复的组,2)为每套相关的数据建立一个独立的表格,3)使用一个主键来标识每套相关的数据。
以上的表格明显违反了上面第一条的规定,那么第三条的主键又是什么意思呢?很简单,它只是在每个记录中加入一个唯一的、自动增加的整型值。通过这个值,就可以将两个姓名一样的记录区分开来。通过应用第一范式,我们得到了以下的表格:
表6-2 users(第一范式表结构)
现在的表格已经处在第一范式的形式了,它已经解决了url字段的限制问题,不过这样的处理后又带来了一个新的问题。每次在user表中插入一条记录的时候,我们都必须重复所有的公司和用户数据。这样不仅令数据库比以前大了,而且很容易出错。
这一限制是关系的基本性质,所以任何关系都必须满足第一范式。在仅满足1NF的表中,数据冗余大、修改量大、插入删除时会有异常,由此我们引入2NF。
3.第二范式(2NF)
定义:如果关系模式R是第一范式的,而且关系中每一个非主属性大部分依赖于主键,称R是第二范式的,记作:R∈2NF。
具体要求为:1)为应用在多条记录的字段建立独立的表格,2)通过一个foreign key来关联这些表格的值。
我们将url的值放在一个独立的表格中,这样我们就可以在以后加入更多的数据,而无须担心产生重复的值。我们还通过主键值来关联这些字段。
表6-3 users(第二范式表结构)
表6-4 urls(第二范式表结构)
如上所示,我们创建了独立的表格,users表中的主键userid现在与url表中的foreign key relUserId关联。现在的情况好像已经得到了明显的改善。不过,如果我们要为ABC公司加入一个员工记录呢?或者更多,200个这样我们就必须重复使用公司名和地址,这明显不够冗余。因此我们将应用第三范式。
4.第三范式(3NF)
定义:如果关系模式R是2NF的,且每一个非主属性都不传递依赖于主键,称R是第三范式的,记作R∈3NF。
具体要求为:消除不依赖于该键的字段。公司名及地址与User Id都是没有关系的,因此它们应用拥有自己的公司Id。
表6-5 users(第三范式表结构)
表6-6 companies(第三范式表结构)
表6-7 urls(第三范式表结构)(www.xing528.com)
这样我们就将companies表中的主键comId和users表中名字为relCompId的foreign key关联起来,就算为ABC公司加入200个员工,在companies中也只有一条记录。我们的users和urls表可以不断地扩大,而无须担心插入不必要的数据。
我们可以留意一下URL的字段,你注意到数据的冗余了吗?如果给用户输入这些url数据的HTML页面是一个文本框,可任意输入的话,这并没有问题,两个用户输入同样收藏夹的概率较少,不过,如果是通过一个下拉式的菜单,只让用户选择两个url输入,或者更多一点。这种情况下,我们的数据库还可以进行下一级别的优化,第四范式,对于大多数的开发者来说,这一步都是忽略的,因为它要依赖一个很特别的关系——一个多对多的关系。
3NF去除了非主属性对主键的部分函数依赖和传递函数依赖。一般满足3NF的关系模式已能消除冗余和各种异常现象,获得较满意的效果,但无论2NF还是3NF都没有涉及主属性间的函数依赖,所以有时仍会引起一些问题。由此我们引入BC范式(BCNF,Boyeet和Codd提出),通常认为BCNF是第三范式的改进。
BC范式的定义:如果关系模式R∈1NF,且R中每一个决定因素都是候选键,则R是满足BC范式的关系,记作R∈BCNF。
当一个关系模式R∈BCNF,则在函数依赖范畴里,已实现了分离,消除了插入、删除的异常。
5.第四范式(4NF)
第四范式是BC范式的推广,是针对有多值依赖的关系模式所定义的规范化形式。
定义:关系模式R<U,F>∈1NF,X、Y是U的非空子集,,Z=U-X-Y也非空。此时若X→→Y,则X必包含R的主键,称R是第四范式的,记作:R∈4NF。
对于多对多的关系来说,就有点复杂了。在第三范式的例子中,一个用户与很多的url有关,如果将该结构变为允许多个用户与多个的urls有关,这样就可以得到一个多对多的结构。在讨论前,先看看表格结构会有些什么变化。
表6-8 users(第四范式表结构)
表6-9 companies(第四范式表结构)
表6-10 urls(第四范式表结构)
表6-11 url_relations(第四范式表结构)
为了进一步减低数据的冗余,运用第四范式,创建一个url_relations表,里面的字段均为主键或者foreign key。通过这个表,就可以消除urls表中的重复项目。
第四范式的具体要求:在一个多对多的关系中,独立的实体不能存放在同一个表格中。
由于它仅应用于多对多的关系,因此大多数的开发者可以忽略这条规定。不过在某些情况下,它是非常实用的,这个例子就是这样,我们通过将相同的实体分离出来,并且将关系移到它们自己的表格中,从而改进了urls表格。
为了更容易明白,我们举个具体的例子,以下将用一个SQL语句选择出所有属于joe的urls:SELECT name,url FROM users,urls,url_relationss where surl_relations.relatedUserId=1 AND
users.userId=1 AND urls.urlId=url_relations.relatedUrlId
如果我们想要遍历每个人的个人信息和url信息,我们可以这样做:
SELECT name,url FROM users,urls,url_relationsswheresusers.userId=url_relations.relatedUserId AND
urls.urlId=url_relations.relatedUrlId
6.第五范式(5NF)
定义:如果关系模式R中的每一个连接依赖,都是由R的候选键所蕴含,称R是第五范式的,记作:R∈5NF。
第五范式并不常见,并且在大部分的情况下都是不必要的。它的要求是:原来的表格必须可以通过由它分离出去的表格重新构建。
使用这个规定的好处是,你可以确保不会在分离的表格中引入多余的列,所有你创建的表格结构都与它们的实际需要一样大。应用这条规定是一个好习惯,不过除非你要处理一个非常大型的数据,否则你将不需要用到它。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。