oracle 操作表空間和分區表

前提:

   查詢分區:Select *From user_extents WHERE partition_name='分區名';

1)創建表空間

create tablespace HRPM0

datafile '/oradata/misdb/HRPM0.DBF' size 5m autoextend on next 10m maxsize unlimited

2)刪除表空間(同時把數據文件也刪除)

DROP TABLESPACE data01 INCLUDING CONTENTS AND DATAFILES;

   如果不想刪除數據文件:

           Drop tablespace tablespace_name;

3) 修改表空間大小

alter database datafile '/path/NADDate05.dbf' resize 100M

4)添加數據文件(在建立表空間時,若是約束了表空間的大小,那麼一段時間後,這個表空間就會被裝滿,無法再添加其他對象。則需要給表空間添加數據文件):

Alter tablespace tablespace_name add datafile’ '/path/NADDate06.dbf’ size 100M;

4) 備註:

4.1).--.禁止undo tablespace自動增長

alter database datafile 'full_path\undotbs01.dbf' autoextend off;

4.2).-- 創建一個新的小空間的undo tablespace

create undo tablespace undotBS2 datafile 'full_path\UNDOTBS02.DBF' size 100m;

4.3).-- 設置新的表空間爲系統undo_tablespace

alter system set undo_tablespace=undotBS2;

4.4).-- Drop 舊的表空間

drop tablespace undotbs1 including contents;

4.5).--查看所有表空間的情況

select * from dba_tablespaces

5)查到一個最好用的表:dict

5.1)select *from dict where table_name like '%PART%'

5.2)ALL_TAB_PARTITIONS:可以查出表所對應的分區內容;

5.3)dab_tab_partitons :與上2);

5.4)dba_ind_partitons:查詢分區的索引;

5.5)子分區也是一樣的(dba_tab_subpartitons,dba_ind_partitons)

一、使用分區的優點:

    1、增強可用性:如果表的某個分區出現故障,表在其他分區的數據仍然可用;

    2、維護方便:如果表的某個分區出現故障,需要修復數據,只修復該分區即可;

    3、均衡I/O:可以把不同的分區映射到磁盤以平衡I/O,改善整個系統性能;

4、改善查詢性能:對分區對象的查詢可以僅搜索自己關心的分區,提高檢索速度。

二、Oracle數據庫提供對錶或索引的分區方法有幾種(收集到四種):

        1、範圍分區

        2、列表分區

        3Hash分區(散列分區)

        4、複合分區

三、詳描述分區實例:

    1)下面將以實例的方式分別對這三種分區方法來說明分區表的使用。爲了測試方便,我們先建三個表空間。

create tablespace dinya_space01 datafile 'C:\表空間\dinya01.dbf' size 5M

create tablespace dinya_space02 datafile 'C:\表空間\dinya02.dbf'SIZE 5M

create tablespace dinya_space03 datafile 'C:\表空間\dinya03.dbf' SIZE 5M;

select * from user_tablespaces

1.1)範圍分區

    範圍分區就是對數據表中的某個值的範圍進行分區,根據某個值的範圍,決定將該數據存儲在哪個分區上。如根據序號分區,根據業務記錄的創建日期進行分區等。

    需求描述:有一個物料交易表,表名:material_transactions。該表將來可能有千萬級的數據記錄數。要求在建該表的時候使用分區表。這時候我們可以使用序號分區三個區,每個區中預計存儲三千萬的數據,也可以使用日期分區,如每五年的數據存儲在一個分區上。

根據交易記錄的序號分區建表:----爲了測試需要做以下修改;

create table dinya_test

   (

        transaction_id number primary key,

        item_id number(8) not null,

        item_description varchar2(300),

        transaction_date date not null

    )

    partition by range (transaction_id)

    (

       partition part_01 values less than(2) tablespace dinya_space01,-----2條以下的交易在此分區上:part_01

      partition part_02 values less than(3) tablespace dinya_space02,-----等於+大於2而小於3的交易在此分區:part_02

      partition part_03 values less than(maxvalue) tablespace dinya_space03----大於3的交易在此分區:part_03

根據交易日期分區建表:

SQL> create table dinya_test

   (

        transaction_id number primary key,

        item_id number(8) not null,

       item_description varchar2(300),

       transaction_date date not null  

 )

    partition by range (transaction_date)

    (

   partition part_01 values less than(to_date('2006-01-01','yyyy-mm-dd')) tablespace dinya_space01,

   partition part_02 values less than(to_date('2010-01-01','yyyy-mm-dd')) tablespace dinya_space02,

 partition part_03 values less than(maxvalue) tablespace dinya_space03

 );

這樣我們就分別建了以交易序號和交易日期來分區的分區表。每次插入數據的時候,系統將根據指定的字段的值來自動將記錄存儲到制定的分區(表空間)中。

當然,我們還可以根據需求,使用兩個字段的範圍分佈來分區,如partition by range ( transaction_id ,transaction_date),分區條件中的值也做相應的改變,請讀者自行測試。

1.2) 範圍分區創建成功之後的相關操作測試;

 a)向表添加測試數據:

