Oracle 中地理数据库内的 BLOB 数据存储
在数据库管理系统 (DBMS) 行业,BLOB 是二进制大对象的英文首字母缩写。几年前甲骨文公司开始实施 BLOB 列,用 BLOB 列取代了用于存储二进制数据的 LONG RAW 技术。
BLOB 数据类型的结构分为三个基本部分:BLOB 列、LOB 段和 LOB 索引。如果 BLOB 列存储 LOB 定位器(36 个字节)并在行内存储二进制数据(如果二进制数据少于 3965 个字节且没有对该列禁用行内存储)。
ESRI 所做的测试表明允许行内存储可提供最佳性能,因此建议您不要禁用行内存储。
如果二进制数据超过 3964 个字节,则不会分配 BLOB 列的行内存储空间,并且 LOB 定位器将引用存储在 LOB 段中的二进制数据。
因此,启用行内存储时 BLOB 列中所存储的值始终至少为 36 个字节(分配给 LOB 定位器的空间)并且可能高达 4000 个字节(分配给 LOB 定位器的组合空间和可分配给行内所存储的二进制数据的最大空间)。
LOB 段分为许多区段。区段大小必须是 Oracle 数据块大小的倍数。例如,如果数据块大小为 8K,则可以使用 8K 的最小区段大小来创建 LOB 段。如果存储在 LOB 段内的数据长度为 5000 个字节,那么由于该数据量超过 3964 个字节且区段大小为 8K(或 8192 个字节),所以这些数据被存储到了 LOB 段中。在这种情况下,仍有 3192 个字节的 LOB 段区段未用。将数据从 LONG RAW 转换为 BLOB 将导致所需空间量增大,由于 LOB 段中出现未使用空间,而使增加量可能高达 30%。如果数据超过 3964 个字节(BLOB 列的行内存储阈值),这种情况就不可避免。
8K 的区段大小可提供最佳的 I/O 性能,同时使浪费的空间量最小。16K 的区段大小比 8K 的区段大小浪费的空间量大。因此,为避免空间损失,建议您使用 8K 数据块大小对当前具有 16K 数据块大小的数据库重新进行创建,或者,如果无法重新创建,则可在已使用 8K 块大小创建的表空间中创建 LOB 段。为此,您需要在 Oracle 系统全局区 (SGA) 中分配 8K 缓冲器高缓。
据发现,4K 和 2K 的区段大小浪费的空间量较少,但由于 I/O 成本增加而使得不会使用它们。
仅当 LOB 定位器寻址的区段数超过 12 时,才会使用 LOB 索引;否则,前 12 个区段由 LOB 定位器来寻址。
以下三幅图说明了存储在 BLOB 列中的二进制数据的三种可能存储情况。在第一种情况中,3000 个字节的二进制数据存储在行内,这是因为 3000 个字节小于 3965 个字节(行内存储阈值)。如果未对 BLOB 列禁用行内存储,则不会使用 LOB 段和 LOB 索引。通常,这会使 BLOB 数据提取速度加快,因为 Oracle 无需访问 LOB 段或 LOB 索引而使 I/O 操作次数减少。
下一幅图说明了第二种情况,二进制数据大于 3964 个字节(在本例中,数据为 81920 个字节),不适合在行内存储。因此,LOB 定位器引用存储在 LOB 段中的二进制数据。由于二进制数据在 LOB 段中占用的区段数低于 12 个,因此 LOB 定位器会存储其地址。在这种情况下,不使用 LOB 索引。
在最后一幅图中,二进制数据非常大(106496 个字节),需要使用 LOB 索引。在本例中,二进制数据超过行内存储且在 LOB 段内需要 12 个以上的区段来存储该数据。对于这么大的数据,LOB 定位器会引用 LOB 索引来获得 LOB 段内区段的位置。对于矢量数据来说这种情况极为罕见,而对于栅格数据则可避免发生这种情况。
设置 DBTUNE 参数来存储 BLOB 列
DBTUNE 表的存储参数控制着 ArcGIS 如何在 Oracle 中创建表和索引。有些存储参数还决定着创建表时使用的数据类型。有关 DBTUNE 表的详细信息,请参阅什么是 DBTUNE 表?有关 DBTUNE 存储参数的常规信息,请参阅什么是 DBTUNE 配置关键字和参数?
ArcSDE DBTUNE 存储参数 GEOMETRY_STORAGE、RASTER_STORAGE 和 ATTRIBUTE_BINARY 决定着存储 ArcSDE 数据所使用的 Oracle 数据类型。
GEOMETRY_STORAGE 参数控制着在要素类中存储矢量数据的方式。RASTER_STORAGE 参数控制着在栅格数据集、栅格目录或栅格属性中存储栅格数据的方式。最后,ATTRIBUTE_BINARY 参数控制着既不是矢量也不是栅格的所有其他二进制数据的存储。
要创建 BLOB 列,必须在给定 DBTUNE 关键字中对参数进行如下设置:
GEOMETRY_STORAGE SDELOB RASTER_STORAGE BLOB ATTRIBUTE_BINARY BLOB
对于矢量数据和栅格数据,ESRI 推荐使用以下 LOB 存储参数:
- 始终启用行内存储,因为多数地理信息系统 (GIS) 数据小于 3964 个字节(行内阈值)。在行内存储数据可提供最佳性能。
- 启用缓存,因为会频繁读取 ArcSDE 数据。
- 由于 ArcSDE 不对 BLOB 数据执行更新,而只是执行插入和删除,因此将 PCT_VERSION 设置为 0,这样做是因为无需保留 LOB 段内较旧版本的数据。
- 不应使用小于 8K 的区段大小。2K 和 4K 的区段大小会增加 I/O 量,因为 Oracle 服务器进程必须提取更多区段。您可能会发现 8K 的区段大小比 16K 的区段大小浪费的空间量少。如果使用 2K 或 4K 的区段大小,您会发现浪费的空间量较少,但经测试发现,与使用 8K 的区段大小存储时相比,多数栅格数据和矢量数据的显示时间有明显地增加。由于区段大小必须始终是数据块大小的倍数,所以用于在 BLOB 中存储 GIS 数据的最佳数据块大小是 8K。
以下示例说明了为适合以 BLOB 数据类型存储的栅格块表而对栅格 DBTUNE 存储参数进行修改后的结果:
RASTER_STORAGE "BLOB" BLK_STORAGE "PCTFREE 0 INITRANS 4 TABLESPACE RASTER LOB (BLOCK_DATA) STORE AS (TABLESPACE RASTER_LOB_SEGMENT CACHE PCTVERSION 0)" AUX_STORAGE "PCTFREE 0 INITRANS 4 TABLESPACE RASTER LOB (OBJECT) STORE AS (TABLESPACE RASTER CACHE PCTVERSION 0)"
RASTER_STORAGE "ST_RASTER" BLK_STORAGE "PCTFREE 0 INITRANS 4 TABLESPACE RASTER LOB (BLOCK_DATA) STORE AS (TABLESPACE RASTER_LOB_SEGMENT CACHE PCTVERSION 0)"
如果栅格块像素数据小于 3965 个字节,该数据将存储在 RASTER 表空间的 BLOCK_DATA 列中。但是,如果超过此阈值,则将存储在 RASTER_LOB_SEGMENT 表空间的 LOB 段中。仅当区段数超过 12 时才使用 LOB 索引。对于 ArcSDE 数据,不太可能发生这种情况。考虑使用 8K 区段大小的 LOB 段。仅当 ArcSDE 二进制数据超过 96K 时,才可使用 LOB 索引。
以下示例说明了为适合以 BLOB 数据类型存储的要素表而对矢量 DBTUNE 存储参数进行修改后的结果:
GEOMETRY_STORAGE "SDELOB" F_STORAGE "PCTFREE 0 INITRANS 4 TABLESPACE VECTOR LOB (POINTS) STORE AS (TABLESPACE VECTOR_LOB_SEGMENT CACHE PCTVERSION 0)"
GEOMETRY_STORAGE "ST_GEOMETRY"
如果要素的二进制数据小于 3965 个字节,该数据将存储在 VECTOR 表空间的 POINTS 列中。但是,如果超过此阈值,则将存储在 VECTOR_LOB_SEGMENT 表空间的 LOB 段中。
ATTRIBUTE_BINARY "BLOB" B_STORAGE "PCTFREE 0 INITRANS 4 TABLESPACE BIZZTABS LOB (DOCUMENT) STORE AS (TABLESPACE BIZZ_LOB_SEGMENT CACHE PCTVERSION 0)" A_STORAGE "PCTFREE 0 INITRANS 4 TABLESPACE BIZZTABS LOB (DOCUMENT) STORE AS (TABLESPACE BIZZ_LOB_SEGMENT CACHE PCTVERSION 0)"
在本示例中,如果业务表的二进制数据小于 3965 个字节,该数据将存储在 BIZZTABS 表空间的业务表的 BLOB 列中。但是,如果超过此阈值,则将存储在 BIZZ_LOB_SEGMENT 表空间的 LOB 段中。本示例中的 BLOB 列为 DOCUMENT。如果上方的 B_STORAGE DBTUNE 参数用来创建没有 DOCUMENT 列的表,Oracle 将返回以下错误:
ORA-00904: "DOCUMENT": invalid identifier
因此,最好不要将引用特定 BLOB 列的 B_STORAGE 或 A_STORAGE 参数添加到 DEFAULTS 关键字,因为业务表必须包含这些列。相反,您可以创建单独的 DBTUNE 关键字,然后将这些存储参数添加到这些关键字中。在创建表期间将引用包含存储参数的关键字。还应注意,如果特定的关键字不包含存储参数,则将使用 DEFAULTS 关键字的存储参数。鉴于这种情况,如果某关键字的配置字符串与 DEFAULTS 关键字下的存储参数相同,则无需在该关键字中添加特定的存储参数。例如,如果新关键字 ROADS 的所有存储参数(除 B_STORAGE 和 A_STORAGE 以外)都具有与 DEFAULTS 关键字的存储参数相同的配置字符串,那么您只需在 ROADS 关键字下创建 B_STORAGE 和 A_STORAGE 参数。其他所有存储参数都从 DEFAULTS 关键字读取,因为 ROADS 关键字不包含这些参数。