表的学习笔记本(除了列出的表之外,还有分区表和外部表,在此不一一列出):
1.heap table:
1.1 堆表。最常用,插入数据时,到HWM以下的空块。对于mssm,大于pctfree就从freelist中去掉,小于pctused时加到freelist
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
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)) |
参数修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
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,相关的记录会放在同一个或者附件的块上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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 范例:
1 |
SQL> create cluster emp_dept_cluster(deptno number(2)) size 1024; |
Cluster created.
注:size的大小很重要,每个块能放下簇的数量为:假设数据块为8k,则floor(8000/1024)=7,即每个块最多能放下7个depno的数据
因此size愈大,一个块中能容下最多cluster的数量越小。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
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,但是容易发生溢出,形成块串联。
1 2 3 4 5 6 |
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:
适合于按照主键来访问的表,但是不关心是否聚簇。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
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的字段按顺序来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
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 范例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
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 数据的加载:
1 2 3 4 5 6 |
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 数据的显示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
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来指定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
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 范例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
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. |