insert into dinya_test values(1,12,'BOOKS',sysdate);

insert into dinya_test values(2,12, 'BOOKS',sysdate+30);

insert into dinya_test values(3,12, 'BOOKS',to_date('2006-05-30','yyyy-mm-dd'));

insert into dinya_test values(4,12, 'BOOKS',to_date('2007-06-23','yyyy-mm-dd'));

insert into dinya_test values(5,12, 'BOOKS',to_date('2011-02-26','yyyy-mm-dd'));

insert into dinya_test values(6,12, 'BOOKS',to_date('2011-04-30','yyyy-mm-dd'));

b)查詢

   b.1)如果查詢全表數據

select * from dinya_test;

select * from dinya_test partition(part_01);

select * from dinya_test partition(part_02);

select * from dinya_test partition(part_03);

update dinya_test partition(part_01) t set t.item_description='DESK' where t.transaction_id=1;

select * from dinya_test partition(part_01);BOOKS->DESK(發生變化)

               

select * from dinya_test(此結果就不用查看了,肯定變了);

---刪除part_03分區中transaction_id=4的記錄:

delete from dinya_test partition(part_03) t where t.transaction_id=4;

select * from dinya_test partition(part_03)


c)索引的創建:

   c.1)局部索引的創建:

create index dinya_idx_t on dinya_test(item_id)

 local

   (

     partition idx_1 tablespace dinya_space01,---分區名爲:idx_1

     partition idx_2 tablespace dinya_space02, ---分區名爲:idx_2

     partition idx_3 tablespace dinya_space03---分區名爲:idx_3

 );

注:

select *from ALL_TAB_PARTITIONS where table_name ='DINYA_TEST'

    select *From dba_ind_partitions where partition_name='IDX_1'

 

   c.2)全局索引的創建:

全局索引建立時global 子句允許指定索引的範圍值,這個範圍值爲索引字段的範圍值:

create index dinya_idx_t on dinya_test(item_id)

   global partition by range(item_id)

 (

     partition idx_1 values less than (1000tablespace dinya_space01,

     partition idx_2 values less than (10000tablespace dinya_space02,

     partition idx_3 values less than (maxvaluetablespace dinya_space03

 );----PL/SQL末測試[參照以上local]

整個表創建索引:

   Create index dinya_idx_t on dinya_test(item_id);

備註: select *from all_indexes(dba_indexesall_ind_columns user_ind_columns  dba_ind_columns)

1.3) Hash分區(散列分區)

    散列分區爲通過指定分區編號來均勻分佈數據的一種分區類型,因爲通過在I/O設備上進行散列分區,使得這些分區大小一致。如將物料交易表的數據根據交易ID散列地存放在指定的三個表空間中:

create table dinya_test

    (

       transaction_id number primary key,

        item_id number(8) not null,

        item_description varchar2(300),

        transaction_date date

   )

   partition by hash(transaction_id)

   (

       partition part_01 tablespace dinya_space01,

       partition part_02 tablespace dinya_space02,

       partition part_03 tablespace dinya_space03

 );

建表成功,此時插入數據,系統將按transaction_id將記錄散列地插入三個分區中,這裏也就是三個不同的表空間中。

 

1.4) 列表分區:該分區的特點是某列的值只有幾個,基於這樣的特點我們可以採用列表分區。

示例1

CREATE TABLE PROBLEM_TICKETS

(

PROBLEM_ID NUMBER(7) NOT NULL PRIMARY KEY,

DESCRIPTION VARCHAR2(2000),

CUSTOMER_ID NUMBER(7) NOT NULL,

DATE_ENTERED DATE NOT NULL,

STATUS VARCHAR2(20)

)

PARTITION BY LIST (STATUS)

(

PARTITION PROB_ACTIVE VALUES ('ACTIVE') TABLESPACE PROB_TS01,

                  

PARTITION PROB_INACTIVE VALUES ('INACTIVE') TABLESPACE PROB_TS02

)     

備註:activeinactive是列status的值!謹記與rangehash分區的區別;

1.4.1)測試如下:

   insert into PROBLEM_TICKETS values(1,'BOOKS',1,sysdate,'ACTIVE');

