Oracle提供了分區(qū)技術(shù)以支持VLDB(Very Large DataBase)。分區(qū)表通過(guò)對(duì)分區(qū)列的判斷,把分區(qū)列不同的記錄,放到不同的分區(qū)中。分區(qū)完全對(duì)應(yīng)用透明。
專注于為中小企業(yè)提供成都網(wǎng)站建設(shè)、做網(wǎng)站服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)鎮(zhèn)沅免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了數(shù)千家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
Oracle的分區(qū)表可以包括多個(gè)分區(qū),每個(gè)分區(qū)都是一個(gè)獨(dú)立的段(SEGMENT),可以存放到不同的表空間中。查詢時(shí)可以通過(guò)查詢表來(lái)訪問(wèn)各個(gè)分區(qū)中的數(shù)據(jù),也可以通過(guò)在查詢時(shí)直接指定分區(qū)的方法來(lái)進(jìn)行查詢。
分區(qū)提供以下優(yōu)點(diǎn):
由于將數(shù)據(jù)分散到各個(gè)分區(qū)中,減少了數(shù)據(jù)損壞的可能性;
可以對(duì)單獨(dú)的分區(qū)進(jìn)行備份和恢復(fù);
可以將分區(qū)映射到不同的物理磁盤(pán)上,來(lái)分散IO;
提高可管理性、可用性和性能。
Oracle提供了以下幾種分區(qū)類型:
范圍分區(qū)(range);
哈希分區(qū)(hash);
列表分區(qū)(list);
范圍-哈希復(fù)合分區(qū)(range-hash);
范圍-列表復(fù)合分區(qū)(range-list)。
Oracle的普通表沒(méi)有辦法通過(guò)修改屬性的方式直接轉(zhuǎn)化為分區(qū)表,必須通過(guò)重建的方式進(jìn)行轉(zhuǎn)變,下面介紹三種效率比較高的方法,并說(shuō)明它們各自的特點(diǎn)。
方法一:利用原表重建分區(qū)表。
步驟:
SQL CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);
表已創(chuàng)建。
SQL INSERT INTO T SELECT ROWNUM, CREATED FROM DBA_OBJECTS;
已創(chuàng)建6264行。
SQL COMMIT;
提交完成。
SQL CREATE TABLE T_NEW (ID, TIME) PARTITION BY RANGE (TIME)
2 (PARTITION P1 VALUES LESS THAN (TO_DATE('2004-7-1', 'YYYY-MM-DD')),
3 PARTITION P2 VALUES LESS THAN (TO_DATE('2005-1-1', 'YYYY-MM-DD')),
4 PARTITION P3 VALUES LESS THAN (TO_DATE('2005-7-1', 'YYYY-MM-DD')),
5 PARTITION P4 VALUES LESS THAN (MAXVALUE))
6 AS SELECT ID, TIME FROM T;
表已創(chuàng)建。
SQL RENAME T TO T_OLD;
表已重命名。
SQL RENAME T_NEW TO T;
表已重命名。
SQL SELECT COUNT(*) FROM T;
COUNT(*)
----------
6264
SQL SELECT COUNT(*) FROM T PARTITION (P1);
COUNT(*)
----------
SQL SELECT COUNT(*) FROM T PARTITION (P2);
COUNT(*)
----------
6246
SQL SELECT COUNT(*) FROM T PARTITION (P3);
COUNT(*)
----------
18
優(yōu)點(diǎn):方法簡(jiǎn)單易用,由于采用DDL語(yǔ)句,不會(huì)產(chǎn)生UNDO,且只產(chǎn)生少量REDO,效率相對(duì)較高,而且建表完成后數(shù)據(jù)已經(jīng)在分布到各個(gè)分區(qū)中了。
不足:對(duì)于數(shù)據(jù)的一致性方面還需要額外的考慮。由于幾乎沒(méi)有辦法通過(guò)手工鎖定T表的方式保證一致性,在執(zhí)行CREATE TABLE語(yǔ)句和RENAME T_NEW TO T語(yǔ)句直接的修改可能會(huì)丟失,如果要保證一致性,需要在執(zhí)行完語(yǔ)句后對(duì)數(shù)據(jù)進(jìn)行檢查,而這個(gè)代價(jià)是比較大的。另外在執(zhí)行兩個(gè)RENAME語(yǔ)句之間執(zhí)行的對(duì)T的訪問(wèn)會(huì)失敗。
適用于修改不頻繁的表,在閑時(shí)進(jìn)行操作,表的數(shù)據(jù)量不宜太大。
方法二:使用交換分區(qū)的方法。
步驟:
SQL CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);
表已創(chuàng)建。
SQL INSERT INTO T SELECT ROWNUM, CREATED FROM DBA_OBJECTS;
已創(chuàng)建6264行。
SQL COMMIT;
提交完成。
SQL CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME)
2 (PARTITION P1 VALUES LESS THAN (TO_DATE('2005-7-1', 'YYYY-MM-DD')),
3 PARTITION P2 VALUES LESS THAN (MAXVALUE));
表已創(chuàng)建。
SQL ALTER TABLE T_NEW EXCHANGE PARTITION P1 WITH TABLE T;
表已更改。
SQL RENAME T TO T_OLD;
表已重命名。
SQL RENAME T_NEW TO T;
表已重命名。
SQL SELECT COUNT(*) FROM T;
COUNT(*)
----------
6264
優(yōu)點(diǎn):只是對(duì)數(shù)據(jù)字典中分區(qū)和表的定義進(jìn)行了修改,沒(méi)有數(shù)據(jù)的修改或復(fù)制,效率最高。如果對(duì)數(shù)據(jù)在分區(qū)中的分布沒(méi)有進(jìn)一步要求的話,實(shí)現(xiàn)比較簡(jiǎn)單。在執(zhí)行完RENAME操作后,可以檢查T(mén)_OLD中是否存在數(shù)據(jù),如果存在的話,直接將這些數(shù)據(jù)插入到T中,可以保證對(duì)T插入的操作不會(huì)丟失。
不足:仍然存在一致性問(wèn)題,交換分區(qū)之后RENAME T_NEW TO T之前,查詢、更新和刪除會(huì)出現(xiàn)錯(cuò)誤或訪問(wèn)不到數(shù)據(jù)。如果要求數(shù)據(jù)分布到多個(gè)分區(qū)中,則需要進(jìn)行分區(qū)的SPLIT操作,會(huì)增加操作的復(fù)雜度,效率也會(huì)降低。
適用于包含大數(shù)據(jù)量的表轉(zhuǎn)到分區(qū)表中的一個(gè)分區(qū)的操作。應(yīng)盡量在閑時(shí)進(jìn)行操作。
方法三:Oracle9i以上版本,利用在線重定義功能
步驟:
SQL CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);
表已創(chuàng)建。
SQL INSERT INTO T SELECT ROWNUM, CREATED FROM DBA_OBJECTS;
已創(chuàng)建6264行。
SQL COMMIT;
提交完成。
SQL EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE(USER, 'T', DBMS_REDEFINITION.CONS_USE_PK);
PL/SQL 過(guò)程已成功完成。
SQL CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME)
2 (PARTITION P1 VALUES LESS THAN (TO_DATE('2004-7-1', 'YYYY-MM-DD')),
3 PARTITION P2 VALUES LESS THAN (TO_DATE('2005-1-1', 'YYYY-MM-DD')),
4 PARTITION P3 VALUES LESS THAN (TO_DATE('2005-7-1', 'YYYY-MM-DD')),
5 PARTITION P4 VALUES LESS THAN (MAXVALUE));
表已創(chuàng)建。
SQL EXEC DBMS_REDEFINITION.START_REDEF_TABLE(USER, 'T', 'T_NEW', -
'ID ID, TIME TIME', DBMS_REDEFINITION.CONS_USE_PK);
PL/SQL 過(guò)程已成功完成。
SQL EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE('YANGTK', 'T', 'T_NEW');
PL/SQL 過(guò)程已成功完成。
SQL SELECT COUNT(*) FROM T;
COUNT(*)
----------
6264
SQL SELECT COUNT(*) FROM T PARTITION (P2);
COUNT(*)
----------
6246
SQL SELECT COUNT(*) FROM T PARTITION (P3);
COUNT(*)
----------
18
優(yōu)點(diǎn):保證數(shù)據(jù)的一致性,在大部分時(shí)間內(nèi),表T都可以正常進(jìn)行DML操作。只在切換的瞬間鎖表,具有很高的可用性。這種方法具有很強(qiáng)的靈活性,對(duì)各種不同的需要都能滿足。而且,可以在切換前進(jìn)行相應(yīng)的授權(quán)并建立各種約束,可以做到切換完成后不再需要任何額外的管理操作。
不足:實(shí)現(xiàn)上比上面兩種略顯復(fù)雜。
適用于各種情況。
這里只給出了在線重定義表的一個(gè)最簡(jiǎn)單的例子,詳細(xì)的描述和例子可以參考下面兩篇文章。
Oracle的在線重定義表功能:
Oracle的在線重定義表功能(二):
索引也可以進(jìn)行分區(qū),分區(qū)索引有兩種類型:global和local。對(duì)于local索引,每一個(gè)表分區(qū)對(duì)應(yīng)一個(gè)索引分區(qū),當(dāng)表的分區(qū)發(fā)生變化時(shí),索引的維護(hù)由Oracle自動(dòng)進(jìn)行。對(duì)于global索引,可以選擇是否分區(qū),而且索引的分區(qū)可以不與表分區(qū)相對(duì)應(yīng)。當(dāng)對(duì)分區(qū)進(jìn)行維護(hù)操作時(shí),通常會(huì)導(dǎo)致全局索引的INVALDED,必須在執(zhí)行完操作后REBUILD。Oracle9i提供了UPDATE GLOBAL INDEXES語(yǔ)句,可以使在進(jìn)行分區(qū)維護(hù)的同時(shí)重建全局索引。
全局索引可以包含多個(gè)分區(qū)的值 局部索引比全局索引容易管理,而全局索引比較快
注意:不能為散列分區(qū) 或者 子分區(qū)創(chuàng)建全局索引
Oracle的分區(qū)功能十分強(qiáng)大。不過(guò)用起來(lái)發(fā)現(xiàn)有兩點(diǎn)不大方便:
第一是已經(jīng)存在的表沒(méi)有方法可以直接轉(zhuǎn)化為分區(qū)表。不過(guò)Oracle提供了在線重定義表的功能,可以通過(guò)這種方式來(lái)完成普通表到分區(qū)表的轉(zhuǎn)化??梢詤⒖歼@個(gè)例子:
第二點(diǎn)是如果采用了local分區(qū)索引,那么在增加表分區(qū)的時(shí)候,索引分區(qū)的表空間是不可控制的。如果希望將表和索引的分區(qū)分開(kāi)到不同的表空間且不同索引分區(qū)也分散到不同的表空間中,那么只能在增加分區(qū)后,對(duì)新增的分區(qū)索引單獨(dú)rebuild。
Oracle最大允許存在多少個(gè)分區(qū)呢?
我們可以從Oracle的Concepts手冊(cè)上找到這個(gè)信息,對(duì)于Oracle9iR2:
Tables can be partitioned into up to 64,000 separate partitions.
對(duì)于Oracle10gR2,Oracle增強(qiáng)了分區(qū)特性:
Tables can be partitioned into up to 1024K-1 separate partitions.
關(guān)于何時(shí)應(yīng)該進(jìn)行分區(qū),Oracle有如下建議:
■ Tables greater than 2GB should always be considered for partitioning.
■ Tables containing historical data, in which new data is added into the newest partition. A typical example is a historical table where only the current month's data is updatable and the other 11 months are read only.
這些信息是在網(wǎng)上查到的,測(cè)試了下確實(shí)可以用。
默認(rèn)情況下,oracle的分區(qū)表對(duì)于分區(qū)字段是不允許進(jìn)行update操作的,如果有對(duì)分區(qū)字段行進(jìn)update,就會(huì)報(bào)錯(cuò)——ORA-14402: 更新分區(qū)關(guān)鍵字列將導(dǎo)致分區(qū)的更改。但是可以通過(guò)打開(kāi)表的row movement屬性來(lái)允許對(duì)分區(qū)字段的update操作。
例:創(chuàng)建分區(qū)表test_part進(jìn)行實(shí)驗(yàn)
create table TEST_PART
(
A1 NUMBERnot null,
A2 DATE not null,
A3 VARCHAR2(6) not null,
A4 DATE not null,
A5 NUMBER not null,
)
partition by range (A1)
(
partition P1 values less than (1000),
partition P2 values less than (2000),
partition P3 values less than (3000),
partition P4 values less than (4000),
partition P5 values less than (5000),
partition P6 values less than (MAXVALUE)
);
插入如下的數(shù)據(jù)
SQL select * from test_part;
A1 A2 A3 A4 A5
---------- ----------- ------ ----------- ----------
123 2006-06-30 123456 2006-06-30 123
456 2006-06-30 asdfgh 2006-06-30 456
1 2006-06-30 234123 2006-06-30 1
2 2006-06-30 234234 2006-06-30 2
1234 2006-06-30 456789 2006-06-30 1234
1111 2006-06-30 ewrqwe 2006-06-30 1111
2222 2006-06-30 fdafda 2006-06-30 2222
3333 2006-06-30 342342 2006-06-30 3333
5678 2006-06-30 qwerty 2006-06-30 5678
9 rows selected
分區(qū)P1、P2的數(shù)據(jù)分別為:
SQL select rowid,t.* from test_part partition(p1) t;
ROWID A1 A2 A3 A4 A5
------------------ ---------- ----------- ------ ----------- ----------
AAAGLoAAGAAAtsEAAB 456 2006-06-30 asdfgh 2006-06-30 456
AAAGLoAAGAAAtsEAAC 1 2006-06-30 234123 2006-06-30 1
AAAGLoAAGAAAtsEAAD 2 2006-06-30 234234 2006-06-30 2
AAAGLoAAGAAAtsEAAE 123 2006-06-30 123456 2006-06-30 123
SQL select rowid,t.* from test_part partition(p2) t;
ROWID A1 A2 A3 A4 A5
------------------ ---------- ----------- ------ ----------- ----------
AAAGLwAAGAAA+8MAAC 1234 2006-06-30 456789 2006-06-30 1234
AAAGLwAAGAAA+8MAAD 1111 2006-06-30 ewrqwe 2006-06-30 1111
直接update提示錯(cuò)誤
SQL update test_part set a1=1123 where a1=123;
update test_part set a1=1123 where a1=123
ORA-14402: 更新分區(qū)關(guān)鍵字列將導(dǎo)致分區(qū)的更改
打開(kāi)row movement屬性
SQL alter table test_part enable row movement;
Table altered
再次執(zhí)行update操作
SQL update test_part set a1=1123 where a1=123;
1 row updated
執(zhí)行是成功的并遷移到分區(qū)P2上了,且這時(shí)候rowid也發(fā)生了變化
SQL select rowid,t.* from test_part partition(p2) t;
ROWID A1 A2 A3 A4 A5
------------------ ---------- ----------- ------ ----------- ----------
AAAGLwAAGAAA+8MAAC 1234 2006-06-30 456789 2006-06-30 1234
AAAGLwAAGAAA+8MAAD 1111 2006-06-30 ewrqwe 2006-06-30 1111
AAAGLwAAGAAA+8PAAB 1123 2006-06-30 123456 2006-06-30 123
SQL
enable row movement可以允許數(shù)據(jù)段的壓縮、update分區(qū)字段的數(shù)據(jù)(跨分區(qū)的)
1、創(chuàng)建語(yǔ)句
create table p(id number)
partition by range(id)
(partition p1 values less than(100) tablespace t1,
partition p2 values less than(200) tablespace t2,
partition p3 values less than(300) tablespace t3);
2、添加分區(qū)
alter table p add partition p4 values less than (400) tablespace t4;
3、清除分區(qū)數(shù)據(jù)
alter table p trunc partition p1;
4、刪除分區(qū)
alter table p drop partition p1;
一.表分區(qū)策略
1.識(shí)別大表
采用ANALYZE TABLE語(yǔ)句進(jìn)行分析,然后查詢數(shù)據(jù)字典獲得相應(yīng)的數(shù)據(jù)量。
2.大表如何分區(qū)
可根據(jù)月份,季度以及年份等進(jìn)行分區(qū);
3.分區(qū)的表空間規(guī)劃
要對(duì)每個(gè)表空間的大小進(jìn)行估計(jì)
二.創(chuàng)建表分區(qū)
a.創(chuàng)建范圍分區(qū)的關(guān)鍵字是'RANGE'
1.范圍分區(qū)
create table ware_retail_part --創(chuàng)建一個(gè)描述商品零售的數(shù)據(jù)表
(
id integer primary key,--銷售編號(hào)
retail_date date,--銷售日期
ware_name varchar2(50)--商品名稱
)
partition by range(retail_date)
(
--2011年第一個(gè)季度為part_01分區(qū)
partition par_01 values less than(to_date('2011-04-01','yyyy-mm-dd')) tablespace TEMP01,
--2011年第二個(gè)季度為part_02分區(qū)
partition par_02 values less than(to_date('2011-07-01','yyyy-mm-dd')) tablespace TEMP01,
--2011年第三個(gè)季度為part_03分區(qū)
partition par_03 values less than(to_date('2011-10-01','yyyy-mm-dd')) tablespace TEMP01,
--2011年第四個(gè)季度為part_04分區(qū)
partition par_04 values less than(to_date('2012-01-01','yyyy-mm-dd')) tablespace TEMP01
);
2.創(chuàng)建散列分區(qū)
3.組合分區(qū):
4.interval 分區(qū)
三.創(chuàng)建索引分區(qū)
索引分區(qū)分為本地索引分區(qū)和全局索引分區(qū),全局索引不反應(yīng)基礎(chǔ)表的結(jié)構(gòu),要分區(qū)只能進(jìn)行范圍分區(qū)。
創(chuàng)建索引分區(qū)要參照表分區(qū)
四.分區(qū)技術(shù)簡(jiǎn)介
優(yōu)點(diǎn):
1.減少維護(hù)工作量
2.增強(qiáng)數(shù)據(jù)的可用性
3.均衡I/O,提升性能
4.提高查詢速度
5.分區(qū)對(duì)用戶保持透明,用戶感覺(jué)不到分區(qū)的存在。
五,管理表分區(qū)
1.添加表分區(qū)
ALTER TABLE...ALTER PARATITION
2.合并表分區(qū)
3.刪除分區(qū)
ALTER TABLE...DROP PARTITION
刪除分區(qū)時(shí),里面的數(shù)據(jù)也會(huì)被刪除。
-創(chuàng)建表和分區(qū)
create table sales--創(chuàng)建一個(gè)銷售記錄表
(
id number primary key,--記錄編號(hào)
goodsname varchar2(10),--商品名
saledate date--銷售日期
)
partition by range(saledate)--按照日期分區(qū)
(
--第一季度數(shù)據(jù)
partition part_sea1 values less than(to_date('2011-04-01','yyyy-mm-dd')) tablespace tbsp_1,
--第二季度數(shù)據(jù)
partition part_sea2 values less than(to_date('2011-07-01','yyyy-mm-dd')) tablespace tbsp_2,
--第三季度數(shù)據(jù)
partition part_sea3 values less than(to_date('2011-10-01','yyyy-mm-dd')) tablespace tbsp_1,
--第四季度數(shù)據(jù)
partition part_sea4 values less than(to_date('2012-01-01','yyyy-mm-dd')) tablespace tbsp_2
);
--創(chuàng)建局部索引
create index index_3_4 on sales(saledate)
local(
partition part_seal tablespace tbsp_1,
partition part_sea2 tablespace tbsp_2,
partition part_sea3 tablespace tbsp_1,
partition part_sea4 tablespace tbsp_2
);
--并入分區(qū)
alter table sales merge partitions part_sea3,part_sea4 into partition part_sea4;
--重建局部索引
alter table sales modify partition part_sea4 rebuild unusable local indexes;
六.管理索引分區(qū)
刪除索引:DROP PARTITION
重建分區(qū):REBUILT PARTITION
更名索引分區(qū):RENAME PARTITION
分割索引分區(qū):SPLIT PARTITION