OceanBaseは V4.3.5 BP1 から(MySQLモード/Oracleモード)、SELECT または LOAD DATA を使用してCSV、Parquet、ORC形式のファイルを直接読み取ることをサポートしています。V4.3.5 BP1 からはODPSデータソース(SOURCE() / LOAD DATA)もサポートしています。この機能は、以下の典型的なAPシナリオに適用されます:
- 一時的なデータ探索
- 迅速なデータロード
URL外部テーブルは、OceanBaseが提供する メタデータ登録不要 の外部データアクセス機能です。ユーザーは SELECT または LOAD DATA ステートメントでデータファイルのパスと形式を直接指定し、システムが動的に解析して結果を返します。事前に外部テーブルを作成する必要はありません。
対応データソースと形式
データソースタイプ |
アクセス方法 |
サポート形式 |
説明 |
|---|---|---|---|
| ローカル / オブジェクトストレージファイル | FILES() |
CSV / Parquet / ORC | HDFS、OSS、S3およびS3プロトコル互換のオブジェクトストレージ、ローカルファイルをサポートします |
| MaxCompute (ODPS) | SOURCE() |
ODPSテーブル | ODPS Tunnelに直接接続し、エクスポートは不要です |
注意
- CSVクエリ結果はデフォルトで
VARCHAR型です(後からCASTで変換可能)。 - Parquet / ORCはスキーマ(ネスト構造を含む)を自動推定します。
- 1回の読み取りはクラスタリソース、外部ストレージ、ネットワーク状況に制限されます。ドキュメントでは固定ファイル数やサイズの上限は定義されていません。
- ODPSは
FILES()をサポートしていません。SOURCE()を使用する必要があります(現在はMySQLモードのLOAD DATA構文が主です)。 - URL外部テーブル(
FILES()/ Location URL)はMySQLモードとOracleモードの両方でサポートされています。具体的な構文は各モードのSQLリファレンスを参照してください。
外部データのクエリ
汎用構文
方法1:Location URL形式(シンプル)
SELECT * FROM 'outfiles/'
(
FORMAT (TYPE = 'format_type', FIELD_DELIMITER = ','),
PATTERN = 'regex'
);
方法2:Table Function形式(柔軟、推奨)
SELECT * FROM FILES(
LOCATION = 'outfiles/',
FORMAT (TYPE = 'format_type', FIELD_DELIMITER = ','),
PATTERN = 'regex'
);
'outfiles/':外部テーブルファイルの保存パスを指定します。サブディレクトリの再帰スキャンをサポートします。FORMAT:外部ファイルの形式と解析オプションを指定するために使用します。PATTERN:正規表現パターン文字列を指定し、LOCATIONディレクトリ内のファイルをフィルタリングします。指定しない場合、デフォルトですべてのファイルを読み取ります。
各形式のクエリ例
CSVファイル
共通構文
URL外部テーブルは、CSVファイルを読み取るための2つの等価な構文形式をサポートしており、TYPE = 'CSV' を指定する必要があります。
Location URL形式(簡潔)
SELECT * FROM 'outfiles/'
(
FORMAT (
TYPE = 'CSV',
FIELD_DELIMITER = ','
),
PATTERN = 'data$'
);
Table Function形式(柔軟、推奨)
SELECT * FROM FILES(
LOCATION = 'outfiles/',
FORMAT (
TYPE = 'CSV',
FIELD_DELIMITER = ','
),
PATTERN = 'data$'
);
説明
outfiles/は外部テーブルファイルの保存パスを指定し、サブディレクトリの再帰スキャンをサポートします。
FORMATは外部ファイル形式をCSVおよび関連する解析オプションに指定するために使用されます。
PATTERNは正規表現パターン文字列を指定し、LOCATIONディレクトリ内のファイルをフィルタリングするために使用されます。指定しない場合、すべてのファイルが読み取られます。
- 重要:URL外部テーブルを使用してCSVファイルを読み取る場合、すべての列のデータ型はデフォルトでVARCHARです(後からCASTを使用して他の型に変換できます)。
LOCATION パラメータは、文字列形式のパス(例:'oss://bucket/path/'、'outfiles/')を指定することも、作成済みのLocationオブジェクト名を指定することもできます(@location_name を使用して参照します。構文は現在のバージョンのSQLリファレンスに準じます)。
例1:永続的な外部テーブルを作成し、Locationオブジェクトを参照する
長期間使用する外部テーブルのシナリオに適しており、テーブルメタデータはデータベースに保存されます。
-- まず、my_hdfs_locという名前のLocationオブジェクトを定義します
CREATE LOCATION my_hdfs_loc URL = 'hdfs://namenode:8020/data/";
-- 外部テーブル作成時にこのLocationを参照します
CREATE EXTERNAL TABLE ex_t1 (
c1 INT,
c2 INT,
c3 INT
)
LOCATION = @my_hdfs_loc
FORMAT (
TYPE = 'csv',
FIELD_DELIMITER = ',',
LINE_DELIMITER = '\n'
);
例2:一時的なクエリでFILES()を使用してLocationオブジェクトを参照する
一度限り外部ファイルを分析する場合に適しており、永続的なテーブルを作成する必要はありません。
-- Locationオブジェクトmy_hdfs_locが既に存在することを前提とします。
CREATE LOCATION my_hdfs_loc URL = 'hdfs://namenode:8020/data/";
-- FILESテーブル関数内で直接参照する
SELECT * FROM FILES(
LOCATION = @my_hdfs_loc, -- @プレフィックスを使用して定義済みのLocationを参照する
FORMAT (TYPE = 'PARQUET'),
PATTERN = '.*\\.parquet$' -- すべての.parquetファイルに一致する
);
例3:Locationオブジェクトを使用せず、パスを直接指定する
パスを再利用する必要がないシンプルなシナリオや一時的なシナリオでは、クエリ内にURLまたはパスを直接記述できます。2つの等価な構文がサポートされています。
-- 方法1:パスをテーブル名として使用する(簡潔な書き方)
SELECT * FROM '/data/'
(
FORMAT (TYPE = 'CSV', FIELD_DELIMITER = ',', SKIP_BLANK_LINES = TRUE),
PATTERN = '^datafiles.*\\.csv$' -- 注意:PATTERNは正規表現です
);
-- 方法2:FILESテーブル関数を使用する(明示的に指定し、複雑な設定に推奨)
SELECT * FROM FILES(
LOCATION = '/data/',
FORMAT (TYPE = 'CSV', FIELD_DELIMITER = ',', SKIP_BLANK_LINES = TRUE),
PATTERN = '^datafiles.*\\.csv$'
);
ヘッダー解析のサポート
FILES()関数を使用してCSVファイルにアクセスする場合、テーブル構造(列名と列数)を明示的に定義しない場合、システムは自動的にテーブル構造を推定します:
- 列数:指定ディレクトリ内のCSVファイルの最初の行をサンプリングします。
- 列名:デフォルトでは、
'c1','c2', ... の順に名付けられます。
多くのCSVファイルでは、最初の行が列名(ヘッダー)であり、後続の行がデータであるため、OceanBaseはPARSE_HEADER構成パラメータを提供しており、最初の行を列名として解析するかどうかを制御します。
- CSVファイルの最初の行が列名の場合:
PARSE_HEADER = TRUEを設定する必要があります。 - CSVファイルの最初の行が実際のデータの場合:
PARSE_HEADER = FALSE(デフォルト)のままにします。
-- 基本クエリ、CSVの最初の行がデータ(ヘッダーなし)、デフォルトの列名c1, c2を使用
SELECT * FROM FILES(
LOCATION = 'oss://my-bucket/logs/',
FORMAT (
TYPE = 'CSV',
FIELD_DELIMITER = ',',
SKIP_BLANK_LINES = TRUE
),
PATTERN = 'user_log_202504.*\\.csv$'
);
-- CSVファイルの最初の行は列名(例:name,age,city)です。PARSE_HEADERを有効にします。
SELECT * FROM FILES(
LOCATION = '/data/sales.csv',
FORMAT (
TYPE = 'CSV',
FIELD_DELIMITER = ',',
PARSE_HEADER = TRUE -- 最初の行を列名として扱う
)
);
制限事項:PARSE_HEADER と SKIP_HEADER は互斥であり、同時に使用することはできません。
Parquetファイル(スキーマの自動推定)
-- Location URL形式
SELECT * FROM 'outfiles/'
(
FORMAT (TYPE = 'PARQUET'),
PATTERN = 'data$'
);
-- Table Function形式
SELECT * FROM FILES(
LOCATION = 'outfiles/',
FORMAT (TYPE = 'PARQUET'),
PATTERN = 'data$'
);
'outfiles/'は外部テーブルファイルの保存パスを指定します。サブディレクトリの再帰スキャンをサポートします。FORMATはファイル形式をPARQUETと指定します。PATTERNはファイルのフィルタリング(正規表現によるマッチング)に使用されます。
-- 実際の例:S3上のParquetパーティションファイルを読み取る
SELECT * FROM FILES(
LOCATION = 's3://analytics-bucket/events/',
FORMAT (TYPE = 'PARQUET'),
PATTERN = 'part-.*\\.parquet$'
);
-- '/data/' パス配下で "datafiles" で始まるすべてのParquetファイルを読み取る
SELECT * FROM '/data/' (
FORMAT = (TYPE = 'PARQUET'),
PATTERN = 'datafiles$'
);
SELECT * FROM FILES(
LOCATION = '/data/',
FORMAT = (TYPE = 'PARQUET'),
PATTERN = 'datafiles$'
);
ORCファイル
-- URL Location形式
SELECT * FROM 'outfiles/'
(
FORMAT (TYPE = 'ORC'),
PATTERN = 'data$'
);
-- Table Function形式
SELECT * FROM FILES(
LOCATION = 'outfiles/',
FORMAT (TYPE = 'ORC'),
PATTERN = 'data$'
);
'outfiles/'はパスを指定するもので、サブディレクトリをサポートします。FORMATは形式をORCと指定します。PATTERNはファイルのフィルタリングに使用されます。
-- 例:HDFS上のORCファイルを読み取る
SELECT * FROM 'hdfs://mycluster/data/orc/'
(
FORMAT (TYPE = 'ORC'),
PATTERN = 'clicks_202504.*'
);
ODPSテーブル(MaxComputeへの直接接続)
ODPSデータソースはファイル形式ではないため、FILES()はサポートされず、SOURCE()のみがサポートされます。
SELECT * FROM SOURCE(
TYPE = 'ODPS',
ACCESSID = 'LTAI5tXXXXXX',
ACCESSKEY = 'xxxxxxxxxxxxxx',
ENDPOINT = 'http://service.cn-hangzhou.maxcompute.aliyun.com/api',
TUNNEL_ENDPOINT = 'http://dt.cn-hangzhou.maxcompute.aliyun.com',
PROJECT_NAME = 'sales_analytics',
TABLE_NAME = 'user_behavior'
);
外部データのインポート(LOAD DATA)
外部データをOceanBaseの内部テーブルに効率的にインポートします。並列処理や直接書き込みなどの最適化をサポートしています。
構文
LOAD DATA
[/*+ INSERT HINT */]
[REPLACE | IGNORE]
FROM {
<url_table_function_expr> |
( SELECT expression_list FROM <url_table_function_expr> )
}
INTO TABLE table_name
[PARTITION (partition_name1, [partition_name2 ...])]
[(column_name_var [, column_name_var] ...)]
ここで <url_table_function_expr> は次のとおりです:
FILES (
LOCATION = '<string>',
{
FORMAT = (
TYPE = 'CSV',
LINE_DELIMITER = '<string>' | <expr>,
FIELD_DELIMITER = '<string>' | <expr>,
ESCAPE = '<character>' | <expr>,
FIELD_OPTIONALLY_ENCLOSED_BY = '<character>' | <expr>,
ENCODING = 'charset',
NULL_IF = ('<string>' | <expr>, '<string>' | <expr> ...),
SKIP_HEADER = <int>,
SKIP_BLANK_LINES = { TRUE | FALSE },
TRIM_SPACE = { TRUE | FALSE },
EMPTY_FIELD_AS_NULL = { TRUE | FALSE }
)
| FORMAT = ( TYPE = 'PARQUET' | 'ORC' )
},
[PATTERN = '<regex_pattern>']
)
| SOURCE (
TYPE = 'ODPS',
ACCESSID = '<string>',
ACCESSKEY = '<string>',
ENDPOINT = '<string>',
TUNNEL_ENDPOINT = '<string>',
PROJECT_NAME = '<string>',
SCHEMA_NAME = '<string>',
TABLE_NAME = '<string>',
QUOTA_NAME = '<string>',
COMPRESSION_CODE = '<string>'
)
LOCATIONはファイルパスを指定し、サブディレクトリの再帰スキャンをサポートします。ローカルパス:形式は
[file:// | sfile://] local_file_pathで、secure_file_priv設定のパスのサブディレクトリである必要があります。file://:このプロトコルヘッダーは、複数のOBServerノードで同じ論理パスのファイルに遭遇した場合、それぞれ異なるファイルとして扱われ、個別に処理されることを示します。各ノードはローカルパス下のファイルを独立して読み取ります。sfile://:このプロトコルヘッダーは、複数のOBServerノードで同じ論理パスのファイルに遭遇した場合、システムが論理パスに基づいて重複処理を行い、データを1部だけ読み取ることを保証します(マルチサーバーロードバランシングをサポート)。注意
sfile://を使用する場合、システムはファイルサイズの一貫性検証を行います。同一の論理パス下のファイルが異なるOBServerノードでサイズが一致しない場合、システムはOB_INVALID_EXTERNAL_FILEエラーを返します。これは、データの不整合による結果の誤りを防ぐためです。- V4.4.2バージョンでは、V4.4.2 BP2バージョンから
LOAD DATA構文のローカルLocationパス形式にsfile://プロトコルヘッダーのサポートが追加されました。
リモートパス:例えば
oss://bucket/path/のように、機密情報(AccessKeyなど)はOceanBaseによって暗号化され、システムテーブルに保存されます。
説明
機密資格情報(AccessKeyなど)はOceanBaseによって暗号化され、システムテーブルに保存されます。事前に設定されたLocationオブジェクトを再利用することで、SQL内での繰り返し平文入力を回避できます(Location構文はSQLリファレンスに準拠してください)。
インポート例
CSVのインポート(全列または指定列)
-- data1.csvのすべての列をインポートする
LOAD DATA /*+ DIRECT(TRUE) PARALLEL(2) */
FROM FILES(
LOCATION = 'data/csv',
FORMAT = (
TYPE = 'CSV',
FIELD_DELIMITER = ',',
SKIP_BLANK_LINES = TRUE
),
PATTERN = 'data1.csv'
)
INTO TABLE csv_ex_t1;
-- ターゲットテーブルのcol1, col2にc1, c2列のみをインポートする
LOAD DATA /*+ DIRECT(TRUE) PARALLEL(2) */
FROM (
SELECT c1, c2 FROM FILES(
LOCATION = 'data/csv',
FORMAT = (
TYPE = 'CSV',
FIELD_DELIMITER = ',',
SKIP_BLANK_LINES = TRUE
),
PATTERN = 'data1.csv'
)
)
INTO TABLE csv_ex_t1 (col1, col2);
Parquetファイルのインポート
LOAD DATA /*+ DIRECT(TRUE) PARALLEL(2) */
FROM FILES(
LOCATION = 'data/parquet',
FORMAT = (TYPE = 'PARQUET'),
PATTERN = 'data1.parquet'
)
INTO TABLE parquet_ex_t1;
ORCファイルのインポート
LOAD DATA /*+ DIRECT(TRUE) PARALLEL(2) */
FROM FILES(
LOCATION = 'data/orc',
FORMAT = (TYPE = 'ORC'),
PATTERN = 'data1.orc'
)
INTO TABLE orc_ex_t1;
ODPSからのインポート
LOAD DATA
FROM SOURCE (
TYPE = 'ODPS',
ACCESSID = '$ODPS_ACCESSID',
ACCESSKEY = '$ODPS_ACCESSKEY',
ENDPOINT = '$ODPS_ENDPOINT',
PROJECT_NAME = 'example_project',
SCHEMA_NAME = '',
TABLE_NAME = 'example_table',
QUOTA_NAME = '',
COMPRESSION_CODE = ''
)
INTO TABLE odps_ex_t1;
パラメータ説明
LOCATIONパス形式
タイプ |
形式例 |
説明 |
|---|---|---|
| ローカルファイル | file://data/ または /data/ |
secure_file_priv を設定する必要があります。パスはそのサブディレクトリです。 |
| OSS | oss://bucket/path/ |
OBServerでAccessKeyを設定する必要があります。 |
| S3 | s3://bucket/path/ |
IAMロール / AccessKeyをサポートします。 |
| HDFS | hdfs://namenode:8020/path/ |
Java SDK + Kerberos(有効な場合)のデプロイが必要です。 |
CSV形式オプション(よく使われる)
パラメータ |
デフォルト値 |
説明 |
|---|---|---|
FIELD_DELIMITER |
, |
フィールド区切り文字 |
PARSE_HEADER |
FALSE |
最初の行を列名として扱うかどうか |
SKIP_BLANK_LINES |
FALSE |
空行をスキップする |
EMPTY_FIELD_AS_NULL |
FALSE |
空のフィールドをNULLに変換する |
ENCODING |
utf8 |
ファイルエンコーディング |
パフォーマンスHint(LOAD DATA専用)
/*+ DIRECT(TRUE) PARALLEL(8) */
DIRECT(TRUE): トランザクション層をバイパスし、ストレージエンジンに直接書き込みます(高速ですがロールバックできません)。PARALLEL(N): ファイルを並列読み取りします(N ≤ ファイル数)。