存储过程、完整性约束
存储过程
- 存储过程是一组预先定义并编译好的的程序,它可以接受参数、返回状态值和参数值。使用存储过程主要有以下优点:
- 存储过程能够提高程序的执行速度。因为存储过程只在创建时进行编译,以后每次执行存储过程都不需再重新编译,所以使用存储过程可提高数据库执行速度。
- 当对数据库进行复杂操作时,可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。而且,存储过程可以重复使用,从而减少数据库开发人员的工作量。
- 存储过程能够减少网络流量。对于同一个针对数据库对象的操作,如查询修改,如果这一操作所涉及到的语句被组织成一个存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是调用语句,而不是查询过程的所有语句,这就大大降低了网络的传输量。
- 安全性高。可设定只有某类用户才具有对指定存储过程的使用权限。
- 系统存储过程:是系统提供的存储过程,可以作为命令进行各种操作,并可作为样本存储过程,指导用户如何编写有效的存储过程。系统存储过程在master数据库中,其前缀为sp_,用来进行系统的各项设定、获取信息及相关管理工作,常用的系统存储过程有:
- sp_help 显示参数清单和其数据类型。
- sp_helptext 显示存储过程的定义文本。
- sp_depends 列出存储过程依据的对象或依据存储过程的对象。
- sp_stored_procedures 返回当前数据库中的存储过程的清单。
- 扩展存储过程:扩展存储过程以前缀xp_来标识,对于用户来说,扩展存储过程和普通存储过程一样,可以用相同的方式,调用操作系统提供的功能。
- 例如,EXEC master..xp_cmdshell ‘ping 10.8.16.1’。该条语句等价于Windows环境下,执行‘ping 10.8.16.1’命令。
- 用户自定义的存储过程:是用户在数据库中建立存储过程,在数据库系统中,为特定业务设计的存储过程,能较好的实现业务逻辑,并增强系统执行效率。
完整性约束
-
实体完整性(Entity Integrity)规则:若属性A是基本关系R的主属性,则属性A不能取空值。对于实体完整性规则说明如下:
- 实体完整性规则能够保证实体的唯一性。实体完整性规则是针对基本表而言的。一个基本表通常对应现实世界的一个实体集,而现实世界中的一个实体是可区分的,即它们具有某种唯一性标识。相应地,关系模型中以主码作为唯一性标识。
- 实体完整性规则能够保证实体的可区分性。主码中的属性即主属性不能取空值,所谓空值就是“无意义”的值,用“NULL”表示。如果主属性取空值,就说明存在某个不可标识的实体,即存在不可区分的实体,这不符合现实世界的情况。
-
参照完整性(Referential Integrity)规则:若属性(或属性组)F是基本关系R的外码,它与基本关系S的主码相对应,则对于R中每个元组在F上的值必须为:或者取空值(F的每个属性值均为空值),或者等于S中某个元组的主码值。
- 例:学生实体和选修实体可以用下面的关系表示,其中主码用下划线标识。
学生(学号,姓名,性别,所在系,班号,出生日期)
选修(学号,课程号,成绩) - 这两个关系之间存在着属性的引用,即选修关系引用了学生关系的主码“学号”。显然,选修关系中的“学号”值必须是确实存在的某个学生的学号,即选修关系中的“学号”属性的取值需要参照学生关系的“学号”属性取值。
- 对于上例,按照参照完整性规则,选修关系中每个元组的“学号”属性只能取两种值,空值或学生关系中某个元组的“学号”值。但由于此例中,“学号”属性不仅是选修关系的外码,同时又是该表的主属性,因此不允许取空值,即只能够取学生关系中某个元组的“学号”值。
- 例:学生实体和选修实体可以用下面的关系表示,其中主码用下划线标识。
-
用户定义的完整性
- 任何关系数据库系统都应该支持实体完整性和参照完整性。除此之外,不同的关系数据库系统根据其应用环境的不同,往往还需要一些特殊的约束条件,用户定义的完整性就是针对某一具体数据库系统的约束条件。
- 用户定义的完整性约束反映某一具体应用所涉及的数据必须满足的语义要求。如某个属性必须取唯一值、某些属性值之间应满足一定的函数关系、某个属性的取值范围等。关系模型应提供定义和检验这类完整性的机制,以便于使用统一的、系统的方法处理它们,而不要由应用程序承担这一功能。
-
修改关系中主码的问题:当用户欲修改关系中某个元组的主码值时,由于可能存在参照与被参照的问题,系统如何处理就是因主码修改而产生问题。这个问题一般有以下两种处理策略:
- 不允许修改主码:不允许用户修改关系中任何元组的主码值,如果需要修改某个元组的主码值,必须先删除该元组,然后再把具有新主码值的元组插入到关系中。
- 允许修改主码:允许用户修改关系中元组的主码值,但必须保证主码值的唯一性和非空,否则拒绝修改。且当修改的关系是被参照关系时,还必须检查参照关系是否存在这样的元组,其外码值等于被参照关系要修改的主码值。
-
外码能否接受空值问题
根据实际情况的不同,一个关系的外码有时可以取空值,有时又不能取空值,这是数据库设计人员必须考虑的外码空值问题。因此在实现参照完整性时,系统除了应该提供定义外码的机制,还应提供定义外码列是否允许空值的机制。 -
在被参照关系中删除元组的问题:当用户将被参照关系中的一个元组删除,如何处理参照关系中对应的元组,即是否将参照关系中对应的元组也一起删除,简称为被参照关系中元组的删除问题。一般有三种不同的策略:
- 级联删除(CASCADES):将参照关系中外码值,与被参照关系中将要删除元组的主码值相同的所有元组一起删除。如果参照关系同时又是另一个关系的被参照关系,则这种删除操作会进行级联下去。
- 受限删除(RESTRICTED):仅当参照关系中没有任何元组的外码值与被参照关系要删除元组的主码值相同时,系统才执行删除操作,否则拒绝此删除操作。
- 置空值删除(NULLIFIES):删除被参照关系的元组,并将参照关系中相应元组的外码值置空值。
在这三种处理策略中,一般要根据应用环境的语义来选择其中的一种,不能一概而论。
-
在参照关系中插入元组时的问题:当用户向参照关系中插入一个元组时,如果被参照关系中并没有对应的元组时,是拒绝插入操作,还是进行其他处理的问题,就是在参照关系中插入元组时产生的问题。一般有两种不同的策略:
-
受限插入 仅当被参照关系中存在相应的元组,其主码值与参照关系刚插入元组的外码值相同时,系统才执行插入操作,否则拒绝此操作。
-
递归插入 首先向被参照关系中插入一个相应的元组,其主码值等于参照关系中将要插入元组的外码值,然后再向参照关系插入元组。
-
例:向SC关系插入(99001,1,90)元组,而Student关系中尚没有Sno=99001的学生。
- 受限插入:系统将拒绝向SC关系插入(99001,1,90)元组。
- 递归插入:系统将首先向Student关系插入Sno=99001的元组,然后向SC关系插入(99001,1,90)元组。
-
-
完整性设计的原则
- 实体完整性、参照完整性是关系数据库最重要的完整性约束,在不影响系统关键性能的前提下需尽量应用,用一定的时间和空间来换取系统的易用性是值得的。
- 在需求分析阶段就必须制定完整性约束的命名规范,尽量使用有意义的英文单词、缩写词、表名、列名及下划线等组合,使其易于识别和记忆。
根据业务规则对数据库完整性进行细致的测试,以尽早排除隐含的完整性约束间的冲突和对性能的影响。 - 要有专职的数据库设计小组,自始至终负责数据库的分析、设计、测试、实施及早期维护。
- 应采用合适的CASE工具来降低数据库设计各阶段的工作量。