表的学习笔记


表的学习笔记本(除了列出的表之外,还有分区表和外部表,在此不一一列出):

1.heap table:
1.1 堆表。最常用,插入数据时,到HWM以下的空块。对于mssm,大于pctfree就从freelist中去掉,小于pctused时加到freelist

test@ORADG(192.168.0.41)create table t
 
2   (x int constraint x_pk primary key,
 
3   y date,
 
4   z clob)
 
5   tablespace mssm;
 
Table created.
 
Elapsed: 00:00:00.18
test@ORADG(192.168.0.41)> select dbms_metadata.get_ddl('TABLE','T') from dual;
 
DBMS_METADATA.GET_DDL('TABLE','T')
------------------------------------------------------------------------------
--
 

 
CREATE TABLE "TEST"."T"
  
(    "X" NUMBER(*,0),
        
"Y" DATE,
        
"Z" CLOB,
        
CONSTRAINT "X_PK" PRIMARY KEY ("X")
 
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
 
STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
 
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
 
TABLESPACE "MSSM"  ENABLE
  
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
 
STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
 
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
 
TABLESPACE "MSSM"
 
LOB ("Z") STORE AS (
 
TABLESPACE "MSSM" ENABLE STORAGE IN ROW CHUNK 8192 PCTVERSION 10
 
NOCACHE
 
STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
 
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT))

参数修改:

test@ORADG(192.168.0.41)> alter table t pctfree 10;
 
Table altered.
 
Elapsed: 00:00:00.06
test@ORADG(192.168.0.41)alter table t pctused 40;
 
Table altered.
 
Elapsed: 00:00:00.05
test@ORADG(192.168.0.41)> alter table t initrans 1 storage(FREELISTS 1);
 
Table altered.
 
Elapsed: 00:00:00.05

=========================================

2.IOT table:
2.1 索引组织表。适用:数据可以物理的在一起,减少io。如果每天话单的导入、如同一个owner,同一个object_type的各个object_name.
因此,给定一个时间点(某一天)或者给定的一个owner,相关的记录会放在同一个或者附件的块上。

test@ORADG(192.168.0.41)> li
 
1  create table tb_iot
 
2  (x varchar2(20),
 
3  y varchar2(20),
 
4  z varchar2(200),
 
5  constraint tb_iot_pk primary key(x,y,z)
 
6  )
 
7  organization index
 
8  compress 2
 
9  pctthreshold 10
 
10* overflow including z
test@ORADG(192.168.0.41)> /
 
Table created.

注:索引压缩:analyze index index_name validate structure;
select NAME,USED_SPACE,OPT_CMPR_COUNT,OPT_CMPR_PCTSAVE from index_stats;
查看建议的压缩层数。

=========================================

3.index clustered table
3.1 聚簇表。相近内容的“扎堆”(不同于IOT,IOT不仅仅会“扎堆”,而且还“有序”),和数据的加载顺序有关:
如果加载顺序是depno:1,2,3……则depno为1会在一个块,为2的也会在一个块,且可能是和depno为1的在同一个块。
如果加载顺序是depno:1,9,2……则depno为1会在一个块,为9的也会在一个块,且可能是和depno为1的在同一个块。但是depno为2的在一个块,但是和depno为1的不在一个块。
即数据扎堆,但不有序。
3.2 建立步骤:
3.2.1 create cluster
3.2.2 create index for cluster
3.2.3 create table need cluster
3.2.4 加载数据到表中
注:以上3.2.2和3.2.3顺序可以调换。

3.3 范例:

SQL> create cluster emp_dept_cluster(deptno number(2)) size 1024;

Cluster created.
注:size的大小很重要,每个块能放下簇的数量为:假设数据块为8k,则floor(8000/1024)=7,即每个块最多能放下7个depno的数据
因此size愈大,一个块中能容下最多cluster的数量越小。

SQL> create index emp_dept_cluster_idx on cluster emp_dept_cluster;
 
SQL> li
 
1  create table dept
 
2  (deptno number(2) primary key,
 
3  dname varchar2(14),
 
4  loc varchar2(13))
 
5* cluster emp_dept_cluster(deptno)
SQL> /
 
Table created.
 
SQL>
 
SQL> create table emp
 
2  (empno number primary key,
 
3  ename varchar2(10),
 
4  job varchar2(9),
 
5  mgr number,
 
6  hiredate date,
 
7  sal number,
 
8  comm number,
 
9  deptno number(2) references dept(deptno)
 
10  )
 
