Oracle ROWID 機能を AWS の PostgreSQL に移行 - AWS 規範ガイダンス

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

Oracle ROWID 機能を AWS の PostgreSQL に移行

Amazon Web Services、Rakesh Raghav、Ramesh Pathuri

概要

このパターンでは、Oracle データベースの ROWID 疑似列機能を、Amazon Aurora PostgreSQL のAmazon Relational Database Service (Amazon RDS)、Amazon Aurora PostgreSQL 互換バージョン、またはAmazon Elastic Compute Cloud (Amazon EC2)に移行するオプションについて説明しています。

Oracle データベースでは、ROWID 疑似列がテーブル内の行の物理アドレスです。この疑似列は、プライマリキーがテーブルに存在しない場合でも行を一意に識別するために使用されます。PostgreSQL にも ctid と呼ばれる同様の疑似列がありますが、ROWID としては使用できません。「PostgreSQLのドキュメント」 で説明されているように、更新される場合、またはctid がすべての VACUUM のプロセスの後に変更される可能性があります。

PostgreSQLで ROWID 疑似列機能を作成する方法が3つあります:

  • ROWID の代わりに、テーブルの行を識別するプライマリキー列を使用します。

  • テーブルには論理的なプライマリキー/ユニークキー (複合キーの場合もあります) を使用します。 

  • 自動生成された値を含む列を追加し、ROWID を模倣するプライマリキー/ユニークキーにします。

このパターンでは、3 つの実装について順を追って説明し、各オプションの利点と欠点を説明します。

前提条件と制限

前提条件

  • アクティブなAWS アカウント

  • 手続き型言語/PostgreSQL (PL/pgSQL) コーディングの専門知識

  • ソース Oracle データベース

  • Amazon RDS for PostgreSQL または Aurora PostgreSQL 互換クラスター、または PostgreSQL データベースをホストする EC2 インスタンス

制限事項

  • このパターンは、ROWID の機能の回避策を提供します。PostgreSQL は Oracle データベースの ROWID と同等の機能を提供していません。

製品バージョン

  • PostgreSQL 11.9 以降

アーキテクチャ

ソーステクノロジースタック

  • Oracle Database

ターゲットテクノロジースタック

  • Aurora PostgreSQL 互換、Amazon RDS for PostgreSQL、または PostgreSQL データベースを備えた EC2 インスタンス

Oracle データベースを AWS で PostgreSQL に変換

実装オプション

PostgreSQLで ROWID のサポート不足を回避するには、テーブルにプライマリキーまたはユニークインデックス、論理的プライマ的キー、またはID属性があるかどうかに応じて、3つの選択肢があります。どれを選択するかは、プロジェクトのスケジュール、現在の移行フェーズ、アプリケーションとデータベースコードへの依存関係によって異なります。

オプション

説明

利点

欠点

プライマリキーまたは一意のインデックス

Oracle テーブルにプライマリキーがある場合、このキーの属性を使用して、行を一意に識別することができます。 

  • 独自データベースの特徴には依存していません。。

  • プライマリキーフィールドにはインデックスが付けられるため、パフォーマンスへの影響は最小限です。

  • プライマリキーフィールドに切り替えるには、ROWID に依存するアプリケーションコードやデータベースコードを変更する必要があります。

 

論理プライマリキー/ユニーククキー

Oracle テーブルに論理プライマリキーがある場合、このキーの属性を使用して行を一意に識別できます。論理プライマリキーは、行を一意に識別できる 1 つまたは複数の属性で構成されますが、制約によってデータベースに適用されません。

  • 独自データベースの特徴には依存していません。

  • プライマリキーフィールドに切り替えるには、ROWID に依存するアプリケーションコードやデータベースコードを変更する必要があります。

  • 論理プライマリキーの属性にインデックスが作成されない場合、パフォーマンスに重大な影響があります。ただし、パフォーマンスの問題を防ぐために唯一のインデックスを追加できます。

アイデンティティ属性

Oracle テーブルにプライマリキーがない場合、GENERATED ALWAYS AS IDENTITY として追加のフィールドを作成できます。この属性は、テーブルにデータが挿入されるたびに常に唯一の値を生成します。ですから、データ操作言語 (DML) 操作の行を一意に識別するために使用できます。

  • 独自データベースの特徴には依存していません。

  • PostgreSQL データベースは、属性を入力し、その一意性を維持します。

  • アイデンティティ属性に切り替えるには、」ROWID に依存するアプリケーションおよびデータベースコードを変更する必要があります。

  • 追加フィールドがインデックスされない場合、パフォーマンスに重大な影響を与えます。ただし、パフォーマンスの問題を避けるためにインデックスを追加できます。

