MaxCompute(ODPS)は、2種類のデータアクセスインターフェースを提供しています:
- Storage API:データサービスインターフェースで、効率的で低遅延、安全なデータ読み取り機能を提供します。
- Tunnel API:データのアップロード/ダウンロードインターフェースで、主にテーブルデータのバッチ操作(例:テーブル全体のインポートとエクスポート)に使用されます。
OceanBaseデータベースは、V4.4.0以降のバージョン(MySQLモード)から、ODPS APIに対応し、外部テーブルを通じてMaxComputeテーブルへのアクセスをサポートしています。
ODPS外部テーブルを作成することで、Alibaba Cloud MaxCompute(旧ODPS)テーブルに対する透過的な読み書きが実現され、データ移行を行わずにシステム間の連携分析、リアルタイムレポート作成、データのフィードバックが可能になります。
ODPS外部テーブルを作成する際、OceanBaseはStorage APIとTunnel APIのパラメータ設定オプションを提供しています。具体的な使用方法については、CREATE EXTERNAL TABLEを参照してください。2つのAPIの選択については、次の表のように推奨されます:
比較項目 |
Storage API |
Tunnel API |
適用シナリオ |
|---|---|---|---|
| 特長 | 細かい粒度でのデータアクセスをサポートします(パーティションフィルタリングや述語プッシュダウンなど)。 | 全テーブルデータの効率的なインポート/エクスポートに特化しており、無条件フィルタリングが可能です。 | HTAPハイブリッドワークロード、パーティションテーブルの条件検索、計算エンジン(Sparkなど)との密接な連携。 |
| シャーディング戦略 | 自動シャーディング:バイト単位または行数に基づいてタスクを動的に分割し、並列処理の効率を向上させます。 | 手動シャーディング:開発者がパーティションサイズや行数を計算し、設定が複雑です。Storage APIに比べてパフォーマンスが低く、ODPSのリソース構成に特別な要件はなく、すべてのODPS構成仕様と互換性があります。 |
|
| パフォーマンス最適化 | 低リソース消費:述語プッシュダウンにより転送データ量が削減され、計算がデータベース側にプッシュダウンされるため、クエリ速度が向上します。 | 高リソース消費:全量転送は大量の帯域幅とストレージを消費する可能性があります。 | 転送データ量を削減し、HTAPの効率を向上させる必要がある場合はStorage APIを選択します。簡単なETLや全量バックアップにはTunnel APIを選択します。 |
| データフィルタリング機能 | サポート:SQL条件(WHEREなど)によりデータをフィルタリングし、必要な部分のみを転送します。 | 不可:全量転送後にローカルでフィルタリングする必要があります。 | 条件に基づいてデータをフィルタリングする必要がある場合(特定ユーザーの行動分析など)、Storage APIを選択します。 |
機能概要
機能 |
説明 |
|---|---|
| 読み取り専用クエリ | SELECT * FROM odps_external_table |
| パーティションサポート | 非パーティションテーブルとパーティションテーブル(動的パーティションの識別を含む)をサポートします |
| 列マッピング | MaxCompute列への自動または明示的なバインド |
| パーティションの自動更新 | IMMEDIATE / INTERVAL / OFF の3種類の同期ポリシーをサポートします |
| 制限 |
|
ODPS外部テーブルの作成
非パーティションテーブル
基本構文(自動列マッピング)
-- step1: MaxComputeにはテーブルt1が存在します
-- CREATE TABLE IF NOT EXISTS odps_project.t1 (c1 INT, c2 INT);
-- step2: OBが外部テーブルt1を作成
CREATE EXTERNAL TABLE t1 (c1 INT, c2 INT)
PROPERTIES = (
TYPE = 'ODPS',
ACCESSID = '*****',
ACCESSKEY = '*****',
ENDPOINT = 'http://service.cn-hangzhou.maxcompute.aliyun.com/api',
PROJECT_NAME = 'odps_project',
SCHEMA_NAME = '',
TABLE_NAME = 't1',
QUOTA_NAME = '',
COMPRESSION_CODE = ''
API_MODE = {"tunnel_api"},
);
説明
生成列を指定しない場合、OceanBaseは定義順に従って自動的にexternal$tablecol1, external$tablecol2...とマッピングします。
明示的な列マッピング(推奨)
-- step1: MaxComputeにはテーブルt1が存在します
-- CREATE TABLE IF NOT EXISTS odps_project.t1 (c1 INT, c2 INT);
-- step2: OBが外部テーブルt1を作成
CREATE EXTERNAL TABLE t1 (
c1 INT AS (external$tablecol1),
c2 INT AS (external$tablecol2)
)
PROPERTIES = (
TYPE = 'ODPS',
ACCESSID = '*****',
ACCESSKEY = '*****',
ENDPOINT = 'http://service.cn-hangzhou.maxcompute.aliyun.com/api',
PROJECT_NAME = 'odps_project',
SCHEMA_NAME = '',
TABLE_NAME = 't1',
QUOTA_NAME = '',
COMPRESSION_CODE = 'lz4'
API_MODE = {"tunnel_api"},
);
説明
- 通常の列
AS (external$tablecolx)は、ODPSのt1テーブルにマッピングするx番目の列を指定するために使用されます(この列は通常の列でなければならず、パーティション列ではありません)。開始番号は1です。
- 例1のように生成列を指定しない場合、デフォルトで生成列が作成され、番号は列の定義順に従って1から連番が付けられます。
パーティションテーブル
重要なルール:
- パーティション列は
metadata$partition_list_colXを使用して明示的に宣言する必要があります。 PARTITION BY句は、MaxCompute テーブルのパーティション構造と一致している必要があります。
-- step1: MaxCompute 上にはパーティションテーブル t2 があり、c1 と c2 は通常列、c3 と c4 はパーティション列です
-- CREATE TABLE IF NOT EXISTS odps_project.t2 (c1 INT, c2 INT) PARTITIONED BY (c3 VARCHAR(20), c4 VARCHAR(20));
-- step2: OB でパーティション外部テーブル t2 を作成
CREATE EXTERNAL TABLE t2 (
c1 INT,
c2 INT,
c3 VARCHAR(20) AS (metadata$partition_list_col1),
c4 VARCHAR(20) AS (metadata$partition_list_col2)
)
PROPERTIES = (
TYPE = 'ODPS',
ACCESSID = '*****',
ACCESSKEY = '*****',
ENDPOINT = 'http://service.cn-hangzhou.maxcompute.aliyun.com/api',
PROJECT_NAME = 'odps_project',
SCHEMA_NAME = '',
TABLE_NAME = 't2',
QUOTA_NAME = '',
COMPRESSION_CODE = ''
API_MODE = {"tunnel_api"},
)
PARTITION BY (c3, c4);
説明
- パーティション列 AS (metadata$partition_list_colx) は、ODPS の t2 テーブルの x 番目のパーティション列にマッピングする列を指定します。開始番号は 1 です。
- パーティション列
AS (metadata$partition_list_colx)は省略できません。省略した場合、通常列として処理され、予期しないエラーが発生します。
- MaxCompute テーブルのパーティション列と OceanBase 外部テーブルのパーティション列は、1対1で対応し、数も一致している必要があります。
エラー例:
AS (metadata$partition_list_colX) を省略すると、パーティション列は通常列として処理され、クエリが失敗します。
-- step1: MaxCompute 上にはパーティションテーブル t2 があり、c1 と c2 は通常列、c3 と c4 はパーティション列です
-- CREATE TABLE IF NOT EXISTS odps_project.t2 (c1 INT, c2 INT) PARTITIONED BY (c3 VARCHAR(20), c4 VARCHAR(20));
-- step2: エラー:パーティション列で metadata$partition_list_colX を使用していない
CREATE EXTERNAL TABLE t2 (
c1 INT,
c2 INT,
c3 VARCHAR(20), -- ⚠️ AS (metadata$partition_list_col1) が欠落
c4 VARCHAR(20) -- ⚠️ AS (metadata$partition_list_col2) が欠落
)
PROPERTIES = (
TYPE = 'ODPS',
ACCESSID = '*****',
ACCESSKEY = '*****',
ENDPOINT = 'http://service.cn-hangzhou.maxcompute.aliyun.com/api',
PROJECT_NAME = 'odps_project',
SCHEMA_NAME = '',
TABLE_NAME = 't2',
QUOTA_NAME = '',
COMPRESSION_CODE = ''
API_MODE = {"tunnel_api"},
)
PARTITION BY (c3, c4); -- パーティションは宣言されていますが、列にパーティションメタデータのマッピングがありません
c3 と c4 が MaxCompute の実際のパーティション値にバインドされていないため、OceanBase はパーティション情報を取得できません。したがって、パーティション列は必ず metadata$partition_list_colX を使用して明示的にマッピングする必要があります。
説明
通常列の生成列は、明示的に指定することも、指定しないこともでき、非パーティション外部テーブルと同じです。
主要パラメータ説明 (PROPERTIES)
パラメータ |
必須 |
説明 |
|---|---|---|
| TYPE | はい | ODPSに固定されます。 |
| ACCESSID / ACCESSKEY | はい | RAMユーザーのAccessKey(最小権限を推奨します) |
| ENDPOINT | はい | MaxComputeサービスのアドレス(リージョンを含む) |
| PROJECT_NAME | はい | MaxComputeプロジェクト名 |
| TABLE_NAME | はい | テーブル名 |
| SCHEMA_NAME | いいえ | テーブルがスキーマ内にある場合は指定する必要があります |
| ACCESSTYPE | いいえ | アカウントタイプ:aliyun(デフォルト)/ sts / app |
| STSTOKEN | 条件 | ACCESSTYPE = 'sts' の場合のみ必須 |
| QUOTA_NAME | いいえ | コンピューティングリソースのクォータを指定します |
| COMPRESSION_CODE | いいえ | 圧縮形式:zlib / zstd / lz4 / odps_lz4 |
MaxComputeデータのクエリ
外部テーブルを通じてMaxComputeデータにアクセスする構文は、通常のテーブルをクエリする構文と同じです。
-- step1: MaxComputeにはテーブルt1が存在します
-- CREATE TABLE IF NOT EXISTS odps_project.t1 (c1 INT, c2 INT);
-- step2: OBが外部テーブルt1を作成
CREATE EXTERNAL TABLE t1 (c1 INT, c2 INT)
PROPERTIES = (
TYPE = 'ODPS',
ACCESSID = '*****',
ACCESSKEY = '*****',
ENDPOINT = 'http://service.cn-hangzhou.maxcompute.aliyun.com/api',
PROJECT_NAME = 'odps_project',
SCHEMA_NAME = '',
TABLE_NAME = 't1',
QUOTA_NAME = '',
COMPRESSION_CODE = ''
API_MODE = {"tunnel_api"},
);
-- step3: 外部テーブルt1に対応するMaxComputeのテーブルt1のデータを確認する
SELECT * FROM t1;
-- パラレル度Nで読み取り速度を向上
SELECT /*+ PARALLEL(N) */ * FROM t1;
データのMaxComputeへのエクスポート
OceanBaseは、標準SQLを使用して内部テーブルのデータをMaxCompute(ODPS)の外部テーブルに書き込み、データのエクスポートを実現します。
-- 上書き書き込み(フル更新用)
INSERT OVERWRITE external_table_name
SELECT column_list FROM source_table [WHERE ...];
-- 追加書き込み(増分インポート用)
INSERT INTO external_table_name
SELECT column_list FROM source_table [WHERE ...];
external_table_name:作成済みのMaxCompute外部テーブル。source_table:OceanBaseの内部テーブルまたはその他のクエリ可能なオブジェクト。
詳細については、MySQLモードでのデータ挿入およびOracleモードでのデータ挿入を参照してください。
非パーティションテーブルのエクスポート
-- step1: MaxComputeにテーブルt1があります
-- CREATE TABLE IF NOT EXISTS odps_project.t1 (c1 INT, c2 INT);
-- step2: OceanBaseが外部テーブルt1を作成します
CREATE EXTERNAL TABLE t1 (c1 INT, c2 INT)
PROPERTIES = (
TYPE = 'ODPS',
ACCESSID = '*****',
ACCESSKEY = '*****',
ENDPOINT = 'http://service.cn-hangzhou.maxcompute.aliyun.com/api',
PROJECT_NAME = 'odps_project',
SCHEMA_NAME = '',
TABLE_NAME = 't1',
QUOTA_NAME = '',
COMPRESSION_CODE = ''
API_MODE = {"tunnel_api"},
);
-- step3: OceanBaseが通常テーブルt1_を作成します
CREATE TABLE t1_ (c1 INT, c2 INT);
-- step4: 外部テーブルからMaxComputeへエクスポート
INSERT INTO t1 SELECT * FROM t1_;
-- パラレル度Nでエクスポート速度を向上
INSERT /*+ PARALLEL(N) */ INTO t1 SELECT * FROM t1_;
-- OVERWRITEを指定すると既存データが上書きされます。t1_テーブルが空の場合、t1も空に上書きされます
INSERT OVERWRITE t1 SELECT * FROM t1_;
-- 指定して挿入する列
INSERT INTO t1 (c1) SELECT c1 FROM t1_; -- c2列にNULLを挿入
パーティションテーブルのエクスポート
-- step1: MaxComputeにパーティションテーブルt2があります。c1とc2は通常列、c3とc4はパーティション列です
-- CREATE TABLE IF NOT EXISTS odps_project.t2 (c1 INT, c2 INT) PARTITIONED BY (c3 VARCHAR(20), c4 VARCHAR(20));
-- step2: OceanBaseがパーティション外部テーブルt2を作成します
CREATE EXTERNAL TABLE t2 (
c1 INT AS (metadata$odpscol1),
c2 INT AS (metadata$odpscol2),
c3 VARCHAR(20) AS (metadata$partition_list_col1),
c4 VARCHAR(20) AS (metadata$partition_list_col2)
)
PROPERTIES = (
TYPE = 'ODPS',
ACCESSID = '*****',
ACCESSKEY = '*****',
ENDPOINT = 'http://service.cn-hangzhou.maxcompute.aliyun.com/api',
PROJECT_NAME = 'odps_project',
SCHEMA_NAME = '',
TABLE_NAME = 't2',
QUOTA_NAME = '',
COMPRESSION_CODE = ''
API_MODE = {"tunnel_api"},
)
PARTITION BY (c3, c4);
-- step3: OceanBaseが通常テーブルt2_を作成します
CREATE TABLE t2_ (c1 INT, c2 INT);
-- step4: 指定したパーティションにデータをエクスポート
-- 注意:V4.3.5 BP2以降のバージョンでは、MaxComputeテーブルに存在しないパーティションを自動作成する機能がサポートされており、事前に手動で作成する必要はありません。このバージョンより前のOceanBaseではこの機能はサポートされていないため、事前にMaxComputeテーブルに対象パーティションを明示的に作成する必要があります。
INSERT INTO t2 PARTITION (c3 = 'abc', c4 = 'def') SELECT * FROM t2_;
INSERT OVERWRITE t2 PARTITION (c3 = 'abc', c4 = 'def') SELECT * FROM t2_;
パーティション情報の同期ポリシー
AUTO_REFRESH を使用して、MaxComputeのパーティションメタデータのリフレッシュ方法を制御します。 AUTO_REFRESH = { IMMEDIATE | OFF | INTERVAL }
ポリシー |
説明 |
適用シナリオ |
|---|---|---|
IMMEDIATE |
各クエリ時に自動的にリフレッシュする | パーティションの頻繁な変更(例:1時間ごと) |
OFF |
手動でのみリフレッシュ可能。使用方法:ALTER EXTERNAL TABLE <table_name> REFRESH; |
静的パーティションテーブル |
INTERVAL |
DBMS_EXTERNAL_TABLE_AUTO_REFRESH_EXTERNAL_TABLE(x) を使用して、秒単位で定期的なタスクリフレッシュを設定する |
中程度の頻度での更新 |
即時リフレッシュを有効にする例
CREATE EXTERNAL TABLE t2 (
c1 INT AS (metadata$odpscol1),
c2 INT AS (metadata$odpscol2),
c3 VARCHAR(20) AS (metadata$partition_list_col1),
c4 VARCHAR(20) AS (metadata$partition_list_col2)
)
AUTO_REFRESH = IMMEDIATE
PROPERTIES = (
TYPE = 'ODPS',
ACCESSID = '*****',
ACCESSKEY = '*****',
ENDPOINT = 'http://service.cn-hangzhou.maxcompute.aliyun.com/api',
PROJECT_NAME = 'odps_project',
SCHEMA_NAME = '',
TABLE_NAME = 't2',
QUOTA_NAME = '',
COMPRESSION_CODE = ''
API_MODE = {"tunnel_api"},
)
PARTITION BY (c3, c4);
手動リフレッシュコマンド(AUTO_REFRESH = OFF の場合に使用)
ALTER EXTERNAL TABLE t2 REFRESH;
データ型とタイムゾーン
型のマッピング
- 詳細なマッピングについては、OceanBaseとMaxComputeのデータ型対照表を参照してください。
タイムゾーン処理
- MaxComputeの時間型(例:
DATETIME)には明示的なタイムゾーン情報がありません。 - OceanBaseは、デフォルトでそれを自身のタイムゾーンと一致するものと見なします。
- 推奨事項:OceanBaseとMaxComputeで同じタイムゾーン(例:
Asia/Shanghai)を使用するようにしてください。