Amazon Aurora PostgreSQL および Amazon RDS for PostgreSQL で Oracle PL/SQL 連想配列をエミュレートする - AWS 規範ガイダンス

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

Amazon Aurora PostgreSQL および Amazon RDS for PostgreSQL で Oracle PL/SQL 連想配列をエミュレートする

Amazon Web Services、Rajkumar Raghuwanshi、Bhanu Ganesh Gudivada、Sachin Khanna

概要

このパターンでは、Amazon Aurora PostgreSQL および Amazon RDS for PostgreSQL 環境で、空のインデックス位置を持つ Oracle PL/SQL 連想配列をエミュレートする方法について説明します。また、それぞれが移行中に空のインデックス位置を処理する方法に関して、Oracle PL/SQL 連想配列と PostgreSQL 配列の違いについても説明します。

PostgreSQL は、Oracle データベースの移行時に aws_oracle_ext 関数により空のインデックス位置を処理する操作の代わりに使用できるものです。このパターンでは、追加の列を使用してインデックス位置を保存し、ネイティブ PostgreSQL 機能を組み込みながら、Oracle によるスパース配列の処理を維持します。

Oracle

Oracle では、コレクションを空として初期化し、配列に NULL 要素を追加する EXTEND コレクションメソッドを使用して入力できます。PLS_INTEGER によってインデックス付けされた PL/SQL 連想配列を使用する場合、EXTEND メソッドでは NULL 要素が連続で追加されますが、要素は非連続のインデックス位置で初期化することもできます。明示的に初期化されていないインデックス位置は空のままとなります。

この柔軟性により、要素を任意の位置に入力できるスパース配列構造が可能になります。FIRST および LAST 境界と一緒に FOR LOOP を使用してコレクションを反復処理する場合、初期化された要素 (NULL または値を定義) のみが処理され、空の位置はスキップされます。

PostgreSQL (Amazon Aurora および Amazon RDS)

PostgreSQL は、空の値を NULL 値とは異なる方法で処理します。空の値は、1 バイトのストレージを使用する個別のエンティティとして保存されます。配列に空の値がある場合、PostgreSQL は空でない値と同様にシーケンシャルインデックス位置を割り当てます。ただし、シーケンシャルインデックス作成には追加の処理が必要です。システムでは、空の位置を含むすべてのインデックス付き位置を反復処理する必要があるためです。これにより、従来の配列の作成はスパースデータセットでは非効率になります。

AWS Schema Conversion Tool

AWS Schema Conversion Tool (AWS SCT) は通常、aws_oracle_ext 関数を使用して Oracle から PostgreSQL への移行を処理します。このパターンでは、ネイティブ PostgreSQL 機能を使用する代替アプローチを提案します。これは、PostgreSQL 配列タイプと追加の列を組み合わせてインデックス位置を保存するものです。システムでは、インデックス列のみを使用して配列を反復処理できるようになります。

前提条件と制限

前提条件

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

  • 管理者権限を持つ AWS Identity and Access Management (IAM) ユーザー。

  • Amazon RDS または Aurora PostgreSQL 互換のインスタンス。

  • リレーショナルデータベースの基本的な理解。

制限事項

  • 一部の AWS のサービス は、すべてで利用できるわけではありません AWS リージョン。利用可能なリージョンについては、「AWS のサービス (リージョン別)」を参照してください。特定のエンドポイントについては、「Service endpoints and quotas」ページから、サービスのリンクを選択してご確認ください。

製品バージョン

このパターンは次のバージョンでテスト済みです。

  • Amazon Aurora PostgreSQL 13.3

  • Amazon RDS for PostgreSQL 13.3

  • AWS SCT 1.0.674

  • Oracle 12c EE 12.2

アーキテクチャ

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

  • オンプレミスの Oracle データベース

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

  • Amazon Aurora PostgreSQL

  • Amazon RDS for PostgreSQL

ターゲットアーキテクチャ

図に示す内容は以下のとおりです。

  • ソース Amazon RDS for Oracle データベースインスタンス

  • Oracle 関数を PostgreSQL に相当する関数に変換 AWS SCT するための を備えた Amazon EC2 インスタンス

  • Amazon Aurora PostgreSQL と互換性のあるターゲットデータベース

ツール

AWS サービス

  • Amazon Aurora」はクラウド用に構築されたフルマネージド型のリレーショナルデータベースエンジンで、MySQL および PostgreSQL と互換性があります。

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

  • Amazon Elastic Compute Cloud (Amazon EC2) は、 AWS クラウドでスケーラブルなコンピューティング容量を提供します。仮想サーバーを必要な数だけ起動して、迅速にスケールアップまたはスケールダウンができます。

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

  • Oracle 向け Amazon Relational Database Service (Amazon RDS) を使用すると、 AWS クラウドで Oracle リレーショナルデータベースをセットアップ、運用、スケールできます。

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

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

その他のツール

  • Oracle SQL Developer は、従来のデプロイとクラウドベースのデプロイの両方で Oracle データベースの開発と管理を簡素化する統合開発環境です。

  • pgAdmin」 は PostgreSQL 用のオープンソース管理ツールです。データベースオブジェクトの作成、管理、使用を支援するグラフィカルインターフェイスを提供します。このパターンでは、pgAdmin は RDS for PostgreSQL データベースインスタンスに接続し、データをクエリします。または、psql コマンドラインクライアントを使用することもできます。