insert into PROBLEM_TICKETS values(2,'son',2,sysdate+30,'INACTIVE');

insert into PROBLEM_TICKETS values(3,'son',3,to_date('2006-05-30','yyyy-mm-dd'),'INACTIVE');

insert into PROBLEM_TICKETS values(4,'BOOKS',4,to_date('2007-06-23','yyyy-mm-dd'),'INACTIVE');

insert into PROBLEM_TICKETS values(5,'old',5,to_date('2011-02-26','yyyy-mm-dd'),'ACTIVE');

insert intoPROBLEM_TICKETSvalues(6,'test',6,to_date('2011-04-30','yyyy-mm-dd'),'INACTIVE');

select * from PROBLEM_TICKETS

 

1.4.2)

   select * from PROBLEM_TICKETS partition(PROB_ACTIVE)

1.4.2)

   select * from PROBLEM_TICKETS partition(PROB_INACTIVE)

 

 在測試中遇到這樣的情況。如果表創建了分區,如果要刪除數據文件(表空間文件),則要先刪除分區,然後才能刪除數據文件(但是在刪除數據文件時,必須要保留一個分區才能最終刪除數據文件>表空間文件,)

當然,也可以直接就刪除表也行,剛所有的全刪除,但是表空間文件還在!

 

1.5) 複合分區

 有時候我們需要根據範圍分區後,每個分區內的數據再散列地分佈在幾個表空間中,這樣我們就要使用複合分區。複合分區是先使用範圍分區,然後在每個分區內再使用散列分區的一種分區方法,如將物料交易的記錄按時間分區,然後每個分區中的數據分三個子分區,將數據散列地存儲在三個指定的表空間中:

create table dinya_test

    (

        transaction_id number primary key,

        item_id number(8not null,

       item_description varchar2(300),

      transaction_date date

    )

   partition by range(transaction_date)subpartition by hash(transaction_id)

       subpartitions 3 store in (dinya_space07,dinya_space08,dinya_space09)

 (

      partition part_07 values less than(to_date('2006-01-01','yyyy-mm-dd')),

      partition part_08 values less than(to_date('2010-01-01','yyyy-mm-dd')),

      partition part_09 values less than(maxvalue)

 );

 ---測試如下:

   select *From user_tab_partitions where table_name=upper('dinya_test')

            selec *From user_tab_subpartitions where table_name=upper('dinya_test')

   插入如下數據:

 insert into dinya_test values(1,12,'BOOKS',sysdate);

insert into dinya_test values(2,12'BOOKS',sysdate+30);

insert into dinya_test values(3,12'BOOKS',to_date('2006-05-30','yyyy-mm-dd'));

insert into dinya_test values(7,12'BOOKS',to_date('2005-05-30','yyyy-mm-dd'));

insert into dinya_test values(4,12'BOOKS',to_date('2007-06-23','yyyy-mm-dd'));

insert into dinya_test values(5,12'BOOKS',to_date('2011-02-26','yyyy-mm-dd'));

insert into dinya_test values(6,12'BOOKS',to_date('2011-04-30','yyyy-mm-dd'));

select *From dinya_test;

select *From dinya_test partition(part_07);

select *From dinya_test partition(part_09);

 

參照下圖,按所顯的子分區名,看能否查出數據:

select*Fromuser_tab_subpartitions where table_name=upper('dinya_test');

select *From dinya_test subpartition(SYS_SUBP62);

  備註: 該例中,先是根據交易日期進行範圍分區,然後根據交易的ID將記錄散列地存儲在三個表空間中。

 

1.6) 複合範圍列表分區:這種分區是基於範圍分區和列表分區,表首先按某列進行範圍分區,然後再按某列進行列表分區,分區之中的分區被稱爲子分區。

示例1

Create table sales

(

Product_id varchar2(5),

Sales_date date,

Sales_cost number(10),

Status varchar2(20)

)

Partition by range(Sales_cost)

Subpartition by list(status)

