3

我们有三个数据库:dev、staging 和 production。我们在开发环境中进行所有编码。然后,我们将所有代码和数据库更改推送到 staging,以便客户端可以看到它在实时环境中的工作方式。在他们签字后,我们对生产环境进行最终部署。

现在,关于这些 CLOB 列:当使用 desc 和/或查询 dev 数据库的 all_tab_columns 视图时,CLOB 显示的数据长度为 4,000。但是,在暂存和生产数据库中,与开发等效的 CLOB 列的数据长度是奇数,例如 86。我已经搜索了所有可能的解决方案,以了解这是如何发生的。我什至尝试添加一个新的 CLOB(86) 列,认为它可以像 VARCHAR2 一样工作,但 Oracle 只是吐出一个错误。

DBA 会搞砸一些事情吗?这还需要担心吗?似乎没有任何事情因此而中断,但我只是希望元数据在所有环境中都是相同的。

4

4 回答 4

4

首先,作为 dba,我很遗憾看到您和 dbas 之间缺乏合作。我们都需要合作才能成功。Clob 数据长度可以小于 4000 字节。

create table z ( a number, b clob);
Table created.
insert into z values (1, 'boe');

1 row created.
exec dbms_stats.gather_table_stats (ownname => 'ronr', tabname => 'z');

PL/SQL procedure successfully completed.
select owner, avg_row_len from dba_tables where table_name = 'Z'
SQL> /

OWNER                  AVG_ROW_LEN
------------------------------ -----------
RONR                       109

select length(b) from z;

 LENGTH(B)
----------
     3

你在哪里发现一个clob长度不能小于4000?

于 2011-04-16T22:02:38.810 回答
4

DATA_LENGTH 存储将在行内为一列占用的最大字节数。如果 CLOB 可以按行存储,则最大值为 4000。LOBS 永远不会占用超过 4000 字节。如果禁用行内存储,则 LOB 将仅存储查找 LOB 数据所需的指针信息,这远小于 4000 字节。

SQL> create table t (clob_in_table clob
  2     , clob_out_of_table clob
  3  ) lob (clob_out_of_table) store as (disable storage in row)
  4     , lob (clob_in_table) store as (enable storage in row)
  5  /

Table created.

SQL> select table_name, column_name, data_length
  2  from user_tab_columns
  3  where table_name = 'T'
  4  /

TABLE_NAME                     COLUMN_NAME                    DATA_LENGTH
------------------------------ ------------------------------ -----------
T                              CLOB_IN_TABLE                         4000
T                              CLOB_OUT_OF_TABLE                       86

编辑,在 *_LOBS 视图上添加信息

使用 [DBA|ALL|USER]_LOBS 视图查看定义的行外存储设置:

SQL> select table_name
  2     , cast(substr(column_name, 1, 30) as varchar2(30))
  3     , in_row
  4  from user_lobs
  5  where table_name = 'T'
  6  /

TABLE_NAME                     CAST(SUBSTR(COLUMN_NAME,1,30)A IN_
------------------------------ ------------------------------ ---
T                              CLOB_IN_TABLE                  YES
T                              CLOB_OUT_OF_TABLE              NO

编辑 2,一些参考资料

有关定义 LOB存储的更多信息,请参阅Oracle Database Application Developer's Guide - Large Objects中的 LOB 存储,尤其是第三条说明可以更改的内容:

笔记:

只能修改部分存储参数。例如,您可以使用ALTER TABLE ... MODIFY LOB语句来更改RETENTION, PCTVERSION, CACHEor NO CACHE LOGGINGor NO LOGGING, 和STORAGE 子句。

您还可以使用 ALTER TABLE ... MOVE 语句更改 TABLESPACE。

但是,一旦创建了表,就不能更改 CHUNK 大小,或者 ENABLE 或 DISABLE STORAGE IN ROW 设置。

此外,索引组织表中的 LOB说:

默认情况下,在没有溢出段的情况下创建的索引组织表中的所有 LOB 都将被离线存储。换句话说,如果创建索引组织表时没有溢出段,则该表中的 LOB 的默认存储属性为 DISABLE STORAGE IN ROW。如果您强制尝试为此类 LOB 指定 ENABLE STORAGE IN ROW 子句,则 SQL 将引发错误。

这就解释了为什么 jonearles 在索引组织表中创建 LOB 时没有在 data_length 列中看到 4,000。

于 2011-08-26T23:54:41.140 回答
3

CLOB 没有指定的长度。当您查询 ALL_TAB_COLUMNS 时,例如:

select table_name, column_name, data_length
from all_tab_columns
where data_type = 'CLOB';

您会注意到 data_length 始终为 4000,但这应该被忽略。

CLOB 的最小大小为零 (0),最大值介于 8 TB 到 128 TB 之间,具体取决于数据库块大小。

于 2011-04-18T02:23:33.297 回答
1

正如 ik_zelf 和 Jeffrey Kemp 所指出的,CLOB 可以存储少于 4000 个字节。

但是为什么 CLOB data_lengths 并不总是 4000?该数字实际上并不限制 CLOB,但您担心服务器上的元数据不同可能是正确的。您可能希望在所有服务器上的对象上运行 DBMS_METADATA.GET_DDL 并比较结果。

通过将 CLOB 添加到索引组织表中,我能够创建一个低 data_length。

create table test
(
    column1 number,
    column2 clob,
    constraint test_pk primary key (column1)
)
organization index;

select data_length from user_tab_cols
where table_name = 'TEST' and column_name = 'COLUMN2';

在 10.2.0.1.0 上,结果为 116。
在 11.2.0.1.0 上,结果为 476。

这些数字对我没有任何意义,我猜这是一个错误。但是我对不同的存储选项没有很好的了解,也许我只是错过了一些东西。

有人知道这里到底发生了什么吗?

于 2011-04-18T07:06:43.753 回答