【问题标题】:Oracle 10g: Can CLOB data lengths be less than 4,000?Oracle 10g:CLOB 数据长度可以小于 4000 吗?
【发布时间】:2011-04-16 15:04:06
【问题描述】:

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

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

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

【问题讨论】:

  • 这个数据库的版本是否相同?
  • 我不知道,但我只能假设他们是。在登台和生产环境中,我无法访问与在开发环境中相同的东西,所以如果不询问 DBA(我不想与他们交谈),我不知道如何判断。是否有一些观点我可以查询以找出答案?
  • 赏金是为了准确解释小于 4000 的数字的含义。
  • 谢谢你的赏金,先生。这已经困扰我好几个月了。我希望有人能给出答案,这样我就可以关闭这个东西了。

标签: oracle oracle10g types clob


【解决方案1】:

首先,作为 dba,我很遗憾看到您与 dba 之间缺乏合作。我们都需要合作才能成功。 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?

【讨论】:

    【解决方案2】:

    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
    

    EDIT 2,一些参考资料

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

    注意:

    只能修改部分存储参数。例如,你 可以使用ALTER TABLE ... MODIFY LOB语句改变RETENTIONPCTVERSIONCACHENO CACHE LOGGINGNO LOGGINGSTORAGE 条款。

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

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

    另外,LOBs in Index Organized Tables 说:

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

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

    【讨论】:

    • 这是 10g R2,顺便说一句,10.2.0.4.0。不知道为什么索引组织的表的 data_length 更长。
    • 当我有时间的时候,我会阅读更多关于表内/表外存储的内容,但是这个元数据为什么在不同的数据库中是不同的呢?开发人员对 dev 数据库进行数据库修改。然后,我们在月底将我们的脚本提供给 DBA,让他们在生产环境中运行它们。我们的脚本将是create table whatever (clobrow clob),它在 dev 中显示的数据长度为 4000,正如预期的那样。 DBA 是否在生产中运行此脚本之前对其进行了更改,以便将其存储在表外?
    • @oscilatingcretin:我找不到为什么如果没有不同的create table 语句,LOB 存储特性会有所不同。或者对于某些存储特性发出alter table 语句。我对您的环境知之甚少,不知道如何运行不同的脚本。当然,DBA 审查所有脚本并“改进”它们是一种方法。另一种方式是变更管理中的问题,即后来使用错误的脚本重建了 dev。
    【解决方案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 之间,具体取决于数据库块大小。

    【讨论】:

      【解决方案4】:

      正如 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。

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

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

      【讨论】:

        猜你喜欢
        • 2019-10-03
        • 1970-01-01
        • 2020-03-20
        • 1970-01-01
        • 2019-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-04
        相关资源
        最近更新 更多