ツール

  • PostgreSQLのAmazon Relational Database Service (Amazon RDS) を使用して、 AWSクラウドで PostgreSQLリレーショナルデータベース (DB) のセットアップ、運用、スケーリングができます。

  • Amazon Aurora PostgreSQL 互換エディション」は、PostgreSQL デプロイのセットアップ、運用、スケーリングに役立つ、フルマネージド型のACID準拠のリレーショナルデータベースエンジンです。

  • AWS コマンドラインインターフェイス (AWS CLI)」は、オープンソースのツールであり、コマンドラインシェルのコマンドを使用して AWS サービスとやり取りすることができます。このパターンでは、AWS CLI を使用して pgAdmin を介して SQL コマンドを実行できます。

  • pgAdmin」は、PostgreSQLのオープンソース管理ツールです。データベースオブジェクトの作成、管理、使用を支援するグラフィカルインターフェイスを提供します。

  • AWS Schema Conversion Tool (AWS SCT) は、ソースデータベーススキーマとカスタムコードの大部分を、ターゲットデータベースと互換性のある形式に自動的に変換することにより、異種データベース移行をサポートします。

エピック

タスク説明必要なスキル

ROWID 属性を使用する Oracle テーブルを識別します。

AWS Schema Conversion Tool (AWS SCT) を使用して、ROWID の機能を持つ Oracle テーブルを識別します。詳細については、「AWS SCTドキュメント」を参照してください。

-または-

Oracle では、DBA_TAB_COLUMNS ビューを使用して、ROWID 属性を持つテーブルを識別します。これらのフィールドは、10 バイトの英数字を格納するために使用される場合があります。使用方法を決定し、必要に応じて VARCHAR フィールドに変換します。

DBA または開発者

これらのテーブルを参照するコードを識別します。

AWS SCT を使用して、移行評価レポートを生成し、ROWID より影響された手順を識別します。詳細については、「AWS SCTドキュメント」を参照してください。

-または-

ソース Oracle データベースでは、dba_source のテーブルのテキストフィールドを使用して、ROWIDの機能を使用するオブジェクトを識別します。

DBA または開発者
タスク説明必要なスキル

プライマリキーがないテーブルを識別します。

ソース Oracle データベースで、DBA_CONSTRAINTS を使用してプライマリキーがないテーブルを識別します。この情報により、各テーブルの戦略を決定することを支援します。例えば、次のようになります。

select dt.* from dba_tables dt where not exists (select 1 from all_constraints ct where ct.owner = Dt.owner and ct.table_name = Dt.table_name and ct.constraint_type = 'P' ) and dt.owner = '{schema}'
DBA または開発者
タスク説明必要なスキル

プライマリキーが定義されているテーブル、または論理的なプライマリキーを持つテーブルに変更を適用します。

追加情報」セクションに示されているアプリケーションコードおよびデータベースコードを変更して、固有のプライマリキーまたは論理プライマリキーを使用してテーブルの行を識別するようにします。

DBA または開発者

プライマリキーが定義されていない、または論理プライマリキーがないテーブルにフィールドを追加します。

タイプ GENERATED ALWAYS AS IDENTITY の属性を追加します。「追加情報」セクションに表示されているアプリケーションとデータベースのコードを変更します。

DBA または開発者

必要に応じてインデックスを追加します。

SQL のパフォーマンスを向上させるには、追加フィールドまたは論理プライマリキーにインデックスを追加します。

DBA または開発者

関連リソース

追加情報

以下のセクションでは、Oracle と PostgreSQL のコード例を示して、これらの 3 つのアプローチを説明します。

シナリオ 1: プライマリユニークキーを使用

以下の例では、testrowid_s1 テーブルを、emp_id をプライマリキーとして作成します。

Orackel コード:

create table testrowid_s1 (emp_id integer, name varchar2(10), CONSTRAINT testrowid_pk PRIMARY KEY (emp_id)); INSERT INTO testrowid_s1(emp_id,name) values (1,'empname1'); INSERT INTO testrowid_s1(emp_id,name) values (2,'empname2'); INSERT INTO testrowid_s1(emp_id,name) values (3,'empname3'); INSERT INTO testrowid_s1(emp_id,name) values (4,'empname4'); commit; SELECT rowid,emp_id,name FROM testrowid_s1; ROWID EMP_ID NAME ------------------ ---------- ---------- AAAF3pAAAAAAAMOAAA 1 empname1 AAAF3pAAAAAAAMOAAB 2 empname2 AAAF3pAAAAAAAMOAAC 3 empname3 AAAF3pAAAAAAAMOAAD 4 empname4 UPDATE testrowid_s1 SET name = 'Ramesh' WHERE rowid = 'AAAF3pAAAAAAAMOAAB' ; commit; SELECT rowid,emp_id,name FROM testrowid_s1; ROWID EMP_ID NAME ------------------ ---------- ---------- AAAF3pAAAAAAAMOAAA 1 empname1 AAAF3pAAAAAAAMOAAB 2 Ramesh AAAF3pAAAAAAAMOAAC 3 empname3 AAAF3pAAAAAAAMOAAD 4 empname4