11  cluster emp_dept_cluster(deptno);
 
Table created.

=========================================

4.hash clustered table
4.1 哈希聚簇表。块会在创建时分配。
一般理想情况是hash键分布均匀,有一个hash函数可以将数字均匀分布到已经分配的块上。查询时利用一个io就能得到数据(走索引需要3个io)。
size过低的话,一个块中能容纳多个cluster,但是容易发生溢出,形成块串联。

test@ORADG(192.168.0.41)> li
 
1  create cluster hash_cluster (hash_key number)
 
2  hashkeys 1000
 
3  size 8192
 
4* tablespace mssm
test@ORADG(192.168.0.41)> /

Cluster created.
4.2 注意块在创建时候分配的空间为:hashkeys/trunc(dbblocksize/size),即1000/trunc(8000/8192),即hashkeys/(每个块上cluster的数量),即有1000/每个块上2个cluster键值,得需要200个块。
适用范围:hashkey:能预估到有多少个cluster,且每个cluster的数据尽量能均匀分布。注意where不要用范围检索,
4.3 特例:单表hash cluster:
适合于按照主键来访问的表,但是不关心是否聚簇。

SQL> create cluster hash_cluster
 
2  (hash_key number(10))
 
3  hashkeys 75000
 
4  size 150
 
5  single table
 
6  hash is hash_key
 
7  /
 
Cluster created.
 
SQL> create table t_hashed
 
2  cluster hash_cluster(object_id)
 
3  as
 
4  select owner,object_name,subobject_name,
 
5  cast(object_id as number(10)) as object_id,
 
6  data_object_id,object_type,created,
 
7  last_ddl_time,timestamp,status,temporary,
 
8  generated,secondary
 
9  from all_objects;
 
Cluster created.

注意number型的要在后面加hash is XXX(某个number型的字段),因为number是有精度的,在这边做hashkey要求是整形。

=========================================

5.sorted hash clustered table(10G新增)
5.1 有序哈希聚簇表。一般用于按照某个键值查询,但是按照另外一个键值排序。数据的加载建议按照sort的字段按顺序来。

SQL> create cluster shc
 
2  (cust_id number(10,0),
 
3  order_dt timestamp sort
 
4  )
 
5  hashkeys 1000
 
6  hash is cust_id
 
7  size 8192 
 
8  /
 
Cluster created.
 
SQL> li
 
1  create table cust_orders
 
2  (order_id number(10),
 
3  order_dt timestamp sort,
 
4  order_number number,
 
5  username varchar2(20),
 
6  ship_addr number,
 
7  bill_addr number,
 
8  invoice_num number
 
9  )
 
10* cluster shc (order_id,order_dt)
SQL> /
 
Table created.

=========================================

6.nested table:
6.1 嵌套表一般用于plsql编程,不常用于作为数据存储。(每行都可能有一个虚拟表)
6.2 步骤:
6.2.1 create type type_O as object(…)
6.2.2 create type type_T as table of type_O
6.2.3 create table table_A
(col_a type_a,col_b type_b,col_c type_T)
nested table col_c /* indeed,col_c is a table */
store as table_B; /* here table_B can be physical store in dbfile */
6.2.4 alter table_B add constraint unique(column_of_table_B);

6.3 范例:

test@ORADG(192.168.0.41)> create or replace type emp_type
 
2  as object
 
3  (EMPNO     NUMBER(4),
 
4  ENAME     VARCHAR2(10),
 
5  JOB       VARCHAR2(9),
 
6  MGR       NUMBER(4),
 
7  HIREDATE  DATE,
 
8  SAL       NUMBER(7,2),
 
9  COMM      NUMBER(7,2)   
 
10  )
 
11  /
 
Type created.
 
Elapsed: 00:00:01.80
test@ORADG(192.168.0.41)> create or replace type emp_tab_type as table of emp_type;
 
2  /
 
Type created.
 
Elapsed: 00:00:01.17
test@ORADG(192.168.0.41)> create table dept_and_emp
 
2  (deptno number(2) primary key,
 
3  dname varchar2(14),
 
4  loc varchar2(13),
 
5  emps emp_tab_type
 
6  )
 
7  nested table emps store as emp_nt;
 
Table created.
 
 
Elapsed: 00:00:01.00
test@ORADG(192.168.0.41)> alter table emp_nt add constraint emps_empno_unique unique(empno);
 
