[Oracle] 初心者向け!Oracleデータベースリンクの作成手順と注意事項

Oracle

便利なOracleデータベースの機能としてデータベースリンクがあります。

データベースリンクを利用することで、リモートにあるデータベースの表であっても、
あたかもローカルに存在する表のように参照や更新ができるようになります。

一方で、データベースリンクを利用する際の注意点もありますので、そのあたりも細かく解説していきます。

データベースリンクとは?

データベースリンクは、異なるOracleデータベース間でリモートアクセスを可能にする機能です。
ローカルのデータベースから別のデータベースの表やビューに対して、
通常のSQLクエリと同じ感覚で参照や更新が可能になります。

データベースリンクを利用する主な用途はこちらです。

  • 異なるデータベースのデータを統合(例:本社DBと支社DBを統合)
  • データの分散管理(負荷分散のために別々のデータベースを使用)
  • リモートデータを直接参照可能(データ移行せずに別DBのデータを利用)
  • データベース移行(ローカルからリモートにデータを移行)

データベースリンクを利用する

本記事ではデータベースリンクを利用する環境として、
Oracle 19cデータベースから、別のOracle 19cデータベースのemp表を参照することを想定します。

Oracle 19cのデータベースはマルチテナント構成が一般的です。
本記事の前提となる構成をまとめておきます。

SQL*Plusローカル(データベースリンク元)リモート(データベースリンク先)
バージョン:19cホスト名:foo
リスナーポート番号:1521
バージョン:19c
コンテナ・データベース:C1DB
プラガブル・データベース:P1DB
ユーザ:scott1
ホスト名:bar
リスナーポート番号:1521
バージョン:19c
コンテナ・データベース:C2DB
プラガブル・データベース:P2DB
ユーザ:scott2

データベースリンクは以下のような流れで利用することができます。

  1. リモート側(データベースリンク先)のC2DBデータベースにemp表を作成する
  2. リモート側のC2DBデータベースにリスナー経由で接続できるようにする
  3. ローカル側(データベースリンク元)のC1DBデータベースでデータベースリンクを作成する
  4. ローカル側のC1DBデータベースからリモート側の表を参照する

ひとつずつ詳細を説明していきます。

リモート側(データベースリンク先)のデータベースに表を作成する

プラガブル・データベースであるP2DBのscott2ユーザに、
データベースリンク経由で参照するためのemp表を作成します。

P2DBにemp表を作る方法は色々ありますが、以下の流れで作成することができます。

[bar]$ sqlplus / as sysdba
SQL> alter session set container = P2DB;
SQL> grant dba to scott2 identified by tiger;
SQL> create table scott2.emp (empno number, ename varchar(50));
SQL> insert into scott2.emp values (1001, 'root');
SQL> insert into scott2.emp values (1002, 'oracle');
SQL> insert into scott2.emp values (1003, 'grid');
SQL> commit;
SQL> select * from scott2.emp;
SQL> exit;

実行結果は以下となります。
「show con_name」や「show user」でユーザを確認しながら進めてください。

[bar]$ sqlplus / as sysdba
SQL> alter session set container = P2DB;
セッションが変更されました。

SQL> show con_name
CON_NAME
------------------------------
P2DB

SQL> grant dba to scott2 identified by tiger;
権限付与が成功しました。

SQL> create table scott2.emp (empno number, ename varchar(50));
表が作成されました。

SQL> insert into scott2.emp values (1001, 'root');
1行が作成されました。

SQL> insert into scott2.emp values (1002, 'oracle');
1行が作成されました。

SQL> insert into scott2.emp values (1003, 'grid');
1行が作成されました。

SQL> commit;
コミットが完了しました。

SQL> set lines 200 pages 200
SQL> select * from scott2.emp

     EMPNO ENAME
---------- -----------------------------------------
      1001 root
      1002 oracle
      1003 grid

SQL> exit;

ここまでで、P2DBプラガブル・データベースのscott2ユーザにemp表を作成することができました。

リモート側のデータベースにリスナー経由で接続できるようにする

データベースリンクを利用する場合、データベースにリモート接続する必要があります。
具体的には、リスナー経由での接続をできるようにしておく必要があります。

リモート接続する方法はこちらの記事を参照してください。

以下のコマンドで、リスナー経由で接続可能かを簡易的に確認することができます。

[foo]$ sqlplus scott2/tiger@<リモート側ホスト名>:<リスナーポート番号(デフォルトは1521)>/P2DB
SQL> select * from emp;
SQL> exit;

実行結果は以下のようになります。

[foo]$ sqlplus scott2/tiger@bar:1521/P2DB
SQL> show con_name
CON_NAME
------------------------------
P2DB

