APP下载

关系型数据库逻辑结构设计的原则、方法与意义探析

2024-09-03陈小芳

电脑知识与技术 2024年19期

摘要:文章从数据库系统的逻辑结构设计的重要性切题,以关系型数据库为例,阐明逻辑结构设计原则与方法,用实例回答了良好的逻辑结构设计所带来的好处,最后进行总结,指出基本概念是关键,逻辑结构中的表尽量符合第三范式,表与表之间的联系通过外键来表达。同时也要兼顾表的规范化及数据库的性能,保证数据库系统的稳定性、高可用。

关键词:逻辑结构设计;函数依赖;关系规范化

中图分类号:TP3 文献标识码:A

文章编号:1009-3044(2024)19-0084-03

数据库系统设计的步骤主要包括需求分析、概念结构设计、逻辑结构设计以及数据库的实施和维护。逻辑结构设计是关键环节之一,这个环节做好做实了,数据库系统的稳定性、安全性、完整性和高性能才有基础。

1 数据库系统逻辑结构设计的重要性

数据库系统设计的根本目的是满足用户收集、存储、操作和管理数据的需要。数据库系统的三个模式两级映像保证了数据库外模式的稳定性,既保证了数据的逻辑独立性;也从底层保证了应用程序的稳定性,还保证了数据的物理独立性。除非应用需求本身发生变化,否则应用程序一般不需要修改。

在数据库系统的三级模式结构中,数据库逻辑模式是数据库的中心与关键,它独立于数据库的其他层次,因此设计数据库模式结构时应首先确定数据库的逻辑模式,进行逻辑结构设计。良好的数据库系统的逻辑结构设计,可以节省数据的存储空间,能够保证数据的完整性,方便进行数据库系统的开发。反之,会导致数据冗余、存储空间浪费,数据更新、删除和插入的异常。

2 数据库系统的逻辑结构设计的原则

数据库常见的数据模型有层次模型、网状模型、关系模型、对象-关系模型等,关系模型是目前最重要的一种数据模型,关系数据库就是采用关系模型作为数据的组织方式。关系模型源于数学,它把数据看成是二维表中的元素,而这个二维表在关系数据库中就称为关系。在关系数据库中,记录值仅构成关系,关系之间的联系是靠语义相同的字段(称为连接字段)值表达的[1]。理解关系和连接字段(即列)的思想在关系数据库中是非常重要的。本文讨论数据库系统的逻辑结构设计就是以关系模型为例。

2.1 表设计原则

在关系型数据库系统中的逻辑结构设计体现在二维表结构的设计,在设计时尽可能遵守第三范式标准的表设计原则,一个主题对应一张表,即一个表中只包含其本身的基本属性。

之所以要尽可能遵守第三范式标准的表设计原则,是因为第一范式、第二范式都有可能存在数据冗余,如果存在数据冗余,就有可能引起操作异常,包括插入异常、删除异常、更新异常。为了避免数据操作异常,我们一般把数据库设计到第三范式,也就是说我们在一张表中不允许存在部分函数依赖和传递函数依赖:从第一范式规范到第二范式时消除了部分函数依赖;从第二范式规范到第三范式时消除了传递函数依赖,在规范化的过程中逐步消除了“不良”的函数依赖[2]。

表的规范化可以保证表内的字段都是最基本的要素,同时规范化这一措施也有助于消除数据中的数据冗余。规范化有好几种形式:1NF、2NF、3NF、BCNF、4NF、5NF等。但3NF通常被认为在性能、扩展性和数据完整性方面达到了最佳平衡。而BCNF、4NF、5NF更多是作为数据理论研究。简单来说,满足3NF的表,有如下3个特点,表内的每一个值都只能被表达一次;表内的每一行都能被区分;每一个表都不包含其他表已经包含的非主关键字信息。

2.2 字段设计原则

在进行数据库系统逻辑设计中,表中的字段设计在长度上要尽量充足,同时考虑未来发展。比如企业目前职工人数是数百人,则职工编号为3位数字,但考虑到今后企业有可能壮大到数千人,则可将职工编号设置为4位数字,这样尽量满足一段时间内企业发展的需求。给字段留足余量,将来无须重构整个数据库就可以实现数据库规模的增长了,增强了系统的灵活性[3]。

