上面我们主要讨论了unused column的特性,我们继续讨论virtual column和其他特性。
3、Functional 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$”,其hidden和virtual属性设置均为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
4、Virtual 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里面,已经有了对index的unusable和virtual index特性。
如果一个索引unusable了,说明这个索引在结构上已经被废止,段结构已经失去了合法性。自然也不会参与到Oracle优化器决策过程中。但是,这个索引如果要重新起作用,需要进行一个复杂的rebuild过程。
对大表而言,rebuild索引可能是一个持续时间很长的过程,而且要消耗很多资源。于是,Oracle推出了invisible index的特性,索引没有被设置为unusable,而且与数据之间的同步关系没有被打散,但是不参与到CBO决策过程。
Invisible index主要是为了进行执行计划的调整和实验,这样的策略较rebuild要好很多。
在12c里面,我们发现Oracle将invisible的概念引入到column中,提出了invisible column的功能。这个特性最大的好处在于:相对于unused column而言,不可见列是可以逆转的操作。也就是说,我们今天将数据列设置为invisible之后,过一会可以“反悔”,再加回来,数据可以找回来。
目前,12c刚刚推出,很多大牛们的测试文章也逐渐出水。笔者作为后辈,权当汗牛充栋而已。
6、结论
Oracle对column提供了很多的特性,但是这些特性大都带有运维场景的背景要素。了解这些场景,适时的使用这些方法,对我们实际工作非常有意义。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17203031/viewspace-767910/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/17203031/viewspace-767910/