Oracle 10g:CLOB 数据长度可以小于 4,000 吗?

发布于 2024-11-01 18:30:28 字数 386 浏览 4 评论 0 原文

我们拥有三个数据库:开发、登台和生产。我们在开发环境中完成所有编码。然后,我们将所有代码和数据库更改推送到暂存阶段,以便客户可以看到它在实时环境中的工作原理。在他们签字后,我们将最终部署到生产环境。

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

DBA 是否搞砸了一些事情?这还值得担心吗?似乎没有因此而破坏任何东西,但我只是希望元数据在所有环境中都相同。

We have three databases: dev, staging, and production. We do all our coding in the dev environment. We then push all our code and database changes to staging so the client can see how it works in a live environment. After they sign off, we do the final deployment to the production environment.

Now, about these CLOB columns: When using desc and/or querying the all_tab_columns view for the dev database, CLOBs show a data length of 4,000. However, in the staging and production databases, data lengths for dev-equivalent CLOB columns are odd numbers like 86. I've searched for every possible solution as to how this could have come about. I've even tried adding a new CLOB(86) column thinking it would work like it does for VARCHAR2, but Oracle just spits out an error.

Could the DBAs have botched something up? Is this even something to worry about? Nothing has ever seemed to break as a result of this, but I just like the metadata to be the same across all environments.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

北方。的韩爷 2024-11-08 18:30:28

首先,作为一名 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?

First of all, I - as a dba - feel sorry to see the lack of cooperation between you and the dbas. We all need to cooperate to be successful. Clob data lengths can be less than 4000 bytes.

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

Where do you find that a clob length can not be less than 4000?

jJeQQOZ5 2024-11-08 18:30:28

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,一些参考

请参阅 中的 rel="nofollow">LOB 存储 Oracle 数据库应用程序开发人员指南 - 大对象了解有关定义 LOB 存储的更多信息,尤其是讨论可以更改的内容的第三条注释:

注意:

只能修改部分存储参数。例如,你
可以使用ALTER TABLE ... MODIFY LOB语句来更改RETENTION
PCTVERSIONCACHENO CACHE LOGGINGNO LOGGING 以及 STORAGE
条款。

您还可以使用 ALTER TABLE ... 更改表空间
MOVE 语句。

但是,表一旦创建,就无法更改 CHUNK
大小,或启用或禁用行存储设置。

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

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

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

DATA_LENGTH stores the maximun # of bytes that will be taken up within the row for a column. If the CLOB can be stored in row, then the maximum is 4000. LOBS will never take up more than 4000 bytes. If in row storage is disabled, then the LOB will only store the pointer information it needs to find the LOB data, which is much less than 4000 bytes.

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

EDIT, adding info on *_LOBS view

Use the [DBA|ALL|USER]_LOBS view to look at the defined in row out of row storage settings:

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, some references

See LOB Storage in Oracle Database Application Developer's Guide - Large Objects for more information on defining LOB storage, especially the third note that talks about what can be changed:

Note:

Only some storage parameters can be modified. For example, you
can use the ALTER TABLE ... MODIFY LOB statement to change RETENTION,
PCTVERSION, CACHE or NO CACHE LOGGING or NO LOGGING, and the STORAGE
clause.

You can also change the TABLESPACE using the ALTER TABLE ...
MOVE statement.

However, once the table has been created, you cannot change the CHUNK
size, or the ENABLE or DISABLE STORAGE IN ROW settings.

Also, LOBs in Index Organized Tables says:

By default, all LOBs in an index organized table created without an overflow segment will be stored out of line. In other words, if an index organized table is created without an overflow segment, then the LOBs in this table have their default storage attributes as DISABLE STORAGE IN ROW. If you forcibly try to specify an ENABLE STORAGE IN ROW clause for such LOBs, then SQL will raise an error.

This explains why jonearles did not see 4,000 in the data_length column when he created the LOB in an index organized table.

情场扛把子 2024-11-08 18:30:28

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 之间的任意值,具体取决于数据库块大小。

CLOBs don't have a specified length. When you query ALL_TAB_COLUMNS, e.g.:

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

You'll notice that data_length is always 4000, but this should be ignored.

The minimum size of a CLOB is zero (0), and the maximum is anything from 8 TB to 128 TB depending on the database block size.

浴红衣 2024-11-08 18:30:28

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

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

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

As ik_zelf and Jeffrey Kemp pointed out, CLOBs can store less than 4000 bytes.

But why are CLOB data_lengths not always 4000? The number doesn't actually limit the CLOB, but you're probably right to worry about the metadata being
different on your servers. You might want to run DBMS_METADATA.GET_DDL on the objects on all servers and compare the results.

I was able to create a low data_length by adding a CLOB to an index organized table.

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';

On 10.2.0.1.0, the result is 116.
On 11.2.0.1.0, the result is 476.

Those numbers don't make any sense to me and I'd guess it's a bug. But I don't have a good understanding of the different storage options, maybe I'm just missing something.

Does anybody know what's really going on here?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文