在进行数据库系统逻辑设计中,还要考虑表字段的命名规范。字段的名称要易于理解,便于阅读,要有意义,不宜太长,要保证数据库表中字段名没有和保留字或者常用访问方法冲突,否则在程序连接时会出错,在用SELECT语句查询时,会得到一大堆无用处的信息。还要注意的是:在命名字段并为其指定数据类型的时候,一定要在各个表中保证一致性;字段名都采用加上前缀的方式,如加上所属表缩写名的前缀,那么在编写SQL表达式的时候会得到大大的简化;对地址采用多个字段,可以提供更大的灵活性;有时在表中创建一个计算列(如成绩总分),通过它可以自动地连接标准化的字段,这样数据变动的时候,计算列也跟着变动,实现数据的自动更新。

进行数据库逻辑设计时,还要有一种服务意识、大局意识,因为数据库逻辑设计只是一个小小的环节,还有数据库管理员、应用程序开发员等,最终用户要使用数据库系统,所以要考虑周全。

2.3 谨慎使用触发器

触发器在保证数据完整性及商业规则方面有积极作用,比如我们要限制不能将学生成绩由不及格改成及格这样复杂的业务规则,我们则用触发器来实现。

但不当地使用触发器时,它会带来效率方面的问题。比如,我们用触发器来限制学生的考试成绩在0~150分。我们知道触发器有两种类型,一种是前触发型,另一种是后触发型。假设先使用了一个后触发型触发器来实现,那这个处理流程是这样的:先完成数据的插入,再执行触发器。在触发器中判断新插入的数据是否不在0~150分,如果不在,要作一个回滚roll⁃back的操作,把刚插入的数据撤销。如果使用的是前触发型触发器,同样假设是在一个插入操作上定义触发器。执行插入操作时,系统它本身并不实际执行插入操作,而是去执行触发器的代码。当我们在触发器当中发现新插入的成绩满足在0~150分时,再在触发器当中写一个重新插入这样一条语句。

不管是后触发型的触发器作一个回滚rollback操作,还是前触发型的触发器再重新写一遍插入操作,这些都比直接做插入操作多了一些额外的工作。因此不当使用触发器会降低数据的操作效率。触发器的功能通常可以用其他方式实现,如果我们定的是一个check约束,情况就不一样了,数据库管理系统首先会检查我们的数据是否满足我们的check约束的要求。如果不满足,这个操作是不会执行的,这样显然比我们用触发器的效率高很多。所以我们能够用check约束或唯一值约束等完整性约束来实现这些约束,都不要使用触发器来实现,只有他们实现不了的复杂约束和企业规则,才使用触发器。

2.4 恰当使用视图

视图主要是为了在数据库和应用程序代码之间提供另一层抽象。我们知道数据库系统是三级模式两级映像的结构。三层模式是内模式、概念模式、外模式,视图就对应到外模式。外模式是针对每一类用户对信息的需求来设计的,因此我们在设计外模式的时候,实际上是可以满足每一类用户的信息需求的。

在定义视图时,实际上它可以实现包含复杂查询的语句。用户需要查询这些数据,如果我们定义好了视图,在客户端用户中需要对这个视图进行访问就可以,不需要去编写复杂的查询语句。当然了我们通过视图,通过外模式访问数据,它最终都会转换到内模式,对基本表的访问。因此通过视图访问数据效率会有一些降低,但可以简化客户端的编程,可以封装复杂的查询,可以恰当地去使用视图。

2.5 编写设计文档

对所有的设计都要编写相应文档,每一个设计阶段都要产生一些文档,便于后期维护和经验总结。

3 数据库系统逻辑结构设计的方法

3.1 数据冗余带来的操作异常

数据库设计是数据库应用领域中的重要研究课题,其主要任务是创建满足用户需求且性能良好的数据库模式。对于关系型数据库设计确切地讲其主要任务就是关系数据库的逻辑设计问题:如何为数据库应用系统设计合适的关系模式,应设计几个关系模式,每个关系模式由哪些属性组成等等。

某电子有限责任公司需要开发一个员工信息管理系统,现设计了一张员工信息表,表中有5项属性(工号、工作车间、宿舍楼、零件号、工分),前提假设同一工作车间的员工住在同一栋宿舍楼里,一位员工可以加工不同的零件来取得工分。这个表的主键是(工号、零件号)。现有如下数据,见表1最初的员工信息表。

