暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle12c扩展数据类型

Oracle蓝莲花 2021-04-15
728


引言

开门见山

  从Oracle数据库12c开始,可以为VARCHAR2、NVARCHAR2和原始数据类型指定32767字节的最大大小。我们可以通过设置初始化参数MAX_STRING_SIZE来控制数据库是否支持这个新的参数设置,方法和规则也很简单,如果MAX_STRING_SIZE =STANDARD,则适用于Oracle数据库12c之前版本的大小限制:VARCHAR2和NVARCHAR2数据类型的大小限制为4000字节,原始数据类型的大小限制为2000字节。这是默认值,如果MAX_STRING_SIZE = EXTENDED,那么VARCHAR2、NVARCHAR2和原始数据类型的大小限制为32767字节定义字段精度大小大于4000字节的VARCHAR2或NVARCHAR2数据类型,或定义字段精度大小大于2000字节的原始数据类型,都是扩展数据类型。利用Oracle的LOB技术,扩展数据类型列被离线存储。LOB存储始终与表对齐。在使用自动段空间管理(ASSM)管理的表空间中,扩展数据类型列存储为SecureFiles lob。否则,它们将存储为BasicFiles lob。lob作为存储机制的使用只是内部的操作而已。

当然需要注意了:Oracle强烈反对使用BasicFiles lob作为存储机制。BasicFiles lob不仅限制了扩展数据类型列的功能,而且还计划在将来的版本中弃用BasicFiles数据类型。



     影响扩展数据类型的因素:

我们可以像使用标准数据类型一样使用扩展数据类型,但是基于文章负责层面,还是建议大家考虑以下因素:

1.有关在扩展数据类型列上创建索引或要求索引强制主键或惟一约束时的特殊考虑,一会咱们详细聊。

2.如果list分区的分区键列是一个扩展数据类型列,那么我们希望为分区指定的值列表可能会超过分区边界的4K字节限制。如何解决此类问题,别着急,我们还是一会详细聊。

    MAX_STRING_SIZE参数影响范围:

初始化参数MAX_STRING_SIZE的值影响因素包括:文本文字的最大长度,连接两个字符串的大小限制,NLSSORT函数返回的排序键的长度,XMLFormat对象的一些属性的大小,例如 XMLCOLATTVAL, XMLELEMENT, XMLFOREST, XMLPI,这些表达式。

扩展数据类型上创建索引:

决于数据库块大小和存储在块中的一些额外索引元数据。例如,对于使用Oracle标准8K块大小的数据库,最大密钥长度大约为6400字节,要解决诸如此类问题就要尽可能缩短索引长度。

创建一个基于函数的索引,以缩短作为索引定义表达式的一部分存储在扩展数据类型列中的值是个不错的办法

创建虚拟列以缩短存储在扩展数据类型列中的值,这些值是用于虚拟列定义的表达式的一部分,并在虚拟列上构建常规索引。使用虚拟列还可以利用常规列的功能,例如收集统计信息和使用约束和触发器。

凡事都有两面性,对于以上这两种方法,我们都可以使用SUBSTR或STANDARD_HASH函数来缩短扩展数据类型列的值,以构建索引。

这些方法有以下优点和缺点:

使用SUBSTR函数返回列的子字符串或前缀,这是索引键可接受的长度。这种类型的索引可以用于原始列上的等号、IN-list和range谓词,而不需要将SUBSTR列指定为谓词的一部分。

使用STANDARD_HASH函数可能会创建比基于substring的索引更紧凑的索引,从而减少不必要的索引访问。这种类型的索引可以用于原始列上的等式谓词和IN-list谓词,而不需要将SUBSTR列指定为谓词的一部分

    如何在扩展数据类型列上创建基于函数的索引:

CREATE INDEX index ON t_600_demo(SUBSTR(column, 0, n));

对于n,指定一个足够大的前缀长度来区分列中的值。

如何在虚拟列上创建索引:

ALTER TABLE t_600_demo ADD (new_hash_column AS (STANDARD_HASH(column)));

CREATE INDEX index ON t_600_demo(new_hash_column);

     索引列本身也存在一些限制:

不能在LONG、LONG RAW、LOB或REF的列或属性上创建索引,除非Oracle数据库支持使用SCOPE子句定义的REF类型列或属性上的索引。

只能在加密的列上创建普通(b树)索引。

    max_string_size参数设置:

扩展数据类型功能是使用MAX_STRING_SIZE初始化参数控制的。默认值是STANDARD,它将最大大小限制为传统长度。

将参数值设置为EXTENDED允许新的最大长度切换到扩展数据类型的过程是单向操作。一旦切换到扩展数据类型,如果不进行某种形式的数据库恢复,就无法切换回来。

除了更改参数之外,还必须运行utl32k.sql脚本使任何可能受最大长度更改影响的对象无效并重新编译。

下面显示了在单个实例非cdb数据库中启用扩展数据类型所需的命令示例:

     如何使用扩展数据类型:

参数认证脚本如下:

最大大小以字节为单位引用,因此使用字符语义定义的数据库列的最大大小取决于所使用的字符集。需要注意,NVARCHAR2总是使用字符语义定义的。

查看各个字段长度信息:

如果表的varchar2长度大于4000,那么还会自动创建一个LOBSEGMENT和一个loindex段。但实际上,插入的行可能足够短,可以内联存储。

     阶段性总结:

