--========================================sql
-- 簇表及簇表管理(Index clustered tables)oracle
--========================================ide
簇表是Oracle中一種可選、的存儲表數據的方法。使用簇表能夠減小磁盤I/O,改善訪問簇表的聯結所帶來的資源開銷,本文講述了簇表的原理、建立以及管理簇表等。函數
1、什麼是簇表及簇表的特性oop
1.簇表性能
由共享相同數據塊的一組表組成。在堆表的管理過程當中,對於某些表的某些列和另外的表的某些列常常被用來聯結使用,能夠將這些表的聯結列做爲共享的公共列而將這些表組合在一塊兒。這就是簇表造成的緣由。例如,scott模式中,有emp表,dept表,兩個表常用 deptno列來進行聯結,爲此,咱們共享deptno列,將emp和dept表組成簇表。組成簇表後,Oracle物理上將emp和dept表中有關每一個部門全部行存儲到相同的數據塊中。ui
簇表不能等同於SQL server中的簇索引,二者並非一回事。SQL server中的簇索引是使得行的存儲按索引鍵來存儲,相似於IOT表。spa
2.簇鍵server
簇鍵是列或多列的組合,爲簇表所共有對象
在建立簇時指定簇鍵的列,之後在建立增長的簇中的每一個表時,指定相同的列便可
每一個簇鍵值在簇和簇索引中僅僅存儲一次,與不一樣表中有有多少這樣的行無關
3.使用簇表的好處。
減小磁盤I/O,減小了因使用聯結所帶來的系統開銷
節省了磁盤存儲空間,由於原來須要單獨存放多張表,如今能夠將聯結的部分做爲共享列的存儲。
4.什麼時候建立簇表
對於常常查詢、當DML較少的表
表中的記錄常用到聯結查詢
5.建立簇表的步驟
建立簇
建立簇索引
建立簇表
6.建立簇、簇鍵、簇表時考慮的問題
哪些表適用於建立簇
對於建立簇的表哪些列用做簇列
建立簇時數據塊空間如何使用(pctfree,pctused)
平均簇鍵及相關行所需的空間大小
簇索引的位置(好比存放到不一樣的表空間)
預估簇的大小
2、建立簇及簇表
在建立簇時,若是未指定索引列,則默認地建立一個索引簇。
若是指定了散列參數,如hashkeys,hashis 或single table hashkeys,則能夠建立散列簇
SQL> show user;
USER is "ROBINSON"
SQL> create cluster emp_dept_cluster(deptno number(2))
2 pctused 80
3 pctfree 15
4 size 1024
5 tablespace users;
Cluster created.
在上面建立的簇中,一個最重要的參數就是size,須要爲size 指定合適的大小,若是size 指定的太大,則每一個塊僅僅能存放
少許的簇,容易引發空間的浪費,若是指定的過小,則容易產生過多的數據鏈
建立簇索引的條件
模式中必須包含簇
必須具備create any index的權限
簇索引的做用
用於一個簇鍵值並返回的包含該簇鍵值的地址塊
SQL> create index emp_dept_cluster_idx
2 on cluster emp_dept_cluster;
Index created.
建立簇表
SQL> create table dept
2 (deptno number(2) primary key,
3 dname varchar2(14),
4 loc varchar2(13)
5 )
6 cluster emp_dept_cluster(deptno); --使用了cluster關鍵字後面跟簇名、簇列
Table created.
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); --使用了cluster關鍵字後面跟簇名、簇列
Table created.
對於建立的簇表,與普通表的惟一差異是使用了cluster關鍵字,即告訴oracle 基表的哪一列將映射到簇表中
查看剛剛建立的簇對象
SQL> select object_name,object_type,status from user_objects order by object_name ;
OBJECT_NAME OBJECT_TYPE STATUS
-------------------- ------------------- -------
DEPT TABLE VALID --簇表dept
EMP TABLE VALID --簇表emp
EMP_DEPT_CLUSTER CLUSTER VALID --簇emp_dept_cluster
EMP_DEPT_CLUSTER_IDX INDEX VALID --簇索引
SYS_C005422 INDEX VALID
SYS_C005423 INDEX VALID
SQL> select table_name,tablespace_name,cluster_name,status,pct_free from
2 dba_tables where owner = 'ROBINSON';
TABLE_NAME TABLESPACE_NAME CLUSTER_NAME STATUS PCT_FREE
--------------- --------------- ------------------ -------- ----------
EMP USERS EMP_DEPT_CLUSTER VALID 0
DEPT USERS EMP_DEPT_CLUSTER VALID 0
下面開始對簇表填充數據
SQL> begin
2 for x in ( select * from scott.dept )
3 loop
4 insert into dept
5 values ( x.deptno, x.dname, x.loc );
6 insert into emp
7 select * from scott.emp
8 where deptno = x.deptno;
9 end loop;
10 end;
11 /
PL/SQL procedure successfully completed.
3、更改簇
對於已經建立的簇,咱們能夠修改簇的相關屬性,好比
修改簇的物理屬性(pctfree,pctused,initrans,maxtrans等)
存儲簇鍵值的全部行所需空間的平均值(size)
默認的並行度
alter cluster emp_dpet_cluster
pctfree 20
initrans 3;
4、刪除簇、簇表
1.刪除簇
能夠刪除再也不須要的簇,刪除簇時,簇中對應的表及對應的簇索引都將被刪除
簇數據段佔用的盤區以及簇索引段佔用的盤區將被釋放返還給各自所在的表空間
刪除不包含表及索引的簇
drop cluster emp_dept_cluster;
對於包含簇表的簇,可使用including talbes選項,若是簇中包含表但未使用including tables子句,將收到錯誤信息
drop cluster emp_dept_cluster including tables;
對於包含簇以外的foreign key 約束說參照的主鍵,須要使用cascade constraints子句
drop cluster emp_dept including tables cascade constraints
2.刪除簇表
對於再也不使用的簇表能夠直接使用drop table table_name命令來刪除
drop table emp;
drop table dept;
3.刪除簇索引
簇索引能夠被刪除而不影響簇或它的簇表
若不存在簇索引則簇表也沒法使用
對於簇的訪問,則須要重建簇索引
drop index emp_dept_cluster_idx;
5、簇的相關視圖
dba_clusters
all_clusters
user_clusters
dba_clu_columns
user_clu_columns
6、演示相關操做
查看dba_clusters視圖得到所建立的簇
SQL> select cluster_name,tablespace_name,pct_free,pct_used,ini_trans
2 from dba_clusters where owner = 'ROBINSON';
CLUSTER_NAME TABLESPACE_NAME PCT_FREE PCT_USED INI_TRANS
-------------------- ------------------------------ ---------- ---------- ----------
EMP_DEPT_CLUSTER USERS 15 2
查看簇列
SQL> select * from user_clu_columns;
CLUSTER_NAME CLU_COLUMN_NAME TABLE_NAME TAB_COLUMN_NAME
-------------------- -------------------- -------------------- ----------------------------------------
EMP_DEPT_CLUSTER DEPTNO DEPT DEPTNO
EMP_DEPT_CLUSTER DEPTNO EMP DEPTNO
修改簇的相關屬性
SQL> alter cluster emp_dept_cluster
2 pctfree 20
3 initrans 3;
Cluster altered.
SQL> select cluster_name,tablespace_name,pct_free,pct_used,ini_trans
2 from dba_clusters where owner = 'ROBINSON';
CLUSTER_NAME TABLESPACE_NAME PCT_FREE PCT_USED INI_TRANS
-------------------- ------------------------------ ---------- ---------- ----------
EMP_DEPT_CLUSTER USERS 20 3
從dba_segments能夠看到簇產生了簇段,簇索引產生的爲索引段
SQL> select segment_name,tablespace_name,segment_type from dba_segments where owner = 'ROBINSON';
SEGMENT_NAME TABLESPACE_NAME SEGMENT_TYPE
-------------------- ------------------------------ ------------------
EMP_DEPT_CLUSTER USERS CLUSTER
EMP_DEPT_CLUSTER_IDX USERS INDEX
SYS_C005422 USERS INDEX
SYS_C005423 USERS INDEX
刪除簇,簇爲非空時收到錯誤提示
SQL> drop cluster emp_dept_cluster;
drop cluster emp_dept_cluster
*
ERROR at line 1:
ORA-00951: cluster not empty
使用including tables 刪除簇及簇表、簇索引
SQL> drop cluster emp_dept_cluster including tables;
Cluster dropped.
SQL> select segment_name,tablespace_name from dba_segments where owner = 'ROBINSON';
no rows selected
簇由一組共享多個數據塊的多個表組成,它將這些表的相關行一塊兒存儲到相同數據塊中,這樣能夠減小查詢數據所需的磁盤讀取量。建立簇後,用戶能夠在簇中建立表,這些表稱爲簇表。
例若有以下兩個表:student和achievement.。其中,student表存儲學生信息,須要使用SID字段(存儲學生ID);achievement表存儲學生成績信息,也須要使用SID字段。也就是說,student和achievement須要共享學生ID數據塊。
注意:若是用戶在本身的模式中建立簇,則必須具備create cluster權限和unlimited tablespace系統權限;若是想在其餘模式中建立簇,則還必須具備create any cluster系統權限
建立簇,須要使用create cluster語句,例如建立一個名爲stu_ach的簇,以下:
[sql] view plain copy
上面建立簇stu_ach時,指定經過SID字段來對簇中的表進行聚簇存儲,這個SID字段就能夠稱之爲聚簇字段。
注意:size子句用來爲聚簇字段提供指定的數據塊數量。例如,將size設置爲1024,即代表簇中的聚簇字段記錄只能存儲在1024個數據塊中。
建立簇表,須要使用cluster子句指定所使用的簇和簇字段。
例如,在stu_ach簇中建立兩個簇表:student和achievement。以下:
[sql] view plain copy
上例在建立student和achievement表時,使用cluster子句指定它們所使用的簇爲stu_ach,所使用的簇字段爲SID。
提示:將student和achievement兩個表組成一個簇後,在物理上oracle會將這兩個表中每一個學生的學生信息和該學生的全部成績信息存儲到相同的數據塊中。
如今向student表中添加記錄,以下:
[sql] view plain copy
發現還沒法向簇表中添加記錄。
注意:爲了可以向簇表中添加記錄,還須要首先爲簇創建索引。
簇索引與簇表不一樣,它並不存在於簇中,而是與普通索引同樣須要具備獨立的存儲空間。
例如,爲簇stu_ach創建一個簇索引,以下:
[sql] view plain copy
上例爲簇stu_ach創建了一個名爲stu_ach_index的簇索引。建立簇索引後,就能夠向簇表中添加記錄了。
對一個簇的管理主要是修改簇和刪除簇。若是用戶想要管理簇,則必須具備alter any cluster系統權限。
修改一個簇,主要是修改簇的以下屬性值:
1.物理存儲屬性,包括pctfree、pctused、initrans、maxtrans和storage。
2.爲了存儲簇鍵值的全部行所需空間的平均值size。
3.默認的並行度。
1.刪除一個空簇:當一個簇中不包含簇表時,刪除該簇可使用drop cluster cluster_name語句。
2.刪除一個含有簇表的簇:須要使用drop cluster...including tables語句,以下
[sql] view plain copy
另外,若是某個簇含有簇表,而且有外鍵約束,則須要使用drop cluster...including tables cascade constraints語句刪除該簇。以下:
[sql] view plain copy
簇其實就是一組表,由一組共享相同數據塊的多個表組成,將常常一塊兒使用的表組合在一塊兒成簇能夠提升處理效率;在一個簇中的表就叫作簇表。
創建順序是:簇→簇表→簇索引→數據
建立簇的格式
CREATE CLUSTER cluster_name
(column date_type [,column datatype]...)
[PCTUSED 40 | integer] [PCTFREE 10 | integer]
[SIZE integer]
[INITRANS 1 | integer] [MAXTRANS 255 | integer]
[TABLESPACE tablespace]
[STORAGE storage]
SIZE:指定估計平均簇鍵,以及與其相關的行所需的字節數。
一、建立簇
複製代碼 代碼以下:
create cluster my_clu (deptno number )
pctused 60
pctfree 10
size 1024
tablespace users
storage (
initial 128 k
next 128 k
minextents 2
maxextents 20
);
二、建立簇表
複製代碼 代碼以下:
create table t1_dept(
deptno number ,
dname varchar2 ( 20 )
)
cluster my_clu(deptno);
create table t1_emp(
empno number ,
ename varchar2 ( 20 ),
birth_date date ,
deptno number
)
cluster my_clu(deptno);
三、爲簇建立索引
複製代碼 代碼以下:
create index clu_index on cluster my_clu;
注:若不建立簇索引,則在插入數據時報錯:ORA-02032: clustered tables cannot be used before the cluster index is built
管理簇
使用ALTER修改簇屬性(必須擁有ALTER ANY CLUSTER的權限)
一、修改簇屬性
能夠修改的簇屬性包括:
* PCTFREE、PCTUSED、INITRANS、MAXTRANS、STORAGE
* 爲了存儲簇鍵值全部行所需空間的平均值SIZE
* 默認並行度
注:
* 不能修改INITIAL和MINEXTENTS的值
* PCTFREE、PCTUSED、SIZE參數修改後適用於全部數據塊
* INITRANS、MAXTRANS僅適用於之後分配的數據塊
* STORAGE參數修改後僅影響之後分配給簇的盤區
例:
複製代碼 代碼以下:
alter cluster my_clu
pctused 40
二、刪除簇
複製代碼 代碼以下:
drop cluster my_clu; -- 僅適用於刪除空簇
drop cluster my_clu including tables ; -- 刪除簇和簇表
drop cluster my_clu including tables cascade constraints ;--同時刪除外鍵約束
注:簇表能夠像普通表同樣刪除。
三、清空簇
複製代碼 代碼以下:
truncate cluster my_clu;
注:全部在此簇上的表的數據所有被清空
散列聚簇表
在簇表中,Oracle使用存儲在索引中的鍵值來定位表中的行,而在散列聚簇表中,使用了散列函數代替了簇索引,先經過內部函數或者自定義的函數進行散列計算,而後再將計算獲得的碼值用於定位表中的行。建立散列簇須要用到HASHKEYS子句。
一、建立散列簇
複製代碼 代碼以下:
create cluster my_clu_two(empno number(10) )
pctused 70
pctfree 10
tablespace users
hash is empno
hashkeys 150 ;
說明:
* hash is 子句指明瞭進行散列的列,若是列是惟一的標示行,就能夠將列指定爲散列值
* hashkeys 指定和限制散列函數能夠產生的惟一的散列值的數量
二、建立散列表
複製代碼 代碼以下:
create table t2_emp (
empno number ( 10 ),
ename varchar2 ( 20 ),
birth_date date ,
deptno number )
cluster my_clu_two(empno);
注意:* 必須設置數值的精度 * 散列簇不能也不用建立索引 * 散列簇不能ALTER:size、hashkeys、hash is參數不宜用聚簇表的狀況1)若是預料到聚簇中的表會大量修改,聚簇表會對DML的性能產生負面影響 2)很是不適合對單表的全表掃描,由於只能引發對其它表的全表掃描 3)頻繁對錶進行TRUNCATE和加載,由於聚簇中的表是不能TRUNCATE的,只能TRUNCATE簇 4)若是表只是偶爾被鏈接或者它們的公共列常常被修改,則不要聚簇表 5)若是常常從全部有相同聚簇鍵值的表查詢出的結果數據超過一個或兩個Oracle塊,則不要聚簇表 6)若是空間不夠,而且不能爲將要插入的新記錄分配額外的空間,那麼不要使用聚簇