パーティション表のディクショナリ表と表領域変更方法

# 1. 内容
- パーティション表のディクショナリ表（dba表）まとめ
- パーティション表の表領域変更方法
  - 物理的に含まれるセグメントに対してmoveコマンドを実行
  - メタデータを対してmoveコマンドを実行するとエラー
  - 表の種類によってmove可能なオブジェクトが異なる
 
| 表の種類 | move可能オブジェクト | 
|:-:|:-:|
| 非パーティション表  | 表  |
| パーティション表  | パーティション  |
| コンポジットパーティション表  | サブパーティション  |

:::note alert
パーティション表の表領域を移動する場合、「パーティション」に対してmoveを実行。「表（メタデータ）」に対してmoveコマンドを実行するとエラー
:::

![5-1_パーティション表の表領域変更.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491580/9fafc481-a503-8502-d5c4-25fe00d95f68.png)




# 2. 前提：パーティション表のディクショナリ表
パーティション表に関連するディクショナリ表
|#| ディクショナリ表 | 内容 | 情報単位 | マニュアル |
|:-:|:-:|:-:|:-:|:-:|
|1| dba_tables  | 表の情報  | 表 | [リンク]((https://docs.oracle.com/cd/F19136_01/refrn/ALL_TABLES.html#GUID-6823CD28-0681-468E-950B-966C6F71325D))  |
|2| dba_part_tables  | パーティション表の情報  | 表 | [リンク](https://docs.oracle.com/cd/F19136_01/refrn/ALL_TAB_PARTITIONS.html#GUID-D6A09AE6-BE9F-43F2-874C-60D218F09AC1)  |
|3| dba_tab_partitions | パーティションの情報  | パーティション  |  [リンク](https://docs.oracle.com/cd/F19136_01/refrn/ALL_PART_TABLES.html#GUID-F6EC7236-9A38-44FA-9A17-F118D1E4F64D) |
|4| dba_tab_subpartitions | サブパーティションの情報  | サブパーティション  | [リンク](https://docs.oracle.com/cd/F19136_01/refrn/ALL_TAB_SUBPARTITIONS.html#GUID-E1EC3001-6092-41A7-96EE-C2CF8A0EB5EA)  |

## ディクショナリ表 格納項目（関連項目のみ抜粋）
### 1. dba_tables

| 表の種類 | tablespace_name | num_rows |
|:-:|:-:|:-:|
|表   | データが格納されている<br>表領域  | 表の行数  |
|パーティション表   | null(※) | 行数合計<br>(全パーティション) |
|コンポジットパーティション表<br>(サブパーティション)   | null(※) | 行数合計<br>(全サブパーティション) |

※デフォルト表領域の設定は dba_part_tables

### 2.  dba_part_tables
| 表の種類 | partitioning_type | subpartitioning_type | def_tablespace_name |
|:-:|:-:|:-:|:-:|
| 表  | ―  | ―  | ―  |
| パーティション表  | パーティションの型<br>RANGE,HASHなど   | NONE  |デフォルト表領域 |
| コンポジットパーティション表<br>(サブパーティション)  | パーティションの型<br>RANGE,HASHなど|サブパーティションの型 | デフォルト表領域 |

※コンポジットパーティション表において、サブパーティションが格納されるデフォルト表領域はdba_tab_partitionsで確認

### 3. dba_tab_partitions
| 表の種類 | tablespace_name | partition_name | COMPOSITE | num_rows |
|:-:|:-:|:-:|:-:|:-:|
| 表  | ―  | ―  | ―  | ―  |
| パーティション表  | データが格納されている<br>表領域  | パーティション名  | NO  | パーティションの行数  |
| コンポジットパーティション表<br>(サブパーティション)  | デフォルト表領域<br>（属性）|パーティション名  | YES  | 行数合計<br>(全サブパーティション)  |

### 4. dba_tab_subpartitions
| 表の種類 | tablespace_name | partition_name | subpartition_name | num_rows |
|:-:|:-:|:-:|:-:|:-:|
| 表  | ―  | ―  | ―  | ―  |
| パーティション表  |  ―  | ―  | ―  | ―  |
| コンポジットパーティション表<br>(サブパーティション)  | データが格納されている<br>表領域|パーティション名  | サブパーティション名  | サブパーティションの行数 |


# 3．表領域移動手順（コマンド例）
## 表領域作成 

```sql
-- 移動前表領域
CREATE TABLESPACE ts_mae DATAFILE 'mae.dbf' SIZE 10M AUTOEXTEND ON;
-- 移動後表領域
CREATE TABLESPACE ts_ato DATAFILE 'ato.dbf' SIZE 10M AUTOEXTEND ON;
```

## 表(t_x)作成 
ts_mae表領域にデータ格納
```sql
CREATE TABLE t_x (
    id NUMBER,
    price NUMBER
) TABLESPACE ts_mae;

INSERT INTO t_x (id, price) VALUES (1, 10);
INSERT INTO t_x (id, price) VALUES (2, 20);
INSERT INTO t_x (id, price) VALUES (3, 30);
INSERT INTO t_x (id, price) VALUES (4, 40);
INSERT INTO t_x (id, price) VALUES (5, 50);
INSERT INTO t_x (id, price) VALUES (6, 16);
INSERT INTO t_x (id, price) VALUES (7, 27);
INSERT INTO t_x (id, price) VALUES (8, 38);
INSERT INTO t_x (id, price) VALUES (9, 49);
INSERT INTO t_x (id, price) VALUES (10, 50);
commit;
```

## パーティション表(pt_x)作成 
RANGEパーティション。ts_mae表領域にデータ格納
```sql
CREATE TABLE pt_x (
    id NUMBER,
    price NUMBER
)
PARTITION BY RANGE (id) (
    PARTITION p1 VALUES LESS THAN (6)  TABLESPACE ts_mae,
    PARTITION p2 VALUES LESS THAN (MAXVALUE) TABLESPACE ts_mae
);

INSERT INTO cpt_x (id, price) VALUES (1, 10);
INSERT INTO cpt_x (id, price) VALUES (2, 20);
INSERT INTO cpt_x (id, price) VALUES (3, 30);
INSERT INTO cpt_x (id, price) VALUES (4, 40);
INSERT INTO cpt_x (id, price) VALUES (5, 50);
INSERT INTO cpt_x (id, price) VALUES (6, 16);
INSERT INTO cpt_x (id, price) VALUES (7, 27);
INSERT INTO cpt_x (id, price) VALUES (8, 38);
INSERT INTO cpt_x (id, price) VALUES (9, 49);
INSERT INTO cpt_x (id, price) VALUES (10, 50);
commit;
```

## コンポジットパーティション表(cpt_x)作成 
RANGE-RANGEパーティション。ts_mae表領域にデータ格納
```sql
CREATE TABLE cpt_x (
    id NUMBER,
    price NUMBER
)
PARTITION BY RANGE (id)
SUBPARTITION BY RANGE (price) (
    PARTITION p1 VALUES LESS THAN (6)(
        SUBPARTITION p1_1 VALUES LESS THAN (31) TABLESPACE ts_mae,
        SUBPARTITION p1_2 VALUES LESS THAN (MAXVALUE) TABLESPACE ts_mae),
    PARTITION p2 VALUES LESS THAN (MAXVALUE)(
        SUBPARTITION p2_1 VALUES LESS THAN (31) TABLESPACE ts_mae,
        SUBPARTITION p2_2 VALUES LESS THAN (MAXVALUE)TABLESPACE ts_mae)
);

INSERT INTO cpt_x (id, price) VALUES (1, 10);
INSERT INTO cpt_x (id, price) VALUES (2, 20);
INSERT INTO cpt_x (id, price) VALUES (3, 30);
INSERT INTO cpt_x (id, price) VALUES (4, 40);
INSERT INTO cpt_x (id, price) VALUES (5, 50);
INSERT INTO cpt_x (id, price) VALUES (6, 16);
INSERT INTO cpt_x (id, price) VALUES (7, 27);
INSERT INTO cpt_x (id, price) VALUES (8, 38);
INSERT INTO cpt_x (id, price) VALUES (9, 49);
INSERT INTO cpt_x (id, price) VALUES (10, 50);
commit;

```

## dba_tables確認
TABLESPACE列はデータの格納表領域がts_mae。
パーティション表はnull。
```sql
SQL> select table_name, tablespace_name, num_rows from dba_tables where table_name in ('T_X', 'PT_X', 'CPT_X');

TABLE_NAME TABLESPACE   NUM_ROWS
---------- ---------- ----------
T_X        TS_MAE             10
PT_X                          10
CPT_X                         10
```

## dba_part_tables確認
パーティション表のデフォルト表領域はusers（DEF_TABLESPACE_NAME列）
```sql
SQL> select table_name, partitioning_type, subpartitioning_type, def_tablespace_name from dba_part_tables where table_name in ('T_X', 'PT_X', 'CPT_X');

TABLE_NAME PARTITIONING_TYPE    SUBPARTITIONING_TYPE DEF_TABLESPACE_NAME
---------- -------------------- -------------------- ------------------------------
CPT_X      RANGE                RANGE                USERS
PT_X       RANGE                NONE                 USERS
```

## DBA_TAB_PARTITIONS確認
（TABLESPACE列）
　パーティション表（pt_x）のデータ格納表領域はts_mae
　コンポジットパーティション表（cpt_x）のデフォルト表領域はusers
```sql
SQL> select table_name, tablespace_name, PARTITION_NAME, COMPOSITE, NUM_ROWS from DBA_TAB_PARTITIONS where table_name in ('T_X', 'PT_X', 'CPT_X');

TABLE_NAME TABLESPACE PARTITION_NAME  COMPOSITE    NUM_ROWS
---------- ---------- --------------- ---------- ----------
PT_X       TS_MAE     P1              NO                  5
PT_X       TS_MAE     P2              NO                  5
CPT_X      USERS      P1              YES                 5
CPT_X      USERS      P2              YES                 5
```

## dba_tab_subpartitions確認
サブパーティションのデータ格納表領域はts_mae（TABLESPACE列）
```sql
SQL> select table_name, tablespace_name, partition_name, subpartition_name, NUM_ROWS from dba_tab_subpartitions where table_name in ('T_X', 'PT_X', 'CPT_X');

TABLE_NAME TABLESPACE PARTITION_NAME  SUBPARTITI   NUM_ROWS
---------- ---------- --------------- ---------- ----------
CPT_X      TS_MAE     P1              P1_1                3
CPT_X      TS_MAE     P1              P1_2                2
CPT_X      TS_MAE     P2              P2_1                2
CPT_X      TS_MAE     P2              P2_2                3
```

## 表の表領域移動（ts_mae → ts_ato）
表の表領域移動コマンド
>  alter table <表名> move tablespace <移動先の表領域名>
```sql
SQL> ALTER TABLE t_x MOVE TABLESPACE ts_ato;

表が変更されました。

SQL> select table_name, tablespace_name, num_rows from dba_tables where table_name in ('T_X', 'PT_X', 'CPT_X');

TABLE_NAME TABLESPACE   NUM_ROWS
---------- ---------- ----------
T_X        TS_ATO             10
PT_X                          10
CPT_X                         10
```

## パーティション表の表領域移動（ts_mae → ts_ato）
パーティション表に対するmoveコマンドはORA-14511エラー
理由：表はメタデータ。物理的にデータを持つのはパーティション。
```sql
SQL> ALTER TABLE pt_x MOVE TABLESPACE ts_ato;
ALTER TABLE pt_x MOVE TABLESPACE ts_ato
            *
行1でエラーが発生しました。:
ORA-14511: この操作はパーティション・オブジェクトでは実行できません。
```
パーティションに対してmoveを実行
> ALTER TABLE <表名> MOVE PARTITION <パーティション名> TABLESPACE <移動先の表領域名>;

```sql
SQL> ALTER TABLE pt_x MOVE PARTITION p1 TABLESPACE ts_ato;

表が変更されました。

SQL> select table_name, partitioning_type, subpartitioning_type, def_tablespace_name from dba_part_tables where table_name in ('T_X', 'PT_X', 'CPT_X');

TABLE_NAME PARTITIONING_TYPE    SUBPARTITIONING_TYPE DEF_TABLESPACE_NAME
---------- -------------------- -------------------- ------------------------------
CPT_X      RANGE                RANGE                USERS
PT_X       RANGE                NONE                 USERS

SQL> select table_name, tablespace_name, PARTITION_NAME, COMPOSITE, NUM_ROWS from DBA_TAB_PARTITIONS where table_name in ('T_X', 'PT_X', 'CPT_X');

TABLE_NAME TABLESPACE PARTITION_NAME  COMPOSITE    NUM_ROWS
---------- ---------- --------------- ---------- ----------
PT_X       TS_ATO     P1              NO                  5
PT_X       TS_MAE     P2              NO                  5
CPT_X      USERS      P1              YES                 5
CPT_X      USERS      P2              YES                 5
```

## コンポジットパーティション表（サブパーティション）の表領域移動（ts_mae → ts_ato）
コンポジットパーティション表でパーティションに対するmoveコマンドはORA-14257エラー
理由：パーティションはメタデータ。データを物理的に持つのはサブパーティション。
```sql
SQL> ALTER TABLE cpt_x MOVE PARTITION p1 TABLESPACE ts_ato;
ALTER TABLE cpt_x MOVE PARTITION p1 TABLESPACE ts_ato
                                 *
行1でエラーが発生しました。:
ORA-14257: コンポジット・パーティションであるパーティションは移動できません
```
サブパーティションに対してmove
> ALTER TABLE <表名> MOVE SUBPARTITION <サブパーティション名> TABLESPACE  <移動先の表領域名>;

```sql
SQL> ALTER TABLE cpt_x MOVE SUBPARTITION p1_1 TABLESPACE ts_ato;

表が変更されました。

SQL> select table_name, tablespace_name, partition_name, subpartition_name, NUM_ROWS from dba_tab_subpartitions where table_name in ('T_X', 'PT_X', 'CPT_X');

TABLE_NAME TABLESPACE PARTITION_NAME  SUBPARTITI   NUM_ROWS
---------- ---------- --------------- ---------- ----------
CPT_X      TS_ATO     P1              P1_1                3
CPT_X      TS_MAE     P1              P1_2                2
CPT_X      TS_MAE     P2              P2_1                2
CPT_X      TS_MAE     P2              P2_2                3

```

## パーティション表のデフォルト表領域変更（users → ts_ato）
パーティションが格納されるデフォルトの表領域を変更
> ALTER TABLE <表名> MODIFY DEFAULT ATTRIBUTES TABLESPACE <表領域名>;

```sql
SQL> ALTER TABLE pt_x MODIFY DEFAULT ATTRIBUTES TABLESPACE ts_ato;

表が変更されました。

SQL> select table_name, partitioning_type, subpartitioning_type, def_tablespace_name from dba_part_tables where table_name in ('T_X', 'PT_X', 'CPT_X');

TABLE_NAME PARTITIONING_TYPE    SUBPARTITIONING_TYPE DEF_TABLESPACE_NAME
---------- -------------------- -------------------- ------------------------------
CPT_X      RANGE                RANGE                USERS
PT_X       RANGE                NONE                 TS_ATO
```

## サブパーティションのデフォルト表領域変更（users → ts_ato）（※パーティション定義）
サブパーティションが格納されるデフォルトの表領域を変更
> ALTER TABLE <表名> MODIFY DEFAULT ATTRIBUTES FOR PARTITION <パーティション名> TABLESPACE <表領域名>;


```sql
SQL> ALTER TABLE cpt_x MODIFY DEFAULT ATTRIBUTES FOR PARTITION p1 TABLESPACE ts_ato;

表が変更されました。

SQL> select table_name, tablespace_name, PARTITION_NAME, COMPOSITE, NUM_ROWS from DBA_TAB_PARTITIONS where table_name in ('T_X', 'PT_X', 'CPT_X');

TABLE_NAME TABLESPACE PARTITION_NAME  COMPOSITE    NUM_ROWS
---------- ---------- --------------- ---------- ----------
PT_X       TS_ATO     P1              NO                  5
PT_X       TS_MAE     P2              NO                  5
CPT_X      TS_ATO     P1              YES                 5
CPT_X      USERS      P2              YES                 5
```



## 参考リンク
- パーティション
  - [実践！パーティションの基本から実装例まで](https://www.oracle.com/technetwork/jp/ondemand/database/db-technique/d-12-disk-1484778-ja.pdf)
  - [【再掲載】[超図解]パーティション化(1/5) パーティション事始め - DBひとりでできるもん](https://xn--w8j8bac3czf5bl7e.com/2023/05/11/%e8%b6%85%e5%9b%b3%e8%a7%a3%e3%83%91%e3%83%bc%e3%83%86%e3%82%a3%e3%82%b7%e3%83%a7%e3%83%b3%e5%8c%961-5-%e3%83%91%e3%83%bc%e3%83%86%e3%82%a3%e3%82%b7%e3%83%a7%e3%83%b3%e4%ba%8b%e5%a7%8b%e3%82%81-2/)


- パーティションの表領域移動
[ALTER TABLE MOVE ＜ヒープ表＞ - オラクル・Oracleをマスターするための基本と仕組み](https://www.shift-the-oracle.com/alter-table/table-move/table-move-heap.html)