上一篇講了很多關於分區的技術,但是怎麼做分區呢,怎麼管理分區呢,還需要細細道來。
對於交易流水來說,不管數據量有多大,它一定是按天進來的,這個看實際的分區粒度,分區不是越大越好,也不是越小越高,主要看每個分區的實際數據量的大小,如果一天的數據都有上百萬,而查詢要求只要看當天的,而且查詢比較頻繁,那按天做分區,創建7個分區,超過一定天數的,就可以把這個分區的數據移走,以減輕系統負擔,對於我現在的情況來說,我一個月的數據量,還是可以處理的,我就建12個分區,以月份爲分區鍵。
還有一個問題就是,如果我在系統建設之初,如果想到這些就好了直接在建表腳本里創建分區就好了,數據庫可以自己管理數據,它知道應該把新加進來的數據往那裏放,可是,最初沒有規劃,現在數據量已經非常大了,那我要怎麼辦呢?
如果有一表先是沒有分區,像這個樣子:
CREATE TABLE PROBLEM_TICKETS
(
PROBLEM_ID NUMBER(7) NOT NULL PRIMARY KEY,
tran_date date
)
我現在希望把它建成一個分區表,像下面一樣
CREATE TABLE PROBLEM_TICKETS
(
PROBLEM_ID NUMBER(7) NOT NULL PRIMARY KEY,
tran_date date ,
par VARCHAR2(2) --分區段,記交易月份
)
PARTITION BY LIST (par)
(
PARTITION P_01 VALUES ('01') TABLESPACE PROB_TS01,
PARTITION P_02 VALUES ('02') TABLESPACE PROB_TS02,
PARTITION P_03 VALUES ('03') TABLESPACE PROB_TS03,
PARTITION P_04 VALUES ('04') TABLESPACE PROB_TS04,
PARTITION P_05 VALUES ('05') TABLESPACE PROB_TS05,
PARTITION P_06 VALUES ('06') TABLESPACE PROB_TS06,
PARTITION P_07 VALUES ('07') TABLESPACE PROB_TS07,
PARTITION P_08 VALUES ('08') TABLESPACE PROB_TS08,
PARTITION P_09 VALUES ('09') TABLESPACE PROB_TS09,
PARTITION P_10 VALUES ('10') TABLESPACE PROB_TS10,
PARTITION P_11 VALUES ('11') TABLESPACE PROB_TS11,
PARTITION P_12 VALUES ('12') TABLESPACE PROB_TS12
);
大家一定注意到了,爲什麼我的新表加了一個字段par,這是我用於建分區的鍵,沒有辦法,我的表是按交易日期來做的,而分區的KEY又不可以通過函數來做,那隻好加一個字段,用於讓ORACLE知道這些數據應該放到那裏去。
然後執行下下update PROBLEM_TICKETS set par=to_char(tran_date,'MM');
這樣數據有有KEY了,可以往下做了。
然後建一張新表,一張帶分區的表,這張表做數據轉換,即先把舊錶的數據放過來,放過來的時候,數據就被分區了,然後再從這個表,把數據拿回去,就可以了。
CREATE TABLE PROBLEM_TICKETS_NEW
(
PROBLEM_ID NUMBER(7) NOT NULL PRIMARY KEY,
tran_date date ,
par VARCHAR2(2) --分區段,記交易月份
)
PARTITION BY LIST (par)
(
PARTITION P_01 VALUES ('01') TABLESPACE PROB_TS01,
PARTITION P_02 VALUES ('02') TABLESPACE PROB_TS02,
PARTITION P_03 VALUES ('03') TABLESPACE PROB_TS03,
PARTITION P_04 VALUES ('04') TABLESPACE PROB_TS04,
PARTITION P_05 VALUES ('05') TABLESPACE PROB_TS05,
PARTITION P_06 VALUES ('06') TABLESPACE PROB_TS06,
PARTITION P_07 VALUES ('07') TABLESPACE PROB_TS07,
PARTITION P_08 VALUES ('08') TABLESPACE PROB_TS08,
PARTITION P_09 VALUES ('09') TABLESPACE PROB_TS09,
PARTITION P_10 VALUES ('10') TABLESPACE PROB_TS10,
PARTITION P_11 VALUES ('11') TABLESPACE PROB_TS11,
PARTITION P_12 VALUES ('12') TABLESPACE PROB_TS12
);
修改一下下面的過程塊,把引號裏的'SCHEMA'改成實際的用戶名,'OLD_TABLE'表名改成實際的源表名,'NEW_TABLE'改成是中間表名,執行下面的過程。
declare
begin
--1.檢查該表OLD_TABLE表不滿足重定義的條件
DBMS_REDEFINITION.CAN_REDEF_TABLE('SCHEMA','OLD_TABLE');
--2.創建修改後的新表NEW_TABLE 這一步就是上面建臨時表的過程
--在用一個方案中建立一個空的中間表,根據重定義後你期望得到的結構建立中間表。比如:採用分區表,增加了COLUMN等
--3.如果映射方法沒有提供,則認爲所有包括在中間表中的列用於表的重定義。如果給出了映射方法,則只考慮映射方法中給出的列。如果----沒有給出重定義方法,則認爲使用主鍵方式
DBMS_REDEFINITION.START_REDEF_TABLE('SCHEMA','OLD_TABLE','NEW_TABLE');
--4.進行一次數據同步(其實是一次物化視圖的刷新)
dbms_redefinition.SYNC_INTERIM_TABLE('SCHEMA','OLD_TABLE','NEW_TABLE');
--5.執行完FINISH_REDEF_TABLE()過程後,原始表重定義後具有了中間表的屬性、索引、約束、授權和觸發器。中間表上disabled
--的約束在原始表上處於enabled狀態
DBMS_REDEFINITION.FINISH_REDEF_TABLE('SCHEMA','OLD_TABLE','NEW_TABLE');
end;
執行完了以後,查看一下源表,看建表腳本是不是已經帶了分區了,如果有的話,那恭喜你,分區成功了。
至於分區的好不好呢,你可以通過下面的SQL語句,查看一下,你每個分區的多少數據量
select * FROM USER_TAB_PARTITIONS ORDER BY TABLE_NAME,PARTITION_NAME;
正常的情況下呢,每個分區都有數據,並且數據分佈均勻的話呢,算是分區策略比較成功,如果有些分區就沒有用呢,那就有問題了,具體問題具體對待。分區是需要管理的,分區並不是一勞永逸的解決了問題,因爲以我現在的分區爲例,如果數據跨年了,那數據就會重複使用分區,那麼就要定時去備份清理分區的數據。具體操作參考上一篇《關於ORACLE分區表的概念及操作》。