ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 讨论几种数据列Column的特性(下)

讨论几种数据列Column的特性(下)

原创 Linux操作系统 作者:realkid4 时间:2013-08-06 21:02:26 0 删除 编辑

上面我们主要讨论了unused column的特性,我们继续讨论virtual column和其他特性。

 

3Functional Index and hidden column

 

函数索引是会引起内部冗余列出现的。我们对数据表t列添加一个函数索引,对last_ddl_time后一天(+1)进行处理。

 

 

SQL> create index idx_t_last_plus_one on t(last_ddl_time+1);

Index created

 

SQL> exec dbms_stats.gather_table_stats(user,'T',cascade => true);

PL/SQL procedure successfully completed

 

 

此时,我们检查数据字典情况。

 

 

SQL> select column_name, HIDDEN_COLUMN, VIRTUAL_COLUMN, SEGMENT_COLUMN_ID from dba_tab_cols where wner='SCOTT' and table_name='T';

 

COLUMN_NAME                    HIDDEN_COLUMN VIRTUAL_COLUMN SEGMENT_COLUMN_ID

------------------------------ ------------- -------------- -----------------

OBJECT_ID                      NO            NO                             1

OBJECT_NAME                   NO            NO                             2

LAST_DDL_TIME                  NO            NO                             3

SYS_NC00004$                   YES           YES            

 

 

新增加了一个系统列,取名为“SYS_NC00004$”,其hiddenvirtual属性设置均为Yes

 

我们直接使用数据表的时候,该数据列默认是不现实出来的。

 

 

SQL> select * from t where rownum<5;

 

 OBJECT_ID OBJECT_NAM LAST_DDL_TIME

---------- ---------- -------------

        20 ICOL$      13-八月-09 23

        46 I_USER1    13-八月-09 23

        28 CON$       13-八月-09 23

        15 UNDO$      13-八月-09 23

 

 

但是,如果这个数据列被显式的指明出来,我们是可以看到这个虚列的。同时,在被索引列发生DML(增加、修改、删除)的时候,这个数据列遵循virtual column的特性连带进行修改。

 

 

SQL> select t.*, SYS_NC00004$ from t where rownum<5;

 

 OBJECT_ID OBJECT_NAM LAST_DDL_TIME SYS_NC00004$

---------- ---------- ------------- ------------

        20 ICOL$      13-八月-09 23 14-八月-09 2

        46 I_USER1    13-八月-09 23 14-八月-09 2

        28 CON$       13-八月-09 23 14-八月-09 2

        15 UNDO$      13-八月-09 23 14-八月-09 2

 

SQL> truncate table t;

Table truncated

 

SQL> insert into t select object_id, object_name, last_ddl_time from dba_objects where rownum<5;

4 rows inserted

 

SQL> commit;

Commit complete

 

SQL> select t.*, SYS_NC00004$ from t where rownum<5;

 

 OBJECT_ID OBJECT_NAM LAST_DDL_TIME SYS_NC00004$

---------- ---------- ------------- ------------

        20 ICOL$      13-八月-09 23 14-八月-09 2

        46 I_USER1    13-八月-09 23 14-八月-09 2

        28 CON$       13-八月-09 23 14-八月-09 2

        15 UNDO$      13-八月-09 23 14-八月-09 2

 

 

函数索引对应的内部列,由Oracle进行管理。如果函数索引被删除了,这个列自动就被删除。

 

 

SQL> drop index idx_t_last_plus_one;

 

Index dropped

 

SQL> select column_name, HIDDEN_COLUMN, VIRTUAL_COLUMN, SEGMENT_COLUMN_ID from dba_tab_cols where wner='SCOTT' and table_name='T';

 

COLUMN_NAME                    HIDDEN_COLUMN VIRTUAL_COLUMN SEGMENT_COLUMN_ID

------------------------------ ------------- -------------- -----------------

OBJECT_ID                      NO            NO                             1

OBJECT_NAME                   NO            NO                             2

