MaxCompute支持创建OSS外部表为分区表,访问OSS上以分区方式存储的数据,通过该方式可降低读取数据量并提升数据处理效率。本文为您介绍MaxCompute支持的OSS标准分区路径格式和自定义分区路径格式。

背景信息

创建OSS外部表后,MaxCompute会全量扫描OSS目录下的所有数据,包括子目录下的数据文件。但当数据量比较大时,对全目录扫描会产生不必要的I/O消耗以及数据处理时间。通常,解决该问题有如下两种方法:
  • (推荐)方式一:在OSS上将数据以标准分区路径或自定义分区路径方式存储。通过MaxCompute新建OSS外部表时,您需要在建表语句指定分区及oss_location信息。推荐您使用标准分区路径。更多分区路径信息,请参见标准分区路径格式自定义分区路径格式
  • 方式二:规划多个数据存放路径。创建多个OSS外部表来读取各个路径下的数据。即每个OSS外部表指向OSS数据的一个子集。该方式操作比较繁琐,数据管理效果不佳。不推荐使用该方式。

标准分区路径格式

标准分区路径格式如下。
oss://<oss_endpoint>/<Bucket名称>/<目录名称>/<partitionKey1=value1>/<partitionKey2=value2>/...
说明 因为OSS数据是离线准备的,即通过OSS控制台或其他OSS工具上传到OSS中,所以数据的路径格式取决于上传时的格式。
参数名称 可选/必填 说明
oss_endpoint 必填 OSS访问域名信息。建议您使用OSS提供的内网域名,否则将产生OSS流量费用。更多OSS内网域名信息,请参见访问域名和数据中心
说明 建议数据文件存放的OSS地域与MaxCompute项目所在地域保持一致。由于MaxCompute只在部分地域部署,跨地域的数据连通性可能存在问题。
Bucket名称 必填 OSS存储空间名称,即Bucket名称。查看存储空间名称操作,请参见列举存储空间
目录名称 必填 指定OSS目录名称。目录后不需要指定文件名。
partitionKey 必填 OSS外部表的分区列名。
value 必填 OSS外部表的分区列值。
例如,某公司会将每天产生的Log文件以CSV格式存放在OSS上,并通过MaxCompute以天为周期处理数据。则存储OSS数据的标准分区路径应设置如下。
oss://oss-odps-test/log_data/year=2016/month=06/day=01/logfile
oss://oss-odps-test/log_data/year=2016/month=06/day=02/logfile
oss://oss-odps-test/log_data/year=2016/month=07/day=10/logfile
oss://oss-odps-test/log_data/year=2016/month=08/day=08/logfile
...

基于上述分区存储路径,创建OSS外部表、引入并分析分区数据的命令示例如下。

--创建OSS外部表。
create external table log_table_external (
    click STRING,
    ip STRING,
    url STRING
  )
partitioned by (
    year STRING,
    month STRING,
    day STRING
  )
stored by 'com.aliyun.odps.CsvStorageHandler'
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/log_data/';

--引入OSS分区数据。
alter table log_table_external add partition (year = '2016', month = '06', day = '01');
alter table log_table_external add partition (year = '2016', month = '06', day = '02');
alter table log_table_external add partition (year = '2016', month = '07', day = '10');
alter table log_table_external add partition (year = '2016', month = '08', day = '08');
...

--分析数据。只访问log_data/year=2016/month=06/day=01子目录下的文件(logfile),不会对整个log_data目录做全量数据扫描。
select count(distinct(ip)) from log_table_external where year = '2016' and month = '06' and day = '01';

完整的读取标准分区路径数据示例,请参见示例:通过内置文本数据解析器创建OSS外部表-分区表

自定义分区路径格式

如果OSS上的数据实际上已按照分区方式存储,只是路径不是标准分区路径格式时,MaxCompute支持将不同的子目录绑定至不同的分区。

自定义分区路径格式示例如下,只有分区列值,无分区列名。
oss://oss-odps-test/log_data_customized/2016/06/01/logfile
oss://oss-odps-test/log_data_customized/2016/06/02/logfile
oss://oss-odps-test/log_data_customized/2016/07/10/logfile
oss://oss-odps-test/log_data_customized/2016/08/08/logfile
...
创建OSS外部表后,通过alter table ... add partition ... location ...命令指定子目录,将不同的子目录绑定到不同的分区,命令示例如下。
alter table log_table_external add partition (year = '2016', month = '06', day = '01')
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-odps-test/log_data_customized/2016/06/01/';
alter table log_table_external add partition (year = '2016', month = '06', day = '02')
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-odps-test/log_data_customized/2016/06/02/';
alter table log_table_external add partition (year = '2016', month = '07', day = '10')
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-odps-test/log_data_customized/2016/07/10/';
alter table log_table_external add partition (year = '2016', month = '08', day = '08')
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-odps-test/log_data_customized/2016/08/08/';

基于该方式,自定义分区路径后,即使数据存放不符合推荐的标准分区路径格式,您也可以正确地对子目录数据进行访问。