云原生数据仓库 AnalyticDB MySQL 版支持通过外表和INSERT INTO方式将AnalyticDB for MySQL数仓版中的数据导出到对象存储OSS(Object Storage Service)中。将数据导出到OSS功能只支持CSV和Parquet格式文件。
前提条件
在对象存储OSS中创建存储AnalyticDB for MySQL数据的目录:
完成创建数仓版集群、设置白名单、创建账号和数据库等准备工作。详情请参见AnalyticDB for MySQL快速入门。
如果AnalyticDB for MySQL数仓版集群是弹性模式,请先登录AnalyticDB MySQL控制台,查看集群信息,在网络信息栏启用ENI(Elastic Network Interface,弹性网卡)网络。
操作步骤
本示例将AnalyticDB for MySQL数仓版的adb_demo
库中的source_table
表数据导出至OSS的adb_data
文件夹下。
连接目标集群,进入源数据库。
在
adb_demo
数据库中创建外表,详情请参见不带分区的数据文件创建OSS外表。根据外表类型选择执行写入语句,将源数据写入到步骤2创建的外表中。不同的外表类型支持的语法,请参见未做分区的普通外表语法支持和分区外表语法支持。
待步骤3的写入任务结束后,您可登录OSS控制台,在目标文件夹下查看导出到OSS的数据文件。您也可以直接通过AnalyticDB for MySQL查询导出到外表的数据。
未做分区的普通外表语法支持
使用INSERT INTO
或INSERT OVERWRITE SELECT
导入数据时,默认是同步执行流程,如果数据量较大达到几百GB,客户端到AnalyticDB for MySQL服务端的连接会中断,导致数据导入失败。因此,如果您的数据量较大时,推荐异步执行INSERT OVERWRITE SELECT
导入数据,即在导入语句前加SUBMIT JOB
,例如SUBMIT JOB INSERT OVERWRITE adb_table SELECT * FROM oss_table;
。关于异步提交任务详情,请参见异步提交导入任务。
导入到OSS中的文件,数据文件内默认不带列名,只有数据。如果需要导出带列名的文件,请在导入语句前添加hint/*+sql_output_oss_file_head_enable=true*/
。
INSERT SELECT FROM
功能:如果您的数据在其他表中已经存在,可以通过
INSERT SELECT FROM
将数据复制到外表。将源表的数据写入外表对应的OSS位置,每次写入会产生新的OSS数据文件。重要写入的外表必须保持列个数的完整,不允许指定只写入一部分的列。
语法:
INSERT INTO table_name SELECT select_statement FROM from_statement;
例句:
insert into oss_table select col1, col2, col3 from source_table;
INSERT OVERWRITE SELECT
功能:
INSERT OVERWRITE SELECT
用于向表中批量插入数据。如果目标外表中已存在数据,则每次写入会先删除原外表路径下全部数据文件,再产生新的OSS数据文件。重要写入的外表必须保持列个数的完整,不允许用户指定只写入一部分的列。
语法:
INSERT OVERWRITE table_name SELECT select_statement FROM from_statement;
例句:
INSERT OVERWRITE oss_table SELECT col1, col2, col3 FROM source_table;
REPLACE SELECT FROM
功能:由于OSS外表不支持定义主键,因此
REPLACE SELECT FROM
的写入表现与INSERT SELECT FROM
保持一致,都是将数据复制到另外一张表;如果目标表已有数据,已有数据保持不变,新数据追加到新的OSS数据文件。
导出到OSS单文件(仅限CSV格式,Parquet格式不允许导出到单一文件)
功能:通过hint指定唯一的OSS文件,将数据导出到此文件中。包含overwrite关键字时,覆盖外表TABLE_PROPERTIES中定义的目录下旧的同名文件,不影响该目录下其他文件。
重要写入的外表必须保持列个数的完整,不允许用户指定只写入一部分的列。
版本说明:
3.1.2版本之前的AnalyticDB for MySQL集群:不支持此功能,文件名由系统自动命名,将会导出多个文件。根据任务并发速度动态确定目标文件数目。
3.1.2及之后版本的AnalyticDB for MySQL集群:支持通过hint将AnalyticDB for MySQLCSV格式的普通外表导出到OSS单文件,用户在导出时可自定义文件名。不带hint的情况下,与3.1.2之前的版本保持一致(导出多个文件)。
语法:
/*+output_filename=adb.txt*/INSERT [OVERWRITE] table_name SELECT select_statement FROM from_statement;
例句:
/*+output_filename=adb.txt*/INSERT [OVERWRITE] oss_table SELECT * FROM source_table;
未带hint导出时:
导出到单一文件时:
分区外表语法支持
使用INSERT INTO
或INSERT OVERWRITE SELECT
导入数据时,默认是同步执行流程,如果数据量较大达到几百GB,客户端到AnalyticDB for MySQL服务端的连接会中断,导致数据导入失败。因此,如果您的数据量较大时,推荐异步执行INSERT OVERWRITE SELECT
导入数据,即在导入语句前加SUBMIT JOB
,例如SUBMIT JOB INSERT OVERWRITE adb_table SELECT * FROM oss_table;
。关于异步提交任务详情,请参见异步提交导入任务。
导入到OSS中的文件,数据文件内默认不带列名,只有数据。如果需要导出带列名的文件,请在导入语句前添加hint/*+sql_output_oss_file_head_enable=true*/
。
分区表写出数据时,数据文件内不包含分区列的数据,分区列的数据信息以OSS目录的形式展现。
分区外表不支持导出到OSS单文件。
例如:分区表中定义了2个分区列,3个普通列。其中一级分区名称为pcol1,分区数值为1;二级分区名称为pcol2,分区数值为a。分区表数据导出到OSS的保存路径为adb_data/,则向pcol1=1且pcol2=a的外表分区写出数据时,数据文件相对路径目录为:adb_data/pcol1=1/pcol2=a/;且外表CSV/Parquet数据文件内不包含pcol1与pcol2这两列的值,只包含3列普通列的值。
INSERT INTO PARTITION SELECT FROM
功能:INSERT INTO PARTITION SELECT FROM
用于向带分区的外表中批量插入数据。写入时在PARTITION字段中指明所有分区列和分区值;也可以只写明高层分区目录的分区值,低层分区动态生成;或完全不写分区值,所有层次分区动态生成,此时也就可以无需PARTITION字段。
写入时,数据将在对应分区追加写入,每次写入会产生新的OSS数据文件。
写入的外表必须保持列个数的完整,不允许用户指定只写入一部分的列。
全静态分区
语法
INSERT INTO table_name PARTITION(par1=val1,par2=val2,...)
SELECT select_statement FROM from_statement;
示例
INSERT INTO oss_table_par PARTITION(par1=val1,par2=val2)
select col1, col2, col3 FROM source_table;
半静态半动态分区
语法
INSERT INTO table_name PARTITION(par1=val1,par2,...)
SELECT select_statement FROM from_statement;
示例
INSERT INTO oss_table_par PARTITION(par1=val1,par2)
SELECT col1, col2, col3, par2col FROM source_table;
全动态分区
语法
INSERT INTO table_name
SELECT select_statement FROM from_statement;
示例
INSERT INTO oss_table_par
SELECT col1, col2, col3, par1col, par2col FROM source_table;
INSERT OVERWRITE PARTITION SELECT
功能:和INSERT INTO PARTITION SELECT
使用方法相同,功能上的不同在于会清除掉本次执行中涉及到的目标分区中之前已有的数据文件,对于没有新数据写入的分区,则不会清除其中的数据文件。
语法:
INSERT OVERWRITE table_name PARTITION(par1=val1,par2=val2,...)[IF NOT EXISTS]
SELECT select_statement FROM from_statement;
例句:
INSERT OVERWRITE oss_table_par PARTITION(par1=val1,par2=val2) IF NOT EXISTS
SELECT col1, col2, col3 FROM source_table;
REPLACE INTO PARTITION SELECT FROM
功能:由于外表不支持主键,REPLACE INTO PARTITION SELECT FROM
行为表现与INSERT INTO PARTITION SELECT FROM
一样。
不支持语法
AnalyticDB for MySQL外表不支持自定义行级写入的插入语法,具体不支持的语法包括:INSERT INTO VALUES
和REPLACE INTO VALUES
。