LAST_DDL_TIME                  NO            NO                             3

 

 

 

4Virtual Column虚拟列

 

虚拟列最开始的初衷很简单,就是将业务逻辑、计算关系绑定在数据表column的列之间。让数据库去负责一些数据字段的计算。严格的说,这样的设计思想和传统的数据库设计理论和如今的业务逻辑划分原则是不符合的。

 

但是作为一个时代的产物,我们还是研究一下这个特性。

 

 

SQL> alter table t add mt number as (object_id+1);

 

Table altered

 

SQL> desc t

Name          Type          Nullable Default       Comments

------------- ------------- -------- ------------- --------

OBJECT_ID     NUMBER        Y                              

OBJECT_NAME   VARCHAR2(128) Y                              

LAST_DDL_TIME DATE          Y                              

MT            NUMBER        Y        "OBJECT_ID"+1          

 

 

添加virtual column之后,我们是可以通过desc查看到数据表中增加的mt列,这个列还有一个默认值。

 

 

SQL> select column_name, HIDDEN_COLUMN, VIRTUAL_COLUMN, SEGMENT_COLUMN_ID from dba_tab_cols where wner='SCOTT' and table_name='T';

 

COLUMN_NAME                    HIDDEN_COLUMN VIRTUAL_COLUMN SEGMENT_COLUMN_ID

------------------------------ ------------- -------------- -----------------

OBJECT_ID                      NO            NO                             1

MT                             NO            YES           

OBJECT_NAME                   NO            NO                             2

LAST_DDL_TIME                  NO            NO                             3

 

 

在数据字典里面,mt列被设置为virtual column,但是没有column_id。在select *列表中,我们是可以看到数据mt的。

 

 

SQL> select * from t;

 

 OBJECT_ID OBJECT_NAM LAST_DDL_TIME         MT

---------- ---------- ------------- ----------

        20 ICOL$      13-八月-09 23         21

        46 I_USER1    13-八月-09 23         47

        28 CON$       13-八月-09 23         29

        15 UNDO$      13-八月-09 23         16

 

 

但是,作为virtual column,其取值和修改,是Oracle自己管理的。我们不能手工的进行干预。

 

 

SQL> insert into t (mt) values (23);

 

insert into t (mt) values (23)

 

ORA-54013: 不允许对虚拟列执行 INSERT 操作

 

SQL> update t set mt=102;

 

update t set mt=102

 

ORA-54017: 不允许对虚拟列执行 UPDATE 操作

 

 

 

5、聊聊12c里面的visible column

 

最后我们聊聊发展趋势。我们在11g里面,已经有了对indexunusablevirtual index特性。

 

如果一个索引unusable了,说明这个索引在结构上已经被废止,段结构已经失去了合法性。自然也不会参与到Oracle优化器决策过程中。但是,这个索引如果要重新起作用,需要进行一个复杂的rebuild过程。

 

对大表而言,rebuild索引可能是一个持续时间很长的过程,而且要消耗很多资源。于是,Oracle推出了invisible index的特性,索引没有被设置为unusable,而且与数据之间的同步关系没有被打散,但是不参与到CBO决策过程。

 

Invisible index主要是为了进行执行计划的调整和实验,这样的策略较rebuild要好很多。

 

12c里面,我们发现Oracleinvisible的概念引入到column中,提出了invisible column的功能。这个特性最大的好处在于:相对于unused column而言,不可见列是可以逆转的操作。也就是说,我们今天将数据列设置为invisible之后,过一会可以“反悔”,再加回来,数据可以找回来。

 

目前,12c刚刚推出,很多大牛们的测试文章也逐渐出水。笔者作为后辈,权当汗牛充栋而已。

 

6、结论

 

Oraclecolumn提供了很多的特性,但是这些特性大都带有运维场景的背景要素。了解这些场景,适时的使用这些方法,对我们实际工作非常有意义。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17203031/viewspace-767910/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
求道~

注册时间:2010-11-30

  • 博文量
    545
  • 访问量
    7629949