目前我们知道了VARCHAR2、NVARCHAR2和原始数据类型的最大大小已从4,000字节增加到32,767字节增加这些数据类型的分配大小允许用户在切换到大型对象(lob)之前在字符数据类型中存储更多信息。这对于简短的文本数据类型以及在这些类型的列上构建索引的功能尤其有用,我们只是站在工作原理理论角度给出了一些说法,目前还没有实践和作用相对较大存储参数对于索引的响应。

我们尝试通过一个简单的案例,了解了扩展数据类型的优势和好处。

接下来我们进入新的知识环节。

一个隐含参数:

Oracle如何将VARCHAR2、NVARCHAR2以及RAW类型存储存储为BLOB的阈值呢,取决于

_scalar_type_lob_storage_threshold隐含参数:

如何控制扩展数据类型从字符类型转换为非结构化的lob

这里可以确定,初始化创建的t_600_extended有lob信息,但通过隐含参数修改,新建立的t_600_extended_first和second表是不存在lob信息的。

对表的存储空间分析说明:

利用Oracle的LOB技术,扩展数据类型列被离线存储。LOB存储始终与表对齐。开篇文章中我们提到,在使用自动段空间管理(ASSM)管理的表空间中,扩展数据类型列存储为SecureFiles lob。否则,它们将存储为BasicFiles lob。lob作为存储机制的使用只是内部的。因此,不能使用DBMS_LOB包操作这些lob,来看看如下操作:

只要数据字段不超过VARCHAR2的4000字节,我们就不会感受到扩展数据类型的存在。但是随着字符串大小限制的取消,我们可能会遇到另一个限制,比如开篇我们提到的索引列的总大小大约是数据库块大小的75%。如果我们使用的VARCHAR2大小远远大于4000,那么我们可能无法在该字段上创建索引,这时候就应该设定32k块大小的表空间,以将风险降到最低。

在12c之前的版本,当使用数据类型CLOB从一个字节字符集(例如WE8ISO8859P15或WE8MSWIN1252)迁移到unicode时,我们遇到了一个问题。CLOB列的大小将增加一倍!Oracle 12c没有改变这种行为。

传统意义来讲当数据库字符集为多字节时,例如UTF8或AL32UTF8, CLOB列中的数据存储在AL16UTF16字符集中。这意味着在转换数据时,文档所需的存储空间将增加一倍。

所以,我们可以反问Oracle,这是否意味着所有超过4000字节的VARCHAR2字段现在都需要双倍的空间呢,答案必然不是!!!从VARCHAR2到CLOB的内部转换不会改变字符集,因此ar值仍然存储在AL32UTF8中——否则我们使用extendedtable

的示例不会成功。

所以,如果必须在enmax_string_size=extendedor转换为clob之间进行选择,个人还是建议大家采用Oracle 12c的新特性。但是,如果已经在使用clob,只要数据库中有足够的空间,不想麻烦就算了。

扩展数据类型可能的负面影响:

记不记得开篇我们聊到在扩展字段建立索引的问题,说:如果已经创建了一个基于函数的索引,返回一个varchar2()类型和创建索引substr()的返回值的数据类型函数的返回值将从当前的默认varchar2 varchar2(32767)(4000)去进行数据检索的情况,下面我们来具体做个试验:

示例显示了在修改数据库以允许扩展数据类型之后使用显式substr()调用创建的索引。我的观点是,如果我们定义了一个没有substr()的预升级索引,那么它将是有效的,因为一个键的长度大约为6400字节;但是在升级之后,该索引将变得无效,我们就必须将其替换为使用显式substr()的索引,所以我们有必要在重复一下索引的工作原理运用在扩展数据类型上。

如果列是扩展数据类型列,那么在尝试创建索引时,我们可能会收到maximum key length exceeded错误。索引的最大键长取决于数据库块大小和存储在块中的一些额外索引元数据。例如,对于使用Oracle标准8K块大小的数据库,最大密钥长度大约为6400字节,要解决诸如此类问题就要尽可能缩短索引长度。

创建一个基于函数的索引,以缩短作为索引定义表达式的一部分存储在扩展数据类型列中的值是个不错的办法。

创建虚拟列以缩短存储在扩展数据类型列中的值,这些值是用于虚拟列定义的表达式的一部分,并在虚拟列上构建常规索引。使用虚拟列还可以利用常规列的功能,例如收集统计信息和使用约束和触发器。

凡事都有两面性,对于以上这两种方法,我们都可以使用SUBSTR或STANDARD_HASH函数来缩短扩展数据类型列的值,以构建索引。

这些方法有以下优点和缺点:

使用SUBSTR函数返回列的子字符串或前缀,这是索引键可接受的长度。这种类型的索引可以用于原始列上的等号、IN-list和range谓词,而不需要将SUBSTR列指定为谓词的一部分。

使用STANDARD_HASH函数可能会创建比基于substring的索引更紧凑的索引,从而减少不必要的索引访问。这种类型的索引可以用于原始列上的等式谓词和IN-list谓词,而不需要将SUBSTR列指定为谓词的一部分。

我们尝试在11.2.0.4版本Oracle数据库上做一些测试注意,当索引定义更改为包含substr()时,执行计划将如何更改。


总结

今天和大家分享了关于Oracle12c扩展数据类型的新特性,希望这篇文章能够帮助大家更好的学习新特性,非常感谢。


敲黑板,划重点啦!

赶快!马上!立刻!

点击下方“阅读原文”查看600团队首次H5秀吧~

文章转载自Oracle蓝莲花,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论