Table altered.

6.4 数据的加载:

test@ORADG(192.168.0.41)> insert into dept_and_emp
 
2  select dept.*,cast(multiset(select empno,ename,job,mgr,hiredate,sal,comm from scott.emp
 
3  where emp.deptno=dept.deptno) as emp_tab_type) from scott.dept
 
4  /
 
4 rows created.

6.5 数据的显示:

test@ORADG(192.168.0.41)> select * from dept_and_emp;
 
    
DEPTNO DNAME                        LOC                  EMPS(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM)
--------
-- ---------------------------- -------------------- ----------------------------------------------------------------------
        
10 ACCOUNTING                   NEW YORK             EMP_TAB_TYPE(EMP_TYPE(7782, 'CLARK', 'MANAGER', 7839, '09-JUN-81', 245
                                                            
0, 10), EMP_TYPE(7839, 'KING', 'PRESIDENT', NULL, '17-NOV-81', 5000, 1
                                                            
0), EMP_TYPE(7934, 'MILLER', 'CLERK', 7782, '23-JAN-82', 1300, 10))
 
        
20 RESEARCH                     DALLAS               EMP_TAB_TYPE(EMP_TYPE(7369, 'SMITH', 'CLERK', 7902, '17-DEC-80', 800,
                                                            
NULL), EMP_TYPE(7566, 'JONES', 'MANAGER', 7839, '02-APR-81', 2975, NUL
                                                            
L), EMP_TYPE(7788, 'SCOTT', 'ANALYST', 7566, '19-APR-87', 3000, NULL),
                                                              
EMP_TYPE(7876, 'ADAMS', 'CLERK', 7788, '23-MAY-87', 1100, NULL), EMP_
                                                            
TYPE(7902, 'FORD', 'ANALYST', 7566, '03-DEC-81', 3000, NULL))
 
        
30 SALES                        CHICAGO              EMP_TAB_TYPE(EMP_TYPE(7499, 'ALLEN', 'SALESMAN', 7698, '20-FEB-81', 16
                                                            
00, 300), EMP_TYPE(7521, 'WARD', 'SALESMAN', 7698, '22-FEB-81', 1250,
                                                            
500), EMP_TYPE(7654, 'MARTIN', 'SALESMAN', 7698, '28-SEP-81', 1250, 14
                                                            
00), EMP_TYPE(7698, 'BLAKE', 'MANAGER', 7839, '01-MAY-81', 2850, NULL)
                                                             ,
EMP_TYPE(7844, 'TURNER', 'SALESMAN', 7698, '08-SEP-81', 1500, 0), EM
                                                            
P_TYPE(7900, 'JAMES', 'CLERK', 7698, '03-DEC-81', 950, NULL))
 
        
40 OPERATIONS                   BOSTON               EMP_TAB_TYPE()
 
Elapsed: 00:00:00.01
test@ORADG(192.168.0.41)>
test@ORADG(192.168.0.41)>
test@ORADG(192.168.0.41)> select * from table(select emps from dept_and_emp);
select * from table(select emps from dept_and_emp)
                    *
ERROR at line 1:
ORA-01427: single-row subquery returns more than one row
 
 
Elapsed: 00:00:00.01
test@ORADG(192.168.0.41)>
test@ORADG(192.168.0.41)>
test@ORADG(192.168.0.41)> select * from table(select emps from dept_and_emp where deptno=20);
 
    
EMPNO ENAME                JOB                       MGR HIREDATE         SAL       COMM
--------
-- -------------------- ------------------ ---------- --------- ---------- ----------
      
7369 SMITH                CLERK                    7902 17-DEC-80        800
      
7566 JONES                MANAGER                  7839 02-APR-81       2975
      
7788 SCOTT                ANALYST                  7566 19-APR-87       3000
      
7876 ADAMS                CLERK                    7788 23-MAY-87       1100
      
7902 FORD                 ANALYST                  7566 03-DEC-81       3000

注:作为被存储的嵌套表,不能直接select:

test@ORALOCAL(192.168.0.128)> select * from emp_nt;
select * from emp_nt
              *
ERROR at line 1:
ORA-22812: cannot reference nested table column's storage table
 
 
Elapsed: 00:00:00.00
test@ORALOCAL(192.168.0.128)> select /*+ nested_table_get_refs */ * from emp_nt;
 
     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM
