🔷 この記事の目的
本記事では、Oracle Databaseでマテリアライズド・ビュー(MV)を使用する手順を、
PDB01(参照側)⇔ PDB02(データ提供側) という構成で実機ベースに解説します。
また、冒頭で 使用ユーザーの作成手順 を記載し、権限要件も明確にします。
さらに、この構成はCDB環境に限らず、通常の2つのデータベース間でも同じ手順で使用可能であることを説明します。
リンク
リンク
リンク
🔷 システム構成図(テキスト)
Oracle CDB環境(例:CDB1)
┌────────┐ DBリンク ┌────────┐
│ PDB01 │◀───────────────│ PDB02 │
│(参照側)│ MV参照 │(提供側)│
└────────┘ └────────┘
▲ │
│ ▼
CREATE MATERIALIZED VIEW CREATE TABLE + GRANT
🔷 1. 使用ユーザーの作成と権限付与
▼ PDB02(提供側)のユーザー作成
-- sysdbaでPDB02に接続
SQL> CONNECT / AS SYSDBA
SQL> ALTER SESSION SET CONTAINER = PDB02;
-- ユーザー作成
CREATE USER hr IDENTIFIED BY hr
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON users;
-- 権限付与
GRANT CONNECT, RESOURCE TO hr;
▼ PDB01(参照側)のユーザー作成
-- sysdbaでPDB01に接続
SQL> CONNECT / AS SYSDBA
SQL> ALTER SESSION SET CONTAINER = PDB01;
-- ユーザー作成
CREATE USER hr IDENTIFIED BY hr
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON users;
-- 権限付与
GRANT CONNECT, RESOURCE, CREATE DATABASE LINK, CREATE MATERIALIZED VIEW TO hr;
🔷 2. ベース表の作成(PDB02)
-- PDB02のhrユーザーで接続
SQL> CONNECT hr/hr@pdb02
-- ベース表作成
CREATE TABLE products (
product_id NUMBER PRIMARY KEY,
product_name VARCHAR2(100),
price NUMBER
);
-- データ投入
INSERT INTO products VALUES (1, 'Keyboard', 4000);
INSERT INTO products VALUES (2, 'Mouse', 2500);
INSERT INTO products VALUES (3, 'Monitor', 18000);
COMMIT;
🔷 3. 参照用ユーザーに権限付与(PDB02側)
-- sysdbaでPDB02に接続
SQL> CONNECT / AS SYSDBA
SQL> ALTER SESSION SET CONTAINER = PDB02;
-- hrユーザーに対してパブリック権限を付与(簡易構成)
GRANT SELECT ON hr.products TO hr;
🔷 4. DBリンクの作成(PDB01)
-- PDB01のhrユーザーで接続
SQL> CONNECT hr/hr@pdb01
-- DBリンク作成(tnsnames.oraにpdb02を定義済みである前提)
CREATE DATABASE LINK pdb02_link
CONNECT TO hr IDENTIFIED BY hr
USING 'pdb02';
# tnsnames.ora の例
pdb02 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.20)(PORT = 1521))
(CONNECT_DATA =
(SERVICE_NAME = pdb02)
)
)
🔷 5. マテリアライズド・ビューの作成(PDB01)
-- DBリンク経由でPDB02の表を参照
CREATE MATERIALIZED VIEW mv_products
REFRESH ON DEMAND
AS
SELECT * FROM products@pdb02_link;
🔷 6. マテビューの参照・リフレッシュと動作確認
▼ 現時点での内容確認(リフレッシュ前)
-- ローカル側(PDB01)のマテビュー確認
SELECT * FROM mv_products;
出力例(初期状態):
PRODUCT_ID PRODUCT_NAME PRICE
----------- ------------- -----
1 Keyboard 4000
2 Mouse 2500
3 Monitor 18000
▼ PDB02に4行目を追加
-- PDB02で接続
SQL> CONNECT hr/hr@pdb02
-- データ追加(4行目)
INSERT INTO products VALUES (4, 'Headset', 5500);
COMMIT;
▼ PDB01でリフレッシュと確認
-- PDB01でMVを手動リフレッシュ
EXEC DBMS_MVIEW.REFRESH('MV_PRODUCTS');
-- 再度確認
SELECT * FROM mv_products;
出力例(リフレッシュ後):
PRODUCT_ID PRODUCT_NAME PRICE
----------- ------------- -----
1 Keyboard 4000
2 Mouse 2500
3 Monitor 18000
4 Headset 5500 ← 追加されたデータ
✅ MVが最新のデータを反映していることが確認できました。
SQL> show con_name
CON_NAME
------------------------------
PDB02
SQL> set lin 1000 pages 1000
SQL> col product_name for a30
SQL> select * from products; ★作成した表
PRODUCT_ID PRODUCT_NAME PRICE
---------- ------------------------------ ----------
1 Keyboard 4000
2 Mouse 2500
3 Monitor 18000
SQL> CONNECT hr/hr@pdb01
接続されました。
SQL> show con_name
CON_NAME
------------------------------
PDB01
SQL> CREATE DATABASE LINK pdb02_link ★DBLINKを作成
2 CONNECT TO hr IDENTIFIED BY hr
3 USING 'pdb02';
データベース・リンクが作成されました。
SQL> select * from products@pdb02_link;
PRODUCT_ID PRODUCT_NAME PRICE
---------- ------------------------------ ----------
1 Keyboard 4000
2 Mouse 2500
3 Monitor 18000
SQL> CREATE MATERIALIZED VIEW mv_products ★マテリアライズド・ビューを作成
2 REFRESH ON DEMAND
3 AS
4 SELECT * FROM products@pdb02_link;
マテリアライズド・ビューが作成されました。
SQL> SELECT * FROM mv_products;
PRODUCT_ID PRODUCT_NAME PRICE
---------- ------------------------------ ----------
1 Keyboard 4000
2 Mouse 2500
3 Monitor 18000
SQL> CONNECT hr/hr@pdb02
接続されました。
SQL> show con_name
CON_NAME
------------------------------
PDB02
SQL> INSERT INTO products VALUES (4, 'Headset', 5500); ★元の表を更新
1行が作成されました。
SQL> COMMIT;
コミットが完了しました。
SQL> select * from products;
PRODUCT_ID PRODUCT_NAME PRICE
---------- ------------------------------ ----------
1 Keyboard 4000
2 Mouse 2500
3 Monitor 18000
4 Headset 5500 ★
SQL> CONNECT hr/hr@pdb01
接続されました。
SQL> show con_name
CON_NAME
------------------------------
PDB01
SQL> SELECT * FROM products@pdb02_link; ★DBLINKでselect
PRODUCT_ID PRODUCT_NAME PRICE
---------- ------------------------------ ----------
1 Keyboard 4000
2 Mouse 2500
3 Monitor 18000
4 Headset 5500 ★
SQL> SELECT * FROM mv_products; ★マテリアライズド・ビュー
PRODUCT_ID PRODUCT_NAME PRICE
---------- ------------------------------ ----------
1 Keyboard 4000
2 Mouse 2500
3 Monitor 18000 ★更新されていない
SQL> EXEC DBMS_MVIEW.REFRESH('MV_PRODUCTS'); ★リフレッシュ
PL/SQLプロシージャが正常に完了しました。
SQL> SELECT * FROM mv_products;
PRODUCT_ID PRODUCT_NAME PRICE
---------- ------------------------------ ----------
1 Keyboard 4000
2 Mouse 2500
3 Monitor 18000
4 Headset 5500 ★
🔷 7. 通常のOracle DB(非CDB)構成でも同様に使用可能
この構成は、CDB環境である必要は一切ありません。
2つのOracle Databaseがあれば、DBリンクさえ作成できれば同様にマテビューを使用可能です。
┌────────────┐ DBリンク ┌────────────┐
│ DB_A │◀───────────────│ DB_B │
│(参照側) │ MV参照 │(提供側) │
└────────────┘ └────────────┘
🔷 8. 補足:リフレッシュ方式の選択肢
| モード | 概要 | 備考 |
|---|---|---|
| ON COMMIT | ベース表更新時に即反映 | リモート表では使用不可 |
| ON DEMAND | 必要な時に手動更新 | 本記事で使用 |
| ON SCHEDULE | スケジューラ連携で自動更新 | DBMS_SCHEDULERと併用可 |
🔷 9. 注意点
- MV作成に必要な権限(CREATE MATERIALIZED VIEW、CREATE DATABASE LINK)を付与すること
- DBリンク経由の表に対してSELECT権限があること
- MVは自動で更新されないため、リフレッシュ運用が必須
- DBリンク名や接続先識別子(TNS)は環境に応じて変更すること
🔷 まとめ
マテリアライズド・ビューは、PDB環境でもシングルDB構成でも同じように利用でき、性能・可用性・ネットワーク最適化の面で非常に有効です。
✅ 頻繁に同じリモートデータを参照する
✅ ネットワーク負荷を軽減したい
✅ ベース表を変更せずに読み取り専用で利用したい
このような要件がある場合、DBリンク+MVの構成は有力な選択肢となります。
[参考]
5 基本的なマテリアライズド・ビュー


コメント