外部表を使用したシャード・データベースへのデータのロード

次のトピックの例およびガイドラインを使用して、外部表を作成し、外部表からシャード表または重複表にデータをロードすることで、シャード・データベースにデータをロードできます。

このデータ・ロード方法は、ロードするデータがCSVファイルなどの外部ファイルに存在する場合に便利です。

外部表は、CREATE TABLE文でORGANIZATION EXTERNALキーワードを使用して定義できます。この表は、シャードまたは重複ではなく、各シャードに対してローカルである必要があります。シャード表または重複表へのデータのロードには、外部表からの単純なINSERT … SELECT文と、シャード表のデータのサブセットのみをフィルタ処理する条件が含まれます。

ファイルのアクセス時間とサイズに基づいて、ファイルを別のホストに保存することもできます。たとえば、シャード・カタログ・ホスト上の重複表のファイルをコピーし、すべてのシャードからアクセス可能なネットワーク共有上のシャード表のファイルを保持します。ロードを高速化するために、シャード表ファイルのコピーを各シャードに保持することもできます。

外部表の詳細は、Oracle Databaseユーティリティ外部表に関する項を参照してください。

重複表へのデータのロード

重複表のデータはシャード・カタログに存在するため、重複表へのデータのロードもシャード・カタログで実行されます。ロードが完了すると、データは自動的にシャードにレプリケートされます。

次の表が重複表として定義されているとします。

CREATE DUPLICATED TABLE StockItems (
 StockNo     NUMBER(4) PRIMARY KEY,
 Description VARCHAR2(20),
 Price       NUMBER(6,2)
);

StockItems表へのデータのロードには、次のステップが必要です。

  1. データ・ファイルを含むディレクトリを指すディレクトリ・オブジェクトを作成し、このディレクトリのシャード・ユーザーにアクセス権を付与します。
    CREATE OR REPLACE DIRECTORY shard_dir AS '/path/to/datafile';
    GRANT ALL on DIRECTORY shard_dir TO uname;
  2. シャード・カタログに対してローカルで、重複表と同じ列を持つ外部表を作成します。

    シャード・カタログで、次のコマンドを実行します。

    ALTER SESSION DISABLE SHARD DDL;
    CREATE TABLE StockItems_Ext (
     StockNo     NUMBER(4) NOT NULL,
     Description VARCHAR2(20),
     Price       NUMBER(6,2)
    )
    ORGANIZATION EXTERNAL
    (TYPE ORACLE_LOADER DEFAULT DIRECTORY shard_dir
    	ACCESS PARAMETERS
    		(FIELDS TERMINATED BY ’|’ (
    		  StockNo,
    		  Description,
    		  Price)
    	)LOCATION (’StockItems.dat’)
     );
    

    この例では、重複表のデータ・ファイルの名前はStockItems.datで、列値は'|'文字で区切られます。

  3. 外部表から重複表にデータを挿入します。
    INSERT INTO StockItems  (SELECT * FROM StockItems_Ext);

    APPENDやPARALLEL (並列度)などのオプティマイザ・ヒントを使用して、システム・リソースに応じてロードを高速化することもできます。たとえば:

    ALTER SESSION ENABLE PARALLEL DML;
    INSERT /*+ APPEND PARALLEL */ INTO StockItems
      (SELECT * FROM StockItems_Ext);

    または

    ALTER SESSION ENABLE PARALLEL DML;
    INSERT /*+ APPEND PARALLEL(24) */ INTO StockItems
      (SELECT * FROM StockItems_Ext);
  4. 挿入操作をコミットします。
    COMMIT;
  5. 外部表を削除します。
    DROP TABLE StockItems_Ext;

    重複表ごとにこれらのステップを繰り返します。

シャード表へのデータのロード

シャード表のデータはシャード間でパーティション化されるため、シャード表へのデータのロードは個々のシャードで実行する必要があります。ロードは、ソース・データ・ファイルが共有されている場合でも、すべてのシャードで同時に実行できます。

ロードのプロセスは重複表のロードと似ていますが、現在のシャードに属していない行をフィルタで除外するための追加のフィルタがINSERT … SELECT文にあります。

たとえば、次のように作成されたシャード表があるとします。

CREATE SHARDED TABLE Customers (
 CustNo     NUMBER(3) NOT NULL,
 CusName    VARCHAR2(30) NOT NULL,
 Street     VARCHAR2(20) NOT NULL,
 City       VARCHAR2(20) NOT NULL,
 State      CHAR(2) NOT NULL,
 Zip        VARCHAR2(10) NOT NULL,
 Phone      VARCHAR2(12),
 CONSTRAINT RootPK PRIMARY KEY (CustNo)
)
PARTITION BY CONSISTENT HASH (CustNo)
PARTITIONS AUTO
TABLESPACE SET ts1
;

この表にデータをロードするには、各シャードで次のステップを実行します。

  1. 重複表と同じ方法でディレクトリ・オブジェクトを作成します。
  2. Customers表の外部表を作成します。
    ALTER SESSION DISABLE SHARD DDL;
    CREATE TABLE Customers_Ext (
     CustNo     NUMBER(3) NOT NULL,
     CusName    VARCHAR2(30) NOT NULL,
     Street     VARCHAR2(20) NOT NULL,
     City       VARCHAR2(20) NOT NULL,
     State      CHAR(2) NOT NULL,
     Zip        VARCHAR2(10) NOT NULL,
     Phone      VARCHAR2(12)
    )
    ORGANIZATION EXTERNAL
    (TYPE ORACLE_LOADER DEFAULT DIRECTORY shard_dir
    	ACCESS PARAMETERS
    	(FIELDS TERMINATED BY ’|’ (
    	  CustNo, CusName, Street, City, State, Zip, Phone)
    	)LOCATION (’Customers.dat’)
     );
    
  3. 外部表からシャード表にデータを挿入します。
    ALTER SESSION ENABLE PARALLEL DML;
    
    INSERT /*+ APPEND PARALLEL(24) */ INTO Customers
     (SELECT * FROM Customers_Ext WHERE
            SHARD_CHUNK_ID(’UNAME.CUSTOMERS’, CUSTNO) IS NOT NULL
      );
    

    演算子SHARD_CHUNK_IDを使用して、現在のシャードに属する行をフィルタします。この演算子は、指定されたシャーディング・キー値に対して有効なチャンク番号を戻します。この演算子のパラメータは、ルート表名(この場合はUNAME.CUSTOMERS)およびシャーディング・キー列の値です。値が現在のシャードに属していない場合、この演算子はNULLを戻します。

    この演算子は、現在のリリース(Oracle Database 21c)で導入されています。ご使用のバージョンでこの演算子を使用できない場合は、システム管理シャーディングの場合に次のようにinsert文を変更する必要があります。

    INSERT /*+ APPEND PARALLEL(24) */ INTO Customers c
     (SELECT * FROM Customers_Ext WHERE
            EXISTS (SELECT chunk_number FROM gsmadmin_internal.chunks
    			WHERE ora_hash(c.CustNo)>= low_key
    			  AND ora_hash c.CustNo)< high_key)
      );

    この問合せでは、ユーザーの内部シャーディング・メタデータを問い合せて、挿入する行の適格性を決定します。

  4. 挿入操作をコミットします。
    COMMIT;
  5. 外部表を削除します。
    DROP TABLE Customers_Ext;

外部キー制約を維持するには、ルート表から開始して表ファミリ階層を降順に、シャード表ごとに前述のステップを繰り返します。