---------- ---------- --------- ---------- --------- ---------- ----------
      7782 CLARK      MANAGER         7839 09-JUN-81       2450
      7839 KING       PRESIDENT            17-NOV-81       5000
      7934 MILLER     CLERK           7782 23-JAN-82       1300
      7369 SMITH      CLERK           7902 17-DEC-80        800
      7566 JONES      MANAGER         7839 02-APR-81       2975
      7788 SCOTT      ANALYST         7566 19-APR-87       3000
      7876 ADAMS      CLERK           7788 23-MAY-87       1100
      7902 FORD       ANALYST         7566 03-DEC-81       3000
      7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300
      7521 WARD       SALESMAN        7698 22-FEB-81       1250        500
      7654 MARTIN     SALESMAN        7698 28-SEP-81       1250       1400
      7698 BLAKE      MANAGER         7839 01-MAY-81       2850
      7844 TURNER     SALESMAN        7698 08-SEP-81       1500          0
      7900 JAMES      CLERK           7698 03-DEC-81        950
 
14 rows selected.

=========================================

7.temporary table:
注:一般dbms_stats不收集临时表的统计信息,但是可以加gather_temp=>true,或者dbms_stats.set_table_stats来指定。

test@ORALOCAL(192.168.0.128)> create global temporary table tmp_comm_pre
 
2  on commit preserve rows
 
3  as select * from dba_users where 1=2
 
4  /
 
Table created.
 
Elapsed: 00:00:01.02
 
test@ORALOCAL(192.168.0.128)> create global temporary table tmp_comm_del
 
2  on commit delete rows
 
3  as select * from dba_users where 1=2
 
4  /
 
Table created.
 
Elapsed: 00:00:00.03
test@ORALOCAL(192.168.0.128)>
test@ORALOCAL(192.168.0.128)> insert into tmp_comm_pre select * from dba_users;
 
31 rows created.
 
Elapsed: 00:00:00.08
test@ORALOCAL(192.168.0.128)> insert into tmp_comm_del select * from dba_users;
 
31 rows created.
 
Elapsed: 00:00:00.01
test@ORALOCAL(192.168.0.128)>
test@ORALOCAL(192.168.0.128)> select cnt_pre,cnt_del from (selecct count(*) cnt_pre from tmp_comm_pre),
 
2  (select
 
3
test@ORALOCAL(192.168.0.128)>
test@ORALOCAL(192.168.0.128)>
test@ORALOCAL(192.168.0.128)> select cnt_pre,cnt_del from (select count(*) cnt_pre from tmp_comm_pre),
 
2  (select count(*) cnt_del from tmp_comm_del);
 
  
CNT_PRE    CNT_DEL
--------
-- ----------
        
31         31
 
Elapsed: 00:00:00.00
test@ORALOCAL(192.168.0.128)>
test@ORALOCAL(192.168.0.128)>
test@ORALOCAL(192.168.0.128)> commit;
 
Commit complete.
 
Elapsed: 00:00:00.00
test@ORALOCAL(192.168.0.128)> select cnt_pre,cnt_del from (select count(*) cnt_pre from tmp_comm_pre),
 
2  (select count(*) cnt_del from tmp_comm_del);
 
  
CNT_PRE    CNT_DEL
--------
-- ----------
        
31          0
 
Elapsed: 00:00:00.00
test@ORALOCAL(192.168.0.128)>

=========================================

8.object table:
与嵌套表类似,先定义type,再定义table
8.1 create type type_1 as object;
create type type_2 as object;
create table t1 as type_2;

8.2 范例:

test@ORALOCAL(192.168.0.128)> create or replace type address_type
 
2  as object
 
3  (city varchar2(30),
 
4  street varchar2(30),
 
5  state varchar2(2),
 
6  zip number
 
7  )
 
8  /
 
Type created.
 
Elapsed: 00:00:03.04
test@ORALOCAL(192.168.0.128)>
test@ORALOCAL(192.168.0.128)> create or replace type person_type
 
2  as object
 
3  (name varchar2(30),
 
4  dob date,
 
5  home_address address_type,
 
6  work_address address_type
 
7  )
 
8  /
 
Type created.
 
Elapsed: 00:00:00.06
 
test@ORALOCAL(192.168.0.128)> create table people of person_type;
 
Table created.

· 【文章发布信息】发表于: 2008-01-27 @ 01:33:49 · ||分类: Study note

留条评论