ベストプラクティス

  • データセットの境界とエッジシナリオをテストします。

  • 範囲外のインデックス条件にエラー処理を実装することを検討してください。

  • スパースデータセットのスキャンを避けるためにクエリを最適化します。

エピック

タスク説明必要なスキル

Oracle でソース PL/SQL ブロックを作成する。

次の連想配列を使用するソース PL/SQL ブロックを Oracle で作成します。

DECLARE TYPE country_codes IS TABLE OF VARCHAR2(100) INDEX BY pls_integer; cc country_codes; cc_idx NUMBER := NULL; BEGIN cc(7) := 'India'; cc(3) := 'UK'; cc(5) := 'USA'; cc(0) := 'China'; cc(-2) := 'Invalid'; dbms_output.put_line('cc_length:' || cc.COUNT); IF (cc.COUNT > 0) THEN cc_idx := cc.FIRST; FOR i IN 1..cc.COUNT LOOP dbms_output.put_line('cc_idx:' || cc_idx || ' country:' || cc(cc_idx)); cc_idx := cc.next(cc_idx); END LOOP; END IF; END;
DBA

PL/SQL ブロックを実行する。

Oracle でソース PL/SQL ブロックを実行します。連想配列のインデックス値の間にギャップがある場合、そのギャップにはデータが保存されません。そのため、Oracle ループはインデックス位置を介してのみイテレーションできます。

DBA

出力の確認

非連続の間隔で 5 つの要素が配列 (cc) に挿入されました。配列数を次の出力に示します。

cc_length:5 cc_idx:-2 country:Invalid cc_idx:0 country:China cc_idx:3 country:UK cc_idx:5 country:USA cc_idx:7 country:India
DBA
タスク説明必要なスキル

PostgreSQL でターゲット PL/pgSQL ブロックを作成する。

次の連想配列を使用するターゲット PL/pgSQL ブロックを PostgreSQL で作成します。

DO $$ DECLARE cc character varying(100)[]; cc_idx integer := NULL; BEGIN cc[7] := 'India'; cc[3] := 'UK'; cc[5] := 'USA'; cc[0] := 'China'; cc[-2] := 'Invalid'; RAISE NOTICE 'cc_length: %', ARRAY_LENGTH(cc, 1); IF (ARRAY_LENGTH(cc, 1) > 0) THEN FOR i IN ARRAY_LOWER(cc, 1)..ARRAY_UPPER(cc, 1) LOOP RAISE NOTICE 'cc_idx:% country:%', i, cc[i]; END LOOP; END IF; END; $$;
DBA

PL/pgSQL ブロックを実行する。

ターゲット PL/pgSQL ブロックを PostgreSQL で実行します。連想配列のインデックス値の間にギャップがある場合、そのギャップにはデータが保存されません。そのため、Oracle ループはインデックス位置を介してのみイテレーションできます。

DBA

出力の確認

インデックス位置間のギャップには NULL が保存されるため、配列の長さは 5 を超えています。次の出力に示すように、ループは 10 回のイテレーションを完了して、配列内の 5 つの値を取得します。

cc_length:10 cc_idx:-2 country:Invalid cc_idx:-1 country:<NULL> cc_idx:0 country:China cc_idx:1 country:<NULL> cc_idx:2 country:<NULL> cc_idx:3 country:UK cc_idx:4 country:<NULL> cc_idx:5 country:USA cc_idx:6 country:<NULL> cc_idx:7 country:India
DBA
タスク説明必要なスキル

配列とユーザー定義型を使用してターゲット PL/pgSQL ブロックを作成する。

パフォーマンスを最適化し、Oracle の機能に合わせるには、インデックス位置と対応するデータの両方を保存するユーザー定義型を作成します。このアプローチでは、インデックスと値との直接的な関連付けを維持することにより、不要なイテレーションを減らします。

DO $$ DECLARE cc country_codes[]; cc_append country_codes := NULL; i record; BEGIN cc_append.idx = 7; cc_append.val = 'India'; cc := array_append(cc, cc_append); cc_append.idx = 3; cc_append.val = 'UK'; cc := array_append(cc, cc_append); cc_append.idx = 5; cc_append.val = 'USA'; cc := array_append(cc, cc_append); cc_append.idx = 0; cc_append.val = 'China'; cc := array_append(cc, cc_append); cc_append.idx = - 2; cc_append.val = 'Invalid'; cc := array_append(cc, cc_append); RAISE NOTICE 'cc_length: %', ARRAY_LENGTH(cc, 1); IF (ARRAY_LENGTH(cc, 1) > 0) THEN FOR i IN ( SELECT * FROM unnest(cc) ORDER BY idx) LOOP RAISE NOTICE 'cc_idx:% country:%', i.idx, i.val; END LOOP; END IF; END; $$;
DBA

PL/pgSQL ブロックを実行する。

ターゲット PL/pgSQL ブロックを実行します。連想配列のインデックス値の間にギャップがある場合、そのギャップにはデータが保存されません。そのため、Oracle ループはインデックス位置を介してのみイテレーションできます。

DBA

出力の確認

次の出力に示すように、ユーザー定義型には、入力されたデータ要素のみが保存されます。そのため、配列の長さは値の数と一致します。その結果、LOOP イテレーションは存在するデータのみを処理するように最適化されるため、空の位置を追跡する必要はありません。

cc_length:5 cc_idx:-2 country:Invalid cc_idx:0 country:China cc_idx:3 country:UK cc_idx:5 country:USA cc_idx:7 country:India
DBA

関連リソース

AWS ドキュメント

その他のドキュメント