如何將Oracle資料庫的普通表轉換成分割槽表

2021-08-31 20:18:31 字數 4812 閱讀 5541

方法一:利用原表重建分割槽表

步驟:

sql> create table t (id number primary key, time date);

表已建立。

sql> insert into t select rownum, created from dba_objects;

已建立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;

表已建立。

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(*)

----------

0sql> select count(*) from t partition (p2);

count(*)

----------

6246

sql> select count(*) from t partition (p3);

count(*)

----------

18優點:

方法簡單易用,由於採用ddl語句,不會產生undo,且只產生少量redo,效率相對較高,而且建表完成後資料已經在分布到各個分割槽中了。

不足:

對於資料的一致性方面還需要額外的考慮。由於幾乎沒有辦法通過手工鎖定t表的方式保證一致性,在執行create table語句和rename t_new to t語句直接的修改可能會丟失,如果要保證一致性,需要在執行完語句後對資料進行檢查,而這個代價是比較大的。另外在執行兩個rename語句之間執行的對 t的訪問會失敗。

適用於修改不頻繁的表,在閒時進行操作,表的資料量不宜太大。

方法二:使用交換分割槽的方法

步驟:

sql> create table t (id number primary key, time date);

表已建立。

sql> insert into t select rownum, created from dba_objects;

已建立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));

表已建立。

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

優點:

只是對資料字典中分割槽和表的定義進行了修改,沒有資料的修改或複製,效率最高。如果對資料在分割槽中的分布沒有進一步要求的話,實現比較簡單。在執行 完rename操作後,可以檢查t_old中是否存在資料,如果存在的話,直接將這些資料插入到t中,可以保證對t插入的操作不會丟失。

不足

仍然存在一致性問題,交換分割槽之後rename t_new to t之前,查詢、更新和刪除會出現錯誤或訪問不到資料。如果要求資料分布到多個分割槽中,則需要進行分割槽的split操作,會增加操作的複雜度,效率也會降低。

適用於包含大資料量的表轉到分割槽表中的乙個分割槽的操作。應盡量在閒時進行操作。

步驟:

sql> create table t (id number primary key, time date);

表已建立。

sql> insert into t select rownum, created from dba_objects;

已建立6264行。

sql> commit;

提交完成。

sql> exec dbms_redefinition.can_redef_table(user』, 't', dbms_redefinition.cons_use_pk);

pl/sql 過程已成功完成。

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));

表已建立。

sql> exec dbms_redefinition.start_redef_table(『user』, 't', 't_new', -

> 'id id, time time', dbms_redefinition.cons_use_pk);

可以改為:

sql> exec dbms_redefinition.start_redef_table(『user』, 't', 't_new')

pl/sql 過程已成功完成。

sql> exec dbms_redefinition.sync_interim_table(『user』, 't', 't_new')

現在,將中間表與原始表同步。(僅當要對錶 t 進行更新時才需要執行該操作。)

sql> exec dbms_redefinition.finish_redef_table(user』, 't', 't_new');

pl/sql 過程已成功完成。

如果重組織失敗,那麼你就必須採取特殊的步驟來讓它重新開始。由於重定義過程需要建立**的快照,因此為了重新開始這一過程,你必須呼叫dbms_redefinition.abort_redef_table來釋放快照。

dbms_redefinition.abort_redef_table過程有三個引數,即使用者(schema)、原始**(original table name)名稱以及持有**名稱(holding table name)。它「出棧」並允許你開始重組織**。

sql> select count(*) from t;

sql> select count(*) from t partition (p2);

sql> select count(*) from t partition (p3);

需要說明的是完成後,原表和中間表的結構也同時進行了交換,並且中間表裡面有原表的資料備份。

優點

保證資料的一致性,在大部分時間內,表t都可以正常進行dml操作。只在切換的瞬間鎖表,具有很高的可用性。這種方法具有很強的靈活性,對各種不同的需要都能滿足。而且,可以在切換前進行相應的授權並建立各種約束,可以做到切換完成後不再需要任何額外的管理操作。

不足:實現上比上面兩種略顯複雜,適用於各種情況。

你必須有足以維護兩份**拷貝的空間。

你不能更改主鍵欄。

**必須有主鍵。

必須在同乙個大綱中進行**重定義。

在重定義操作完成之前,你不能對新加欄加以not null約束。

**不能包含long、bfile以及使用者型別(udt)。

不能重定義鍊錶(clustered tables)。

不能在sys和system大綱中重定義**。

不能用具體化檢視日誌(materialized view logs)來重定義**;不能重定義含有具體化檢視的**。

不能在重定義過程中進行橫向分集(horizontal subsetting)。

上文中介紹的三種將oracle資料庫的普通表轉換成分割槽表的方法,每種方法之後也都總結出了每一種方法的優缺點,所以每一種方法都是各有優缺點,並不是完美的,所以在選擇選用哪一種方法時,要根據實際情況,綜合考慮最終確定選擇那一種。

如何將資料庫水平切分

在大中型專案中,在資料庫設計的時候,考慮到資料庫最大承受資料量,通常會把資料庫或者資料表水平切分,以降低單個庫,單個表的壓力。這裡介紹兩個專案中常用的資料表切分方法。當然這些方法都是在程式中 使用一定的技巧來路由到具體的表的。首先我們要確認根據什麼來水平切分?在我們的系統 sns 中,使用者的uid...

如何將資料庫水平切分

在大中型專案中,在資料庫設計的時候,考慮到資料庫最大承受資料量,通常會把資料庫或者資料表水平切分,以降低單個庫,單個表的壓力。這裡介紹兩個專案中常用的資料表切分方法。當然這些方法都是在程式中 使用一定的技巧來路由到具體的表的。首先我們要確認根據什麼來水平切分?在我們的系統 sns 中,使用者的uid...

如何將excel匯入資料庫中

1 開啟企業管理器,開啟要匯入資料的資料庫,在表上按右鍵,所有任務 匯入資料,彈出dts匯入 匯出嚮導,按 下一步 2 選擇資料來源 microsoft excel 97 2000,檔名 選擇要匯入的xls檔案,按 下一步 3 選擇目的 用於sql server 的microsoft ole db提...