首批通过分布式安全可靠测评,为关键业务系统打造
ODPS 外部表
更新时间:2026-07-02 18:41:33
OceanBase 数据库自 V4.3.5 BP1 起(MySQL 模式),支持通过 CREATE EXTERNAL TABLE 创建 ODPS 外部表,访问阿里云 MaxCompute(原 ODPS)中的表数据(默认使用 Tunnel API)。
与 文件外部表 不同,ODPS 外部表不通过 LOCATION 指向文件路径,而是通过 MaxCompute API 连接远端 ODPS 项目中的表。OceanBase 在本地保存外表定义与列映射,查询或写入时调用 ODPS Storage API 或 Tunnel API 与 MaxCompute 交互。
说明
若需访问整个 MaxCompute 项目下的多张表且无需逐表建外表,可使用 ODPS Catalog。本文介绍单表级别的 ODPS 外部表。
功能简介
MaxCompute 提供两类与 OceanBase 集成的数据访问接口:
| API | 用途 | 主要特点 |
|---|---|---|
| Storage API | 数据服务接口 | 支持分区过滤、谓词下推等细粒度访问 |
| Tunnel API | 数据上传/下载接口 | 面向批量全表导入导出,无服务端过滤能力 |
创建 ODPS 外部表时,通过 PROPERTIES 中的 API_MODE 指定使用的 API。两种 API 的对比如下:
| 维度 | Storage API | Tunnel API |
|---|---|---|
| 数据过滤 | 支持通过 SQL 条件过滤,仅传输所需数据 | 不支持服务端过滤,需全量传输 |
| 分片策略 | 自动分片(按字节或行数) | 手动分片,配置相对复杂 |
| 网络要求 | 需与 MaxCompute 部署在同一 VPC,并开通 Storage API 权限 | 无特殊 VPC 要求 |
| 适用场景 | 分区表条件查询、需减少传输数据量的分析场景 | 未开通 Storage API 或兼容性场景 |
支持的操作
| 操作 | 支持情况 |
|---|---|
SELECT 查询 |
支持 |
INSERT INTO / INSERT OVERWRITE |
支持 |
| 非分区表与分区表 | 支持 |
| 动态分区识别 | 支持(需配置 AUTO_REFRESH) |
UPDATE / DELETE |
不支持 |
前提条件
- 版本与模式:OceanBase V4.3.5 BP1 及以上(MySQL 模式租户)。使用
API_MODE = 'storage_api'或SPLIT时需 V4.3.5 BP3 及以上。 - Java 环境:MaxCompute SDK 基于 Java,需部署 Java SDK 环境,参见 部署 OceanBase 数据库 JAVA SDK 环境。
- MaxCompute 凭证:
- RAM 用户的 AccessKey ID / AccessKey Secret(建议最小权限)
- MaxCompute 服务 Endpoint(含地域信息)
- 使用 Storage API 时,需在同一 VPC 内且已开通 Storage API 权限
- 表权限:RAM 用户对目标 MaxCompute 项目及表具备相应读写权限。
ODPS 外表访问模型
ODPS 外部表的访问链路如下:
| 组件 | 作用 |
|---|---|
| OceanBase 外表定义 | 保存列映射、分区定义及 ODPS 连接参数 |
| MaxCompute API | Storage API 或 Tunnel API,负责与 MaxCompute 服务端通信 |
| MaxCompute 表 | 远端实际存储数据的表(非文件路径外表) |
OceanBase 不缓存 MaxCompute 表的全量数据。查询时通过 API 拉取所需数据;写入时通过 API 将数据写入 MaxCompute 表。
创建 ODPS 外部表
非分区表
自动列映射
未指定生成列时,OceanBase 按列定义顺序映射为 external$tablecol1、external$tablecol2 等。
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"}
);
显式列映射(推荐)
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) 用于指定映射到 MaxCompute 表的第 x 列普通列(非分区列),序号从 1 开始。若未指定生成列,则按列定义顺序自动递增编号。
分区表
分区列须使用 metadata$partition_list_colX 显式声明,且 PARTITION BY 子句须与 MaxCompute 表分区结构一致。
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);
说明
metadata$partition_list_colx用于映射 MaxCompute 表的第 x 个分区列,序号从 1 开始,不可省略。- MaxCompute 表的分区列与 OceanBase 外表的分区列须一一对应,个数一致。
错误示例:分区列未使用 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 ( ... )
PARTITION BY (c3, c4);
关键参数说明(PROPERTIES)
| 参数 | 必填 | 说明 |
|---|---|---|
| TYPE | 是 | 固定为 'ODPS' |
| ACCESSID / ACCESSKEY | 是 | RAM 用户 AccessKey(建议最小权限) |
| ENDPOINT | 是 | MaxCompute 服务地址(含地域) |
| PROJECT_NAME | 是 | MaxCompute 项目名 |
| TABLE_NAME | 是 | MaxCompute 表名 |
| SCHEMA_NAME | 否 | 表位于 Schema 下时需指定 |
| ACCESSTYPE | 否 | 账号类型:aliyun(默认)/ sts / app |
| STSTOKEN | 条件 | 仅 ACCESSTYPE = 'sts' 时必填 |
| QUOTA_NAME | 否 | 指定计算资源配额 |
| COMPRESSION_CODE | 否 | 压缩格式:zlib / zstd / lz4 / odps_lz4 |
| API_MODE | 是 | {"tunnel_api"} 或 {"storage_api"} |
| SPLIT | 条件 | 使用 storage_api 时指定分片方式:byte 或 row |
完整语法参见 CREATE EXTERNAL TABLE。
查询 MaxCompute 数据
查询 ODPS 外部表与查询普通表语法相同。
SELECT * FROM t1;
-- 指定并行度
SELECT /*+ PARALLEL(N) */ * FROM t1;
写入 MaxCompute 数据
OceanBase 支持通过 INSERT INTO 或 INSERT OVERWRITE 向 ODPS 外部表写入数据。
-- 追加写入
INSERT INTO external_table_name
SELECT column_list FROM source_table [WHERE ...];
-- 覆盖写入
INSERT OVERWRITE external_table_name
SELECT column_list FROM source_table [WHERE ...];
非分区表写入示例
INSERT INTO t1 SELECT * FROM t1_;
INSERT /*+ PARALLEL(N) */ INTO t1 SELECT * FROM t1_;
-- 覆盖写入
INSERT OVERWRITE t1 SELECT * FROM t1_;
-- 指定列写入
INSERT INTO t1 (c1) SELECT c1 FROM t1_;
分区表写入示例
INSERT INTO t2 PARTITION (c3 = 'abc', c4 = 'def') SELECT * FROM t2_;
INSERT OVERWRITE t2 PARTITION (c3 = 'abc', c4 = 'def') SELECT * FROM t2_;
说明
V4.3.5 BP2 及更高版本支持自动创建 MaxCompute 表中不存在的分区;更低版本须预先在 MaxCompute 侧创建目标分区。
写入时要求列数与顺序与外表定义一致。更多语法说明,参见 插入数据。
分区信息同步策略
通过 AUTO_REFRESH 控制 MaxCompute 分区元数据的刷新方式:
| 策略 | 说明 | 适用场景 |
|---|---|---|
IMMEDIATE |
每次查询时自动刷新 | 分区频繁变化 |
OFF |
仅手动刷新 | 静态分区表 |
INTERVAL |
通过定时任务刷新 | 中等频率更新 |
启用即时刷新示例
CREATE EXTERNAL TABLE t2 ( ... )
AUTO_REFRESH = IMMEDIATE
PROPERTIES ( ... )
PARTITION BY (c3, c4);
手动刷新
ALTER EXTERNAL TABLE t2 REFRESH;
类型映射与限制
类型映射
OceanBase 与 MaxCompute 之间的数据类型映射,参见:
时区处理
MaxCompute 时间类型(如 DATETIME)无显式时区信息。OceanBase 默认将其视为与自身会话时区一致。建议 OceanBase 与 MaxCompute 使用相同时区(如 Asia/Shanghai)。
使用限制
| 限制项 | 说明 |
|---|---|
| 模式 | 仅支持 MySQL 模式 |
| 复杂类型 | 不支持 ARRAY<MAP<STRING, BIGINT>> 等嵌套复杂类型 |
| 写入列约束 | 写入时列数与顺序须与外表定义严格一致 |
| 性能 | 查询速度受 MaxCompute API 配额与网络带宽影响 |
注意事项
- ODPS 外表与文件外表的区别:ODPS 外部表通过 MaxCompute API 访问远端表,不使用
LOCATION文件路径;文件外部表用于访问 OSS、HDFS 等路径下的 CSV/Parquet/ORC 文件。 - ODPS 外表与 ODPS Catalog 的区别:外表针对单表映射;Catalog 连接整个 MaxCompute 项目,自动同步元数据。参见 ODPS Catalog。
- API 选择:需减少传输数据量、支持条件过滤时优先使用 Storage API;未开通 Storage API 或网络不满足 VPC 要求时使用 Tunnel API。
- 凭证安全:建议使用 RAM 子账号并遵循最小权限原则;避免在 SQL 中硬编码明文 AccessKey。