SQL> show user
ユーザーは"SCOTT2"です。

SQL> set lines 200 pages 200
SQL> select * from emp;
     EMPNO ENAME
---------- -----------------------------------------
      1001 root
      1002 oracle
      1003 grid

SQL> exit;

ローカル側(データベースリンク元)でデータベースリンクを作成する

ローカル側でscott1ユーザにデータベースリンクオブジェクト(dbl_bar)を作成します。

[foo]$ sqlplus / as sysdba
SQL> alter session set container = P1DB;
SQL> grant dba to scott1 identified by tiger;
SQL> exit

[foo]$ sqlplus scott1/tiger@foo:1521/P1DB
SQL> create database link dblink_bar connect to scott2 identified by tiger using '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=bar)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=P2DB)))';
SQL> exit;

実行結果は以下のようになります。

[foo]$ sqlplus / as sysdba
SQL> alter session set container = P1DB;
セッションが変更されました。

SQL> show con_name
CON_NAME
------------------------------
P2DB

SQL> grant dba to scott1 identified by tiger;
権限付与が成功しました。

SQL> exit;

[foo]$ sqlplus scott1/tiger@foo:1521/P1DB
SQL> show con_name
CON_NAME
------------------------------
P1DB

SQL> show user
ユーザーは"SCOTT1"です。

SQL> create database link dblink_bar connect to scott2 identified by tiger using '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=bar)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=P2DB)))';
データベース・リンクが作成されました。

SQL> exit;

(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=bar)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=P2DB))) 部分には、
tnsnames.oraに記述した接続識別子を書くこともできます。

りお
りお

通常は接続識別子を書くことが多いです。

この場合のtnsnames.oraは、$ORACLE_HOME/network/admin配下のtnsnames.oraが使用されますので、
こちらのファイルに接続識別子を記述しておく必要があります。
「con_bar」という接続識別子を使用する場合は、以下のようにデータベースリンクを作成できます。

SQL> create database link dblink_bar connect to scott2 identified by tiger using 'con_bar';
データベース・リンクが作成されました。

ローカル側でリモート側の表を参照する

作成したデータベースリンクを使って、リモートにあるemp表を参照してみます。

[foo]$ sqlplus scott1/tiger@foo:1521/P1DB
SQL> select * from emp@dblink_bar;
SQL> exit;

実行結果は以下のようになります。

[foo]$ sqlplus scott1/tiger@foo:1521/P1DB
SQL> show con_name
CON_NAME
------------------------------
P1DB

SQL> set lines 200 pages 200
SQL> select * from emp@dbl_bar;
     EMPNO ENAME
---------- -----------------------------------------
      1001 root
      1002 oracle
      1003 grid

SQL> exit;

さらにシノニムを利用することで、@dbl_bar を書く必要もなくなりますので、
本当にローカルに存在する表のように扱うことができます。

SQL> create synonym emp for emp@dbl_bar;
シノニムが作成されました。

SQL> set lines 200 pages 200
SQL> select * from emp;
     EMPNO ENAME
---------- -----------------------------------------
      1001 root
      1002 oracle
      1003 grid
りお
りお

参照だけでなく、もちろん更新も可能です。

データベースリンク利用時の注意点

データベースリンクを利用する上で、いくつかの注意点があります。

バージョン互換

データベースリンクを利用する場合、ローカルとリモートのDBバージョンによってサポート可否が変わります。

Client Versionが接続元に相当し、Server Versionが接続先に相当します。
本記事のように、SQL*Plus、ローカルDB、リモートDBがすべて同じバージョンの場合は問題ありませんが、
バージョンが異なる場合には注意が必要です。
データベースリンクの場合、ClientとServerの両方を気にしておかないといけません。

SQL*Plusから見ると、ローカルDBは接続先となりますので、
SQL*PlusをClient、ローカルDBをServerとして、バージョン互換があるかを確認します。

一方、ローカルDBから見ると、今度はリモートDBが接続先になりますので、
ローカルDBをClient、リモートDBをServerとして、バージョン互換があるかを確認する必要があります。

データベース構成

データベースリンクは使い方によってはかなり便利なのですが、
運用時の統制が取れていないと、データベースリンクが乱立してしまう場合があります。
システムによっては、データベースリンクが数珠つなぎに張り巡らされてしまっているケースもあります。

こうなってしまうと管理もできませんし、いざデータベースを移行しようとなった時に、
別のデータベースも一緒に移行しないといけない状態になります。

まとめ

使い方によってはかなり便利なデータベースリンクについて解説しました。
一部使い方に注意は必要ですが、Oracleの非常に強力な機能と言えます。

コメント

タイトルとURLをコピーしました