我们来分析一下这个表的数据,看看可有数据冗余的情况,如有,在数据冗余的情况下,会出现哪些操作异常。

从行的角度来看,前面4 行数据实际上是描述QC1910001这位员工的。之所以出现了4次,是因为他后面选的加工零件有4种。从列的角度来看,前两列描述的是这位员工在哪个车间工作这个主题,第二列与第三列描述的是这个车间的员工住在哪栋宿舍楼这个主题。这两个主题由于与后面所选的加工零件合在一张表进行描述,所以被重复描述了多遍,有数据冗余的情况。

在有数据冗余的情况,它带来的最直观的问题是造成存储空间的浪费。除了存储空间的浪费,还会带来不好的后果,就是操作异常。

1) 数据插入异常

假设公司的规模不断扩大,现要新增一个车间:工作车间4,也分配了这个车间的员工住在4号楼。但目前还没开始招收员工,因此还没有工号与零件号的数据,而(工号、零件号)是这张表的主键,我们知道要插入一行数据,主键为空是插入不了的。这样新增的这个车间的信息就插不进去了。所以说数据冗余有可能造成数据插入异常。

2) 数据更新异常

假设公司新盖了宿舍楼,现要把车间1的员工搬到新盖的宿舍楼:新1号楼。按常理来说,要更改这样一个主题,只要更改一次就够了。但对于我们这个设计方法,在这张表中就要更改6次。那由小及大,如果这个车间1的员工是100人,那起码得更改100次。这就造成了时间的浪费,效率的低下,出错的可能。所以说数据冗余有可能造成数据更新异常。

3) 数据删除异常

假设有员工只加工一种型号的零件,现公司不再加工这个零件了,要把这行数据删除。那么删除掉这行信息,同时也就把这位员工的其他基本信息一并删除了。可见,多个主题合在一起,放在同一张表中进行描述的这种设计方法,有可能造成数据删除异常。

显然,好的数据库逻辑结构设计很重要。不仅避免了空间的浪费,也避免了数据操作异常,还能提高效率,能够保证数据的完整性,方便进行数据库系统的开发[4]。

3.2 数据库逻辑结构设计的规范化

进行数据库逻辑结构设计,要遵循关系规范化理论,要理解函数依赖与范式间的内在关系。某电子有限责任公司这张员工信息表不是一个好的关系模式,只有通过模式分解,把这个关系模式分解成更高级别的两个或是多个关系模式,在分解的过程中消除那些“不良”的函数依赖,从而获得良好的关系模式。

1) 消除部分函数依赖,规范化到第二范式

我们知道,不包含非原子项属性的关系是第一范式的关系。也只有满足第一范式的表,我们在关系模式的数据库中才能去存储。员工信息表(工号、工作车间、宿舍楼、零件号、工分)都是原子项属性,所以它是第一范式的关系。

在员工信息表当中,(工号、零件号)是主键,而工作车间完全函数依赖于工号,这样就存在工作车间部分函数依赖于主键。同时存在数据冗余,操作异常的情况。因此,我们用分解的方法,把这张表规范化到第二范式,消除部分函数依赖。

首先,用组成主键的属性集合的每一个子集,作为主键构成关系表。在这,我们得到主键的3个子集分别为:工号,零件号,(工号、零件号)。

再者,将依赖于不同主键的属性放置到相应的关系表中。得到3张表:(工号、工作车间、宿舍楼);(工号、零件号、工分);(零件号)。

最后,去掉只由主键的子集构成的关系表。

这样就把员工信息表规范化到第二范式了,得到两张表。(工号、工作车间、宿舍楼);(工号、零件号、工分)。

已规范化到第二范式的关系表,再看表2的工作车间与宿舍楼这两列数据,还是存在数据冗余的情况。有数据冗余就可能存在数据操作异常。因此,继续向第三范式进行规范化。

2) 消除传递函数依赖,规范化到第三范式

在(工号、工作车间、宿舍楼)这张第二范式的关系表中,工作车间完全函数依赖于工号,宿舍楼又完全函数依赖于工作车间,因此,宿舍楼传递函数依赖于工号,并且有数据冗余的情况。继续用分解的方法,把这张表规范化到第三范式,消除传递函数依赖。

