ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 列定义的顺序和列存储的顺序

列定义的顺序和列存储的顺序

原创 Linux操作系统 作者:yangtingkun 时间:2009-07-08 22:44:25 0 删除 编辑

今天在看管理员手册的时候,Oracle提到了索引组织表列的顺序问题。于是做了个测试验证了一下。

 

 

由于索引组织表是根据索引的格式存储的表,所以主键的键值列应该存储在前面,随后才是表中的其他列,下面建立一个索引组织表,将主键列放在后面:

SQL> CREATE TABLE T_INDEX_ORG (NAME VARCHAR2(30), ID NUMBER PRIMARY KEY)
  2  ORGANIZATION INDEX;

表已创建。

SQL> DESC T_INDEX_ORG
 
名称                                                              是否为空? 类型
 ----------------------------------------------------------------- -------- ----------------
 NAME                                                                       VARCHAR2(30)
 ID                                                                NOT NULL NUMBER

DESCNAME列排在主键列的前面,查询DBA_TAB_COLUMNS视图:

SQL> SELECT TABLE_NAME, COLUMN_NAME, COLUMN_ID
  2  FROM USER_TAB_COLUMNS
  3  WHERE TABLE_NAME = 'T_INDEX_ORG';

TABLE_NAME                     COLUMN_NAME                     COLUMN_ID
------------------------------ ------------------------------ ----------
T_INDEX_ORG                    NAME                                    1
T_INDEX_ORG                    ID                                      2

可以看到NAME列仍然在主键列的前面,难道Oracle在存储的时候真的先存储其他列,最后才是主键列吗,其实不然,这个列的顺序只是定义的顺序,真正的存储顺序需要查询COL$表:

SQL> COL OBJECT_NAME FORMAT A30
SQL> SELECT OBJECT_ID, OWNER, OBJECT_NAME
  2  FROM DBA_OBJECTS
  3  WHERE OBJECT_NAME = 'T_INDEX_ORG'
  4  AND WNER = USER;

 OBJECT_ID OWNER                          OBJECT_NAME
---------- ------------------------------ ---------------
     93348 YANGTK                         T_INDEX_ORG

SQL> SELECT OBJ#, COL#, SEGCOL#, NAME
  2  FROM SYS.COL$
  3  WHERE OBJ# = 93348;

      OBJ#       COL#    SEGCOL# NAME
---------- ---------- ---------- ------------------------
     93348          1          2 NAME
     93348          2          1 ID

可以看到,SEGCOL#列表示的是存储时列的顺序,和预料的一样,对于索引组织表,Oracle会先存储主键列,然后是其他的非键值列。

除了索引组织表以外,还有一些可能导致列的定义与列的存储顺序不符,比如包含LONG列的情况。

OracleLONG列用于存放在表的最后一列:

SQL> CREATE TABLE T_LONG (ID NUMBER, C_LONG LONG, NAME VARCHAR2(30));

表已创建。

SQL> SELECT OBJECT_ID, OWNER, OBJECT_NAME
  2  FROM DBA_OBJECTS
  3  WHERE OBJECT_NAME = 'T_LONG'
  4  AND WNER = USER;

 OBJECT_ID OWNER                          OBJECT_NAME
---------- ------------------------------ ----------------------------
     93350 YANGTK                         T_LONG

SQL> SELECT OBJ#, COL#, SEGCOL#, NAME
  2  FROM SYS.COL$
  3  WHERE OBJ# = 93350;

      OBJ#       COL#    SEGCOL# NAME
---------- ---------- ---------- ------------------------------
     93350          1          1 ID
     93350          2          3 C_LONG
     93350          3          2 NAME

除了包含LONG的表,CLUSTER表也有同样的现象,CLUSTER的索引列在存储是排在第一位:

SQL> CREATE CLUSTER C_DEPT (DEPTNO NUMBER);

簇已创建。

SQL> CREATE TABLE DEPT (DEPT_NAME VARCHAR2(30), DEPT_NO NUMBER)
  2  CLUSTER C_DEPT (DEPT_NO);

表已创建。

SQL> CREATE TABLE EMP (EMP_NO NUMBER, EMP_NAME VARCHAR2(30), DEPT_NO NUMBER)
  2  CLUSTER C_DEPT (DEPT_NO);

表已创建。

SQL> SELECT OBJECT_ID, OWNER, OBJECT_NAME
  2  FROM DBA_OBJECTS
  3  WHERE WNER = USER
  4  AND OBJECT_NAME IN ('EMP', 'DEPT');

 OBJECT_ID OWNER                          OBJECT_NAME
---------- ------------------------------ ------------------------------
     93355 YANGTK                         DEPT
     93356 YANGTK                         EMP

SQL> SELECT OBJ#, COL#, SEGCOL#, NAME
  2  FROM SYS.COL$
  3  WHERE OBJ# IN (93355, 93356);

      OBJ#       COL#    SEGCOL# NAME
---------- ---------- ---------- ------------------------------
     93355          1          2 DEPT_NAME
     93355          2          1 DEPT_NO
     93356          1          2 EMP_NO
     93356          2          3 EMP_NAME
     93356          3          1 DEPT_NO

同样HASH CLUSTER也具有相同的特性:

SQL> CREATE CLUSTER C_HASH (ID NUMBER)
  2  HASHKEYS 100;

簇已创建。

SQL> CREATE TABLE T_HASH (NAME VARCHAR2(30), ID NUMBER)
  2  CLUSTER C_HASH (ID);

表已创建。

SQL> SELECT OBJECT_ID, OWNER, OBJECT_NAME
  2  FROM DBA_OBJECTS
  3  WHERE WNER = USER
  4  AND OBJECT_NAME = 'T_HASH';

 OBJECT_ID OWNER                          OBJECT_NAME
---------- ------------------------------ ----------------
     93358 YANGTK                         T_HASH

SQL> SELECT OBJ#, COL#, SEGCOL#, NAME
  2  FROM SYS.COL$
  3  WHERE OBJ# = 93358;

      OBJ#       COL#    SEGCOL# NAME
---------- ---------- ---------- -------------------------
     93358          1          2 NAME
     93358          2          1 ID

除了上面这些例子外,函数索引,嵌套表,对象表都会添加一些隐藏列,这些也会对列的存储顺序有所影响。

 

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

请登录后发表评论 登录
全部评论
暂无介绍

注册时间:2007-12-29

  • 博文量
    1955
  • 访问量
    10404854