PostgreSQL コード:

CREATE TABLE public.testrowid_s1 ( emp_id integer, name character varying, primary key (emp_id) ); insert into public.testrowid_s1 (emp_id,name) values (1,'empname1'),(2,'empname2'),(3,'empname3'),(4,'empname4'); select emp_id,name from testrowid_s1; emp_id | name --------+---------- 1 | empname1 2 | empname2 3 | empname3 4 | empname4 update testrowid_s1 set name = 'Ramesh' where emp_id = 2 ; select emp_id,name from testrowid_s1; emp_id | name --------+---------- 1 | empname1 3 | empname3 4 | empname4 2 | Ramesh

シナリオ 2: 論理プライマリキーを使用

以下の例では、 testrowid_s2 テーブルを emp_id を配して、論理プライマリキーとして作成します。

Orackel コード:

create table testrowid_s2 (emp_id integer, name varchar2(10) ); INSERT INTO testrowid_s2(emp_id,name) values (1,'empname1'); INSERT INTO testrowid_s2(emp_id,name) values (2,'empname2'); INSERT INTO testrowid_s2(emp_id,name) values (3,'empname3'); INSERT INTO testrowid_s2(emp_id,name) values (4,'empname4'); commit; SELECT rowid,emp_id,name FROM testrowid_s2; ROWID EMP_ID NAME ------------------ ---------- ---------- AAAF3rAAAAAAAMeAAA 1 empname1 AAAF3rAAAAAAAMeAAB 2 empname2 AAAF3rAAAAAAAMeAAC 3 empname3 AAAF3rAAAAAAAMeAAD 4 empname4 UPDATE testrowid_s2 SET name = 'Ramesh' WHERE rowid = 'AAAF3rAAAAAAAMeAAB' ; commit; SELECT rowid,emp_id,name FROM testrowid_s2; ROWID EMP_ID NAME ------------------ ---------- ---------- AAAF3rAAAAAAAMeAAA 1 empname1 AAAF3rAAAAAAAMeAAB 2 Ramesh AAAF3rAAAAAAAMeAAC 3 empname3 AAAF3rAAAAAAAMeAAD 4 empname4

PostgreSQL コード:

CREATE TABLE public.testrowid_s2 ( emp_id integer, name character varying ); insert into public.testrowid_s2 (emp_id,name) values (1,'empname1'),(2,'empname2'),(3,'empname3'),(4,'empname4'); select emp_id,name from testrowid_s2; emp_id | name --------+---------- 1 | empname1 2 | empname2 3 | empname3 4 | empname4 update testrowid_s2 set name = 'Ramesh' where emp_id = 2 ; select emp_id,name from testrowid_s2; emp_id | name --------+---------- 1 | empname1 3 | empname3 4 | empname4 2 | Ramesh

シナリオ 3: アイデンティティ属性を使用

以下の例では、プライマリキーなしで、またアイデンティティ属性を使用して、テーブル testrowid_s3 を作成します。

Oracle コード:

create table testrowid_s3 (name varchar2(10)); INSERT INTO testrowid_s3(name) values ('empname1'); INSERT INTO testrowid_s3(name) values ('empname2'); INSERT INTO testrowid_s3(name) values ('empname3'); INSERT INTO testrowid_s3(name) values ('empname4'); commit; SELECT rowid,name FROM testrowid_s3; ROWID NAME ------------------ ---------- AAAF3sAAAAAAAMmAAA empname1 AAAF3sAAAAAAAMmAAB empname2 AAAF3sAAAAAAAMmAAC empname3 AAAF3sAAAAAAAMmAAD empname4 UPDATE testrowid_s3 SET name = 'Ramesh' WHERE rowid = 'AAAF3sAAAAAAAMmAAB' ; commit; SELECT rowid,name FROM testrowid_s3; ROWID NAME ------------------ ---------- AAAF3sAAAAAAAMmAAA empname1 AAAF3sAAAAAAAMmAAB Ramesh AAAF3sAAAAAAAMmAAC empname3 AAAF3sAAAAAAAMmAAD empname4

PostgreSQL コード:

CREATE TABLE public.testrowid_s3 ( rowid_seq bigint generated always as identity, name character varying ); insert into public.testrowid_s3 (name) values ('empname1'),('empname2'),('empname3'),('empname4'); select rowid_seq,name from testrowid_s3; rowid_seq | name -----------+---------- 1 | empname1 2 | empname2 3 | empname3 4 | empname4 update testrowid_s3 set name = 'Ramesh' where rowid_seq = 2 ; select rowid_seq,name from testrowid_s3; rowid_seq | name -----------+---------- 1 | empname1 3 | empname3 4 | empname4 2 | Ramesh