首先,对于不是候选键的每个决定因子,从关系模式中删去依赖于它的所有属性。在此表中,工作车间决定宿舍楼,工作车间这个决定因子并不是一个候选键,因此,把依赖于它的属性宿舍楼删去。

再者,新建一个关系模式,新关系模式中包含在原关系模式中所有依赖于该决定因子的属性。那么新关系模式为(宿舍楼)。

最后,将决定因子作为新关系模式的主键。那么新关系模式为(工作车间、宿舍楼)。

这样,我们就把(工号、工作车间、宿舍楼)这张第二范式的关系表分解为两张第三范式的表(工号、工作车间),(工作车间、宿舍楼)。分解到第三范式了,这两张表基本上不存在数据冗余,没有数据冗余,也就基本上消除了操作异常。

3) 设置外键,保持表间的联系,保证数据的完整性

经过规范化,最终把员工信息表分解成了三个第三范式的关系表:

form1(工号、工作车间),工号是主键,工作车间为引用form2的外键。

form2(工作车间、宿舍楼),工作车间是主键,没有外键。

form3(工号、零件号、工分),(工号、零件号)是主键,工号为引用form1的外键。

表之间的关系是通过外键来连接的。原来在一张表中的数据,为了保证数据库的性能,通过分解的方法变成了多张表,规范化到了第三范式,为了保持表中原数据间的联系,我们可以通过设计外键的方法保持表间的联系,保持数据的依赖关系。例如,在前面的表中,定义form3表当中的工号当作外键,它参照form1表中的工号,这样可以保证进行零件加工的员工是在form1表中登记在册的员工。这样也就保证了这两张表数据间的关联关系。

关系规范化的方法是进行模式分解,但分解后产生的关系模式应与原关系模式等价,不能表面上消除了操作异常现象,却留下了其他的问题。为此,模式分解还要注意两点:一是模式分解具有无损连接性;二是模式分解能够保持函数依赖。

4) 坚持标准化的设计理念

在表设计原则中,应尽量遵守第三范式的标准,更高层次的标准也有,但更高标准不一定更好。事实上,对某些项目而言,甚至就连3NF都可能给数据库引入太高的复杂性。有时为了提高运行效率,就得适当保留冗余数据,对表不进行标准化有时也是必要的,非标准化与加速访问之间的妥协是有一定意义的,但绝不能把数据表的非标准化当作理所当然的设计理念[5]。适当保留冗余数据,具体做法是增加字段,但这具体的操作不过是一种派生,所以标准化的设计理念是要坚持的,从根本上保证数据库系统的高性能、高可用。

4 数据库系统逻辑结构设计的意义

数据库系统逻辑结构设计的意义在于为数据库系统的稳定性、安全性、完整性和高性能提供支撑。数据库系统逻辑结构设计是数据库设计的“纲”。在数据库系统的三级模式中,逻辑模式是数据库系统的中间层,是对数据库中的全体数据的描述,是所有用户的公共数据视图。“壹引其纲,万目皆张”,设计出良好的逻辑模式,不仅能节省数据的存储空间,而且方便数据库应用系统的开发,还能保证数据的完整性等。

数据库系统的设计往往工作量比较大,过程复杂,综合性强,涉及面广,要确切表达用户的需求,构造最优的数据库模式,因此要努力把数据库设计和系统其他成分的设计紧密结合,把数据和处理的需求、分析、抽象、设计和实现在各个阶段同时进行,相互参照,相互融合。

参考文献:

[1] 王珊,萨师煊.数据库系统概论[M].5版.北京:高等教育出版社,2014.

[2] 丁智斌,石浩磊.关系数据库设计与规范化[J].计算机与数字工程,2005,33(2):114-116.

[3] 舒思思.浅谈图书管理系统的设计[J].湖北科技学院学报,2013,33(2):159-160.

[4] 郭文明.数据库运维[M].北京:国家开放大学出版社,2019.

[5] 陶勇,丁维明.数据库中规范化与反规范化设计的比较与分析[J].计算机技术与发展,2006,16(4):107-109,121.

【通联编辑:朱宝贵】