本記事では、SQLステートメントを使用して外部テーブルを作成する方法について紹介します。また、外部テーブルを作成するための前提条件、外部テーブルの概要、注意事項などについても紹介し、いくつかの例も提供します。
外部テーブルの概要
外部テーブルは、論理的なテーブルオブジェクトを指し、その実際のデータストレージの位置はデータベース内部ではなく、外部ストレージサービスに保存されています。
外部テーブルの情報については、外部テーブルについてを参照してください。
前提条件
外部テーブルを作成する前に、以下の事項を確認する必要があります:
OceanBaseクラスタをデプロイし、Oracleモードのテナントを作成していること。OceanBaseクラスタのデプロイに関する詳細については、デプロイの概要を参照してください。
OceanBaseデータベースのOracleテナントに接続していること。データベースへの接続に関する詳細については、接続方法の概要を参照してください。
外部テーブルを作成するには、現在のユーザーが
CREATE TABLE権限を持っている必要があります。現在のユーザー権限を確認するための操作情報については、ユーザー権限の確認を参照してください。この権限を保有していない場合は、管理者に連絡して権限の付与を依頼してください。ユーザー権限の付与に関する操作情報については、直接権限付与を参照してください。
注意事項
外部テーブルはクエリ操作のみを実行でき、DML操作を実行することはできません。
外部テーブルをクエリする際に、外部テーブルがアクセスしている外部ファイルが削除されている場合、システムはエラーを報告せず、空の行を返します。
外部テーブルがアクセスするファイルは外部ストレージシステムによって管理されているため、外部ストレージが利用できない場合、外部テーブルのクエリ実行時にエラーが発生します。
外部テーブルのデータは外部データソースに保存されているため、クエリを実行する際にはネットワーク超えやファイルシステムなどの要素が関与し、クエリのパフォーマンスに影響を与える可能性があります。そのため、外部テーブルを作成する際には、適切なデータソースと最適化戦略を選択し、クエリの効率を向上させる必要があります。
コマンドラインで外部テーブルを作成する
CREATE EXTERNAL TABLE ステートメントを使用して外部テーブルを作成してください。
外部テーブル名の定義
外部テーブルを作成する際には、まず外部テーブルに名前を付ける必要があります。混乱や誤解を避けるために、外部テーブルに名前を付ける際には、通常のテーブルと外部テーブルを区別するための特定の命名ルールやプレフィックスを使用することを推奨します。例えば、外部テーブルの名前の末尾に _csv というサフィックスを付けることができます。
例:
学生情報に関する外部テーブルを作成する際には、students_csv という名前を付けることができます。
CREATE EXTERNAL TABLE students_csv external_options
注意
外部テーブルの他のプロパティが追加されていないため、上記のSQLステートメントは実行できません。
列の定義
外部テーブルの列には、DEFAULT、NOT NULL、UNIQUE、CHECK、PRIMARY KEY、FOREIGN KEY などの制約を定義することはできません。
外部テーブルでサポートされる列タイプは通常のテーブルと同じです。OceanBaseデータベースのOracleモードでサポートされているデータ型および詳細な説明については、組み込みデータ型の概要を参照してください。
LOCATIONを定義する
LOCATION オプションは、外部テーブルファイルの保存先パスを指定するために使用されます。通常、外部テーブルのデータファイルは単独のディレクトリに保存され、そのフォルダ内にはサブディレクトリを含むことができます。テーブルを作成する際、外部テーブルはそのディレクトリ内のすべてのファイルを自動的に収集します。
OceanBaseデータベースは、以下の2種類のパス形式をサポートしています:
ローカルLocation形式:
LOCATION = '[file://] local_file_path'注意
ローカルLocation形式を使用するシナリオでは、システム変数
secure_file_privを設定してアクセス可能なパスを設定する必要があります。詳細については、secure_file_privを参照してください。リモートLocationの形式は以下のとおりです:
注意
オブジェクトストレージパスを使用する際、オブジェクトストレージパスの各パラメータは
&記号で区切られます。入力するパラメータ値には英字の大文字と小文字、数字、/-_$+=およびワイルドカードのみ含まれていることを確認してください。上記以外の他の文字を入力した場合、設定が失敗する可能性があります。LOCATION = '{oss|S3}://$ACCESS_ID:$ACCESS_KEY@$HOST:s3_region/remote_file_path'の中で、$ACCESS_ID、$ACCESS_KEY、および$HOSTは、Alibaba Cloud OSS、AWS S3、およびS3プロトコルに互換性のあるオブジェクトストレージにアクセスするために必要な設定のアクセス情報です。s3_regionはS3を使用する際に選択したリージョン情報であり、これらの機密性の高いアクセス情報は暗号化された形式でデータベースのシステムテーブルに保存されます。ファイルがHDFS上にある場合、以下の形式を使用します:
単一のNameNode(NN)のアドレスを使用してクラスタにアクセスする場合の形式は:
LOCATION = hdfs://localhost:port/PATHです。ここで、localhostはHDFSのアドレスを指し、portはHDFSのポート番号を指し、PATHはHDFS内のファイルパスを指します。Kerberos認証を使用する場合の形式は:
LOCATION = 'hdfs://localhost:port/user?principal=xxx&keytab=xxx&krb5conf=xxx&configs=xxx'です。その中で:principal:認証されたログインユーザーを指します。keytab:ユーザー認証の秘密鍵ファイルを指定します。krb5conf:ユーザーがKerberos環境で使用する記述ファイルを指定します。configs:追加のHDFS構成パラメータを指定します。デフォルトは空ですが、Kerberos環境の場合、通常このパラメータには値があり、設定が必要です。例:dfs.data.transfer.protection=authentication,privacyは、データ転送の保護レベルをauthenticationとprivacyに指定します。
Hadoop HA(高可用性)の論理ネームサービスを使用してクラスタにアクセスする場合の形式は:
LOCATION = hdfs://nameserviceID/PATHです。ここで、nameserviceIDはHadoop HAの論理ネームサービスIDを指し、PATHはファイルパスを指します。説明
クライアント側のOBServerの設定にHAクラスタの
nameservice定義とフェールオーバー戦略が含まれていることを確認してください。Kerberos認証を使用する場合の形式は:
LOCATION = 'hdfs://nameserviceID/PATH?principal=xxx&keytab=xxx&krb5conf=xxx&configs=dfs.data.transfer.protection=${string}#dfs.nameservices=${nameservice id}#dfs.ha.namenodes.${nameservice id}=${namenode1}, ${namenode2}#dfs.namenode.rpc-address.${nameservice id}.${namenode1}=${namenode 1 address}#dfs.namenode.rpc-address.${nameservice id}.${namenode2}=${namenode 2 address}#dfs.ha.automatic-failover.enabled.${nameservice id}=true#dfs.client.failover.proxy.provider.${nameservice id}=org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider'です。その中で:principal:ログイン認証ユーザーを指し、非プライマリノードのNameNode (NN)のprincipalを設定します。keytabとkrb5conf:単一NameNodeの場合と同様に設定します。configs:追加のHDFS構成パラメータを指定します。複数の構成パラメータを設定する必要があり、HA構成パラメータとセキュリティ構成パラメータに関連します:dfs.data.transfer.protection=${string}:クラスタのdfs.data.transfer.protectionの設定と一致します。dfs.nameservices=${nameservice id}:現在のHAクラスタのnamesevice(エイリアス)を指定します。dfs.ha.namenodes.${nameservice id}=${namenode1}, ${namenode2}:HAクラスタのnamenodeのバックアップIDリストを指定します。dfs.namenode.rpc-address.${nameservice id}.${namenode1}=${namenode 1 address}:namenode1の具体的なnamenodeアドレスを設定し、クライアントのルーティングを容易にします。dfs.namenode.rpc-address.${nameservice id}.${namenode2}=${namenode 2 address}:namenode2の具体的なnamenodeアドレスを設定し、クライアントのルーティングを容易にします。dfs.ha.automatic-failover.enabled.${nameservice id}=true:HAクラスタが関連リクエストを受け取った際、自動的に利用可能なNameNodeにフェイルオーバーできるようにします。dfs.client.failover.proxy.provider.${nameservice id}=org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider:HAクラスタでプライマリ/スタンバイの切り替えを行うロジックツールクラスを指定します。必要に応じてカスタムクラスを作成し、HAクラスタにアップロードすることも可能です。
注意
HA関連の構成パラメータは
namespaceとバインディングされています。例えば、以下の例3のmyclusterに注意してください。関連する構成パラメータを組み合わせて設定してください。
FORMATを定義する
FORMAT = ( TYPE = 'CSV'... )は、外部ファイルのフォーマットをCSVタイプとして指定するために使用されます。以下のパラメータがあります:TYPE:外部ファイルのタイプを指定します。LINE_DELIMITER:CSVファイルの行区切り文字を指定します。デフォルト値はLINE_DELIMITER='\n'ですFIELD_DELIMITER:CSVファイルの列区切り文字を指定します。デフォルト値はFIELD_DELIMITER='\t'です。ESCAPE:CSVファイルのエスケープ文字を指定します。1バイトの文字のみ使用できます。デフォルト値はESCAPE ='\'です。FIELD_OPTIONALLY_ENCLOSED_BY:CSVファイル内のフィールド値を囲むための文字を指定します。デフォルト値は空です。注意
外部テーブルデータファイルに
NULL値(非文字列 NULL、すなわち "NULL" ではない)が含まれている場合、FIELD_OPTIONALLY_ENCLOSED_BYパラメータを明示的に設定する必要があり、そのパラメータの値は空にすることはできません。ENCODING:ファイルの文字セットエンコーディング形式を指定します。現在のOracleモードがサポートしているすべての文字セットについては、文字セットと照合順序を参照してください。指定しない場合、デフォルト値はUTF8MB4です。NULL_IF:NULLとして扱う文字列を指定します。デフォルト値は空です。SKIP_HEADER:ファイルのヘッダーをスキップし、スキップする行数を指定します。SKIP_BLANK_LINES:空白行をスキップするかどうか指定します。デフォルト値はFALSEで、空白行をスキップしないことを示します。TRIM_SPACE:ファイル内のフィールドの先頭および末尾の空白を削除するかどうか指定します。デフォルト値はFALSEで、ファイル内のフィールドの前後の空白を削除しないことを示します。EMPTY_FIELD_AS_NULL:空文字列をNULLとして扱うかどうかを指定します。デフォルト値はFALSEで、空文字列をNULLとして扱わないことを示します。
FORMAT = ( TYPE = 'PARQUET'... )は、外部ファイルのフォーマットをPARQUETタイプとして指定するために使用されます。FORMAT = ( TYPE = 'ORC'... )は、外部ファイルのフォーマットをORCタイプとして指定するために使用されます。
(オプション)PATTERNを定義する
PATTERN オプションは、LOCATION ディレクトリ内のファイルをフィルタリングするための正規表現パターン文字列を指定するために使用されます。各 LOCATION ディレクトリ内のファイルパスについて、そのパターン文字列にマッチする場合、外部テーブルはこのファイルにアクセスします。マッチしない場合、外部テーブルはこのファイルをスキップします。このパラメータを指定しない場合、デフォルトで LOCATION ディレクトリ内のすべてのファイルにアクセスできます。外部テーブルは、LOCATION で指定されたパスにある PATTERN に一致するファイルのリストをデータベースシステムのテーブルに保存します。外部テーブルをスキャンする際は、このリストに基づいて外部ファイルにアクセスします。
(オプション)外部テーブルのパーティションを定義する
外部テーブルのパーティションを自動的に定義する
外部テーブルは、パーティションキーで定義された式に基づいて、パーティションを計算して追加します。クエリを実行する際に、パーティションキーの値または範囲を指定できます。この時、パーティションプルーニングが行われ、外部テーブルはそのパーティション内のファイルのみを読み取ります。
外部テーブルのパーティションを手動で定義する
手動でパーティションを追加および削除する必要がある場合、外部テーブルにパーティションの自動管理を任せるのではなく、PARTITION_TYPE = USER_SPECIFIED フィールドを指定する必要があります。
例1
注意
例に含まれるIPアドレスに関するコマンドはマスキング処理されていますので、検証時には自分のマシンの実際のIPアドレスを記入してください。
以下は、外部ファイルがローカルおよびOceanBaseデータベースのOracleモードに存在する場合の外部テーブルを作成する例です。手順は次のとおりです:
外部ファイルを準備する。
以下のコマンドを実行して、OBServerノードにログインするマシンの
/home/admin/external_csvディレクトリ内にtest_tbl1.csvファイルを作成します。[admin@xxx /home/admin/external_csv]# vi test_tbl1.csvファイルの内容は以下のとおりです:
1,'Emma' 2,'William' 3,'Olivia'インポートファイルのパスを設定します。
注意
セキュリティ上の理由により、システム変数
secure_file_privを設定する際は、ローカルSocket接続を通じてデータベースに接続し、このグローバル変数を変更するSQLステートメントを実行する必要があります。詳細については、secure_file_privを参照してください。以下のコマンドを実行して、OBServerノードが存在するマシンにログインします。
ssh admin@10.10.10.1以下のコマンドを実行して、ローカルUnixソケット接続を介してテナント
oracle001に接続します。obclient -S /home/admin/oceanbase/run/sql.sock -usys@oracle001 -p******以下のSQLコマンドを実行し、インポートパスを
/home/admin/external_csvに設定します。SET GLOBAL secure_file_priv = "/home/admin/external_csv";
テナント
oracle001に再接続します。例:
obclient -h10.10.10.1 -P2881 -usys@oracle001 -p****** -A以下のSQLコマンドを実行して、外部テーブル
test_tbl1_csvを作成します。CREATE EXTERNAL TABLE test_tbl1_csv ( id INT, name VARCHAR(50) ) LOCATION = '/home/admin/external_csv' FORMAT = ( TYPE = 'CSV' FIELD_DELIMITER = ',' FIELD_OPTIONALLY_ENCLOSED_BY ='''' ) PATTERN = 'test_tbl1.csv';以下のSQLコマンドを実行して、外部テーブル
test_tbl1_csvのデータを確認します。SELECT * FROM test_tbl1_csv;実行結果は次のとおりです:
+------+---------+ | ID | NAME | +------+---------+ | 1 | Emma | | 2 | William | | 3 | Olivia | +------+---------+ 3 rows in set
例2
HDFSの外部テーブルを作成するには、OceanBaseデータベースをJava SDKがインストールされた環境で使用する必要があります。Java SDK環境のデプロイに関する詳細については、OceanBaseデータベースJava SDK環境のデプロイをご参照ください。
HDFS外部テーブルの作成例
Kerberosを使用する:
CREATE EXTERNAL TABLE ext_data(ID NUMBER(32), NAME VARCHAR2(30),SCORE NUMBER(32))
FORMAT = (
TYPE = 'CSV'
FIELD_DELIMITER = ','
FIELD_OPTIONALLY_ENCLOSED_BY ='"'
)
LOCATION = 'hdfs://localhost:8020/user?principal=principal_str&keytab=/path/to/keytab&krb5conf=/path/to/krb5conf_file&configs=xxx=xxx#xxx=xxx'
PATTERN = 'data.csv';
その中で:
principal:ログイン認証ユーザーを指定します。keytab:ユーザー認証の秘密鍵ファイルを指定します。krb5conf:ユーザーがKerberos環境で使用する記述ファイルを指定します。configs: 追加のHDFS構成パラメータを指定します。デフォルトは空ですが、Kerberos環境の場合、通常このパラメータには値があり、設定が必要です。例:dfs.data.transfer.protection=authentication,privacyは、データ転送の保護レベルをauthenticationとprivacyに指定します。
Kerberosを使用しない:
CREATE EXTERNAL TABLE ext_data(ID NUMBER(32), NAME VARCHAR2(30),SCORE NUMBER(32))
FORMAT = (
TYPE = 'CSV'
FIELD_DELIMITER = ','
FIELD_OPTIONALLY_ENCLOSED_BY ='"'
)
LOCATION = 'hdfs://localhost:8020/user'
PATTERN = 'test_tbl1.csv';
関連ドキュメント
外部テーブルのアクセス可能なファイルの確認と更新に関する情報については、外部ファイルの管理を参照してください。