Plsql中的复合数据类型主要包含以下几种:记录类型、关联数组、嵌套表、VARRAY。与常规的标量数据类型相比,这些复合数据类型提供了更高效的开发速度,以及更丰富的数据结构和功能。下面简单介绍下每种数据类型。
记录类型:
数据表中的每行都有一个或者多个不同数据类型的数据列,类似的,一个记录也是由一个或者多个字段组成。在日常业务开发中,通常会声明一个基于数据表的记录类型来保存数据。这样做的好处就是,不用定义过多零散的单独变量,并且每次编译时记录的结构都会自动根据表结构的变动来锚定调整,可以有效规避版本迭代中变量长度引起的异常问题。
在我们开发表触发器的时候,数据库给我们提供了2种结构, old 和 new ,这2个是伪记录。这2个结构和用 %rowtype 声明的基于表的记录类型有相同的格式:表中的每一列都有一个对应的字段。
基于数据表来定义记录类型的声明语法如下:
关联数组:
关联数组是一个只能在plsql环境中使用,一维、没有边界、稀疏、由同质元素构成的集合类型。其中的 index by 语法,可以通过 varchar2类型或者 pls_integer类型来关联或者索引集合中的元素。关联数组在使用的时候不需要初始化。
如下是一个使用关联数组循环扫描输出数据的简单示例:
嵌套表:
嵌套表也是一个一维、没有边界、稀疏、由同质元素构成的集合类型。嵌套表刚开始是紧凑的,不过随着不断的删除操作就开始变得稀疏了。嵌套表可以同时用于plsql和数据库内的列字段定义。需要注意,嵌套表在使用以前需要进行初始化操作。
嵌套表是多重集合的(支持高级集合操作:multiset union、multiset except等),因此嵌套表中的元素是没有固定顺序的。
如下是一个使用嵌套表高级集合操作multiset except的简单示例:
VARRAY:
VARRAY是可变长度的数组,当我们定义一个VARRAY类型时,必须指定它能包含的最大元素个数。和嵌套表一样,可以同时用于plsql和数据库。和嵌套表不一样的是,在VARRAY中保存数据或者提取数据时,它的元素总是有序的。这个特性在实现顺序存储元素的业务需求时很实用。需要注意,嵌套表在使用以前需要进行初始化操作。
如下是一个使用VARRAY顺序保存数据到数据库的简单示例:
其中关联数组、嵌套表、VARRAY有一些共享的内置函数和过程,可以获取集合的信息或者修改集合的内容。下面的示例中会使用到这些方法。
Count 函数: 返回集合中现有元素的数量。
Delete 过程:从集合中移除一个或者多个元素。如果不是重复移除,会减少 count 的值。对于VARRAY,只能删除集合里的所有元素。
Exists 函数:根据某个指定的元素是否已经在集合中返回 true 或者 false 。
Extend 过程:增加嵌套表或者 VARRAY 中元素的个数,同时增加 count 值。
First 、last 函数:返回可用的最小(First)和最大(last)集合下标。
Prior、next 函数:返回紧挨着指定的下标之前(Prior)或者之后(next)的下标值。在使用稀疏集合时,务必使用 Prior和next在集合内遍历。
除了常规的以pls_interger数据类型作为关联数组的索引,varchar数据类型也可以作为关联数组的索引。varchar数据类型索引的关联数组提供了更大的灵活性和能力。既然能够把字符数据类型作为索引,实际上差不多可以把任何东西当作索引,只要不超过数据库最大的长度限制。
下面是一个简单的示例:
对于使用字符串作为索引的集合来说,调用first,last,prior,next等方法的返回值是字符串而不是整数;字符类型索引的集合和整数类型索引的集合,在使用语法上没有区别。
灵活的使用字符串索引集合可以让我们的编程大大简化,把复杂度从算法转移到了数据库里的数据结构。下面是同样程序功能的2种写法。检查集合列表中是否存在已经使用过指定的字符串名称,如果没有使用过,则添加到集合末尾。
常规使用pls_integer类型索引的关联数组:
用while循环逐一扫描关联数组里面的每个元素,进行比较判断,查看是否有匹配的字符串名称。如果有就结束扫描并返回 true,否则返回 false。
使用字符类型索引的关联数组:
这次,要想确定一个字符串名称是否已经使用了,只需要用变量名称调用关联数组的exist 方法。如果有该索引值的元素,就说明这个字符串名称已经使用过了,而不需要再编写扫描集合内容寻找匹配的代码。代码更简洁高效了。
在这2种实现方法中,首先是第一种方法需要开发的代码量更多,其次是循环扫描消耗的 cpu 周期也更多。在编程的过程中,如果所要实现的算法是从集合中一个元素一个元素的发现某个匹配的值,可以考虑把这个集合重新设计成使用字符索引,以避免更长的循环扫描代码和更多的循环检查次数。这样得到的程序会更加精炼有效,同时以后维护起来也更加容易。
创建数据表,并录入数据:
检查录入的数据:
执行方案1查找:
执行方案2查找:
通过执行结果对比发现,方案2的耗时比方案1减少了很多。其中表字段的字符长度加长、比较字符串的长度加长,执行耗时也会随着增长,对比起来可以更直观一些。
当数据库表以字符类型的列作为主键或者创建唯一索引,通过字符类型索引的关联数组,可以缓存对应主键列或者唯一索引的数据行,减少频繁重复的数据库查询,节约系统资源。以员工信息表为例,当程序需要对员工信息表做大量的处理工作,可以把员工数据缓存到若干个集合中去,从而可以更高效的得到数据。
构建如下所示的测试案例:
用关联数组装载表中需要处理的数据,然后在进行逻辑处理的时候,直接使用关联数组里面缓存的数据,从 (name、emai、id) 3个索引中灵活选择所需员工的信息。利用关联数组和数据库包(全局变量、初始化模块)相关特性的组合功能,可以用来开发缓存数据库中使用频次很高的数据表,比如系统中的一些配置信息表。
另外,使用字符串索引和使用整数索引的在性能方面,主要取决于字符串的长度。当我们使用字符串索引时,数据库会把字符串“哈希”成一个整数值,因此开销完全是由哈希函数的性能决定的。
下面写了一个测试的小案例:
从测试的结果来看,100、200、400长度的字符类型索引与整数类型索引的性能基本没有显著区别。不过随着字符串索引的增长,哈希算法的开销也逐渐变得明显起来。因此可以结合实际的应用场景,灵活的选择使用字符串类型索引的关联数组。
文章
阅读量
获赞