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外部テーブルの作成
パーティションテーブル以外
基本構文(自動列マッピング)
-- ステップ1:MaxCompute上にテーブルt1が存在する
-- CREATE TABLE IF NOT EXISTS odps_project.t1 (c1 INT, c2 INT);
-- ステップ2: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...と自動的にマッピングします。
明示的な列マッピング(推奨)
-- ステップ1:MaxCompute上にテーブルt1が存在する
-- CREATE TABLE IF NOT EXISTS odps_project.t1 (c1 INT, c2 INT);
-- ステップ2: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テーブルのパーティション構造と一致している必要があります。
-- ステップ1: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));
-- ステップ2: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外部テーブルのパーティション列は、一対一で対応し、数も一致している必要があります。
エラー例:
AS (metadata$partition_list_colX) を省略した場合、パーティション列は通常の列として処理され、クエリが失敗します。
-- ステップ1: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));
-- ステップ2:誤った書き方:パーティション列に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データにアクセスする場合、通常のテーブルをクエリする際と同じ構文を使用します。
-- ステップ1:MaxCompute上にテーブルt1が存在します
-- CREATE TABLE IF NOT EXISTS odps_project.t1 (c1 INT, c2 INT);
-- ステップ2: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"},
);
-- ステップ3:外部テーブル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モードでのデータ挿入を参照してください。
パーティションテーブル以外のエクスポート
-- ステップ1:MaxComputeにテーブルt1が存在する
-- CREATE TABLE IF NOT EXISTS odps_project.t1 (c1 INT, c2 INT);
-- ステップ2: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"},
);
-- ステップ3:OceanBaseに通常のテーブルt1_を作成
CREATE TABLE t1_ (c1 INT, c2 INT);
-- ステップ4:外部テーブルから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を挿入
パーティションテーブルのエクスポート
-- ステップ1: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));
-- ステップ2: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);
-- ステップ3:OceanBaseに通常のテーブルt2_を作成
CREATE TABLE t2_ (c1 INT, c2 INT);
-- ステップ4:指定されたパーティションにデータをエクスポート
-- 注意: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)を使用するようにしてください。