(

Partition p1 values less than (1tablespace dinya_space01

(

Subpartition p1sub1 values('ACTIVE'tablespace   dinya_space03,

Subpartition p1sub2 values('INACTIVE'tablespace dinya_space04

),

Partition p2 values less than (3tablespace dinya_space02

 (

Subpartition p1sub3 values('ACTIVE'tablespace    dinya_space05,

Subpartition p1sub4 values('INACTIVE'tablespace dinya_space06

)

)測試如下:

insert into sales values(1,sysdate,0.1,'ACTIVE');

insert into sales values(2,sysdate+30,1,'INACTIVE');

insert into sales

values(3,to_date('2006-05-30','yyyy-mm-dd'),2,'INACTIVE');

select *From sales

 

        Select *from sales partition(p2)

 

       SELECT * FROM SALES SUBPARTITION(p1sub4)

 

SELECT * FROM SALES SUBPARTITION(p1sub3)

                           沒有數據!!

select *From dba_tab_subpartitions where table_name='SALES'

 

 

 有關表分區的一些維護性操作:

一、添加分區

以下代碼給SALES表添加了一個P3分區

ALTER TABLE SALES ADD PARTITION P3 VALUES LESS THAN(TO_DATE('2003-06-01','YYYY-MM-DD'));

注意:以上添加的分區界限應該高於最後一個分區界限。

以下代碼給SALES表的P3分區添加了一個P3SUB1子分區

ALTER TABLE SALES MODIFY PARTITION P3 ADD SUBPARTITION P3SUB1 VALUES('COMPLETE');

 

二、刪除分區

以下代碼刪除了P3表分區:

ALTER TABLE SALES DROP PARTITION P3;

 在測試中遇到這樣的情況。如果表創建了分區,如果要刪除數據文件(表空間文件),則要先刪除分區,然後才能刪除數據文件(但是在刪除數據文件時,必須要保留一個分區才能最終刪除數據文件>表空間文件,)

當然,也可以直接就刪除表也行,剛所有的全刪除,但是表空間文件還在!

 

在以下代碼刪除了P4SUB1子分區:

ALTER TABLE SALES DROP SUBPARTITION P4SUB1;

注意:如果刪除的分區是表中唯一的分區,那麼此分區將不能被刪除,要想刪除此分區,必須刪除表。

 

三、截斷分區

截斷某個分區是指刪除某個分區中的數據,並不會刪除分區,也不會刪除其它分區中的數據。當表中即使只有一個分區時,也可以截斷該分區。通過以下代碼截斷分區:

ALTER TABLE SALES TRUNCATE PARTITION P2;

通過以下代碼截斷子分區:

ALTER TABLE SALES TRUNCATE SUBPARTITION P2SUB2;

 

四、合併分區

合併分區是將相鄰的分區合併成一個分區,結果分區將採用較高分區的界限,值得注意的是,不能將分區合併到界限較低的分區。以下代碼實現了P1 P2分區的合併:

ALTER TABLE SALES MERGE PARTITIONS P1,P2 INTO PARTITION P2;

 

五、拆分分區

拆分分區將一個分區拆分兩個新分區,拆分後原來分區不再存在。注意不能對HASH類型的分區進行拆分。

ALTER TABLE SALES SBLIT PARTITION P2 AT(TO_DATE('2003-02-01','YYYY-MM-DD'))

INTO (PARTITION P21,PARTITION P22);

 

六、接合分區(coalesca)

結合分區是將散列分區中的數據接合到其它分區中,當散列分區中的數據比較大時,可以增加散列分區,然後進行接合,值得注意的是,接合分區只能用於散列分區中。通過以下代碼進行接合分區:

ALTER TABLE SALES COALESCA PARTITION;

 

七、重命名錶分區

以下代碼將P21更改爲P2

ALTER TABLE SALES RENAME PARTITION P21 TO P2;

 

九、跨分區查詢

select sum( *) from (

(select count(*) cn from t_table_SS PARTITION (P200709_1)

union all

select count(*) cn from t_table_SS PARTITION (P200709_2));

 

十、查詢表上有多少分區

SELECT * FROM useR_TAB_PARTITIONS WHERE TABLE_NAME='tableName'

 

 

--顯示數據庫所有分區表的信息:

select * from DBA_PART_TABLES where table_name=upper('dinya_test')

 

 

--顯示當前用戶可訪問的所有分區表信息:

select * from ALL_PART_TABLES

同上圖

--顯示當前用戶所有分區表的信息:

select * from USER_PART_TABLES

同上圖

--顯示錶分區信息 顯示數據庫所有分區表的詳細分區信息:

select * from DBA_TAB_PARTITIONS

 

--顯示當前用戶可訪問的所有分區表的詳細分區信息:

select * from ALL_TAB_PARTITIONS

 

--顯示當前用戶所有分區表的詳細分區信息:

select * from USER_TAB_PARTITIONS

 

--顯示子分區信息 顯示數據庫所有組合分區表的子分區信息:

select * from DBA_TAB_SUBPARTITIONS

 

--顯示當前用戶可訪問的所有組合分區表的子分區信息:

select * from ALL_TAB_SUBPARTITIONS

 

--顯示當前用戶所有組合分區表的子分區信息:

select * from USER_TAB_SUBPARTITIONS

 

--顯示分區列 顯示數據庫所有分區表的分區列信息:

select * from DBA_PART_KEY_COLUMNS

 

--顯示當前用戶可訪問的所有分區表的分區列信息:

select * from ALL_PART_KEY_COLUMNS

 

--顯示當前用戶所有分區表的分區列信息:

select * from USER_PART_KEY_COLUMNS

 

--顯示子分區列 顯示數據庫所有分區表的子分區列信息:

select * from DBA_SUBPART_KEY_COLUMNS

 

--顯示當前用戶可訪問的所有分區表的子分區列信息:

select * from ALL_SUBPART_KEY_COLUMNS

 

--顯示當前用戶所有分區表的子分區列信息:

select * from USER_SUBPART_KEY_COLUMNS

 

--怎樣查詢出oracle數據庫中所有的的分區表

select * from user_tables a where a.partitioned='YES'

 

--刪除一個表的數據是

truncate table table_name;

 

--刪除分區表一個分區的數據是

alter table table_name truncate partition p5;

 

注:分區根據具體情況選擇。

 

表分區有以下優點:

1、數據查詢:數據被存儲到多個文件上,減少了I/O負載,查詢速度提高。

2、數據修剪:保存歷史數據非常的理想。

3、備份:將大表的數據分成多個文件,方便備份和恢復。

4、並行性:可以同時向表中進行DML操作,並行性性能提高。

================================================

 

索引:

1、一般索引:

create index index_name on table(col_name);

2Oracle 分區索引詳解

語法:Table Index

CREATE [UNIQUE|BITMAP] INDEX [schema.]index_name

ON [schema.]table_name [tbl_alias]

(col [ASC | DESC]) index_clause index_attribs

 

index_clauses:

分以下兩種情況

 

1. Local Index

就是索引信息的存放位置依賴於父表的Partition信息,換句話說創建這樣的索引必須保證父表是Partition

1.1 索引信息存放在父表的分區所在的表空間。但是僅可以創建在父表爲HashTable或者composite分區表的。

LOCAL STORE IN (tablespace)

1.2 僅可以創建在父表爲HashTable或者composite分區表的。並且指定的分區數目要與父表的分區數目要一致

LOCAL STORE IN (tablespace) (PARTITION [partition [LOGGING|NOLOGGING] [TABLESPACE {tablespace|DEFAULT}] [PCTFREE int] [PCTUSED int] [INITRANS int] [MAXTRANS int] [STORAGE storage_clause] [STORE IN {tablespace_name|DEFAULT] [SUBPARTITION [subpartition [TABLESPACE tablespace]]]])

 

1.3 索引信息存放在父表的分區所在的表空間,這種語法最簡單,也是最常用的分區索引創建方式。

Local

1.4 並且指定的Partition 數目要與父表的Partition要一致

LOCAL (PARTITION [partition

[LOGGING|NOLOGGING]

[TABLESPACE {tablespace|DEFAULT}]

[PCTFREE int]

[PCTUSED int]

[INITRANS int]

[MAXTRANS int]

[STORAGE storage_clause]

[STORE IN {tablespace_name|DEFAULT]

[SUBPARTITION [subpartition [TABLESPACE tablespace]]]])

 

Global Index

索引信息的存放位置與父表的Partition信息完全不相干。甚至父表是不是分區表都無所謂的。語法如下:

GLOBAL PARTITION BY RANGE (col_list)

( PARTITION partition VALUES LESS THAN (value_list)

[LOGGING|NOLOGGING]

[TABLESPACE {tablespace|DEFAULT}]

[PCTFREE int]

[PCTUSED int]

[INITRANS int]

[MAXTRANS int]

[STORAGE storage_clause] )

但是在這種情況下,如果父表是分區表,要刪除父表的一個分區都必須要更新Global Index ,否則索引信息不正確

ALTER TABLE TableName DROP PARTITION PartitionName Update Global Indexes

 

 

--查詢索引

select object_name,object_type,tablespace_name,sum(value)

from v$segment_statistics

where statistic_name IN ('physical reads','physical write','logical reads')and object_type='INDEX'

group by object_name,object_type,tablespace_name

order by 4 desc

發佈了9 篇原創文章 · 獲贊 3 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章