如果您需要将OSS中的数据导入至云原生数据仓库 AnalyticDB MySQL 版,可以参考本文档,通过外表导入方式将OSS中Parquet、CSV和ORC格式的数据文件导入至数仓版。
前提条件
AnalyticDB for MySQL集群的产品系列为数仓版。
说明数仓版弹性模式集群需要在集群信息页面的网络信息区域,打开启用ENI网络的开关。
AnalyticDB for MySQL集群与OSS存储空间位于同一地域。具体操作,请参见开通OSS服务。
示例数据说明
本示例将oss_import_test_data.csv
文件上传至OSS中的testBucketname/adb/
目录,数据行分隔符为换行符,列分隔符为半角分号(;)。oss_import_test_data.csv
文件示例数据如下所示:
uid;other
12;hello_world_1
27;hello_world_2
28;hello_world_3
33;hello_world_4
37;hello_world_5
40;hello_world_6
操作步骤
在AnalyticDB for MySQL中创建数据库。
CREATE DATABASE adb_demo;
创建外表。使用CREATE TABLE语法创建CSV、Parquet或ORC格式的OSS外表。具体语法,请参见OSS外表语法。
本文示例以CSV格式非分区外表为例。
CREATE TABLE IF NOT EXISTS oss_import_test_external_table ( uid string, other string ) ENGINE='OSS' TABLE_PROPERTIES='{ "endpoint":"oss-cn-hangzhou-internal.aliyuncs.com", "url":"oss://testBucketname/adb/oss_import_test_data.csv", "accessid":"LTAIF****5FsE", "accesskey":"Ccw****iWjv", "delimiter":";", "skip_header_line_count":1, "charset":"utf-8" }';
查询
oss_import_test_external_table
外表数据。说明对于CSV格式、Parquet和ORC格式数据文件,数据量越大,通过外表查询的性能损耗越大。如果您需要进一步提升查询效率,建议您按照后续步骤(4~5)将OSS外表数据导入AnalyticDB for MySQL后再做查询。
SELECT uid, other FROM oss_import_test_external_table WHERE uid < 100 LIMIT 10;
在AnalyticDB for MySQL中创建表,用于存储从OSS外表导入的数据。
CREATE TABLE IF NOT EXISTS adb_oss_import_test ( uid string, other string ) DISTRIBUTED BY HASH(uid);
执行INSERT语句将OSS外表数据导入AnalyticDB for MySQL。
重要使用
INSERT INTO
或INSERT OVERWRITE SELECT
导入数据时,默认是同步执行流程。如果数据量较大,达到几百GB,客户端到AnalyticDB for MySQL服务端的连接需要保持较长时间。在此期间,可能会因为网络因素导致连接中断,进而导致数据导入失败。因此,如果您的数据量较大时,推荐使用SUBMIT JOB INSERT OVERWRITE SELECT
异步执行导入。方式一:执行
INSERT INTO
导入数据,当主键重复时会自动忽略当前写入数据,不进行更新覆盖,作用等同于INSERT IGNORE INTO
,详情请参见INSERT INTO。示例如下:INSERT INTO adb_oss_import_test SELECT * FROM oss_import_test_external_table;
方式二:执行INSERT OVERWRITE导入数据,会覆盖表中原有的数据。示例如下:
INSERT OVERWRITE adb_oss_import_test SELECT * FROM oss_import_test_external_table;
方式三:异步执行
INSERT OVERWRITE
导入数据。 通常使用SUBMIT JOB
提交异步任务,由后台调度,可以在写入任务前增加Hint(/*+ direct_batch_load=true*/
)加速写入任务。详情请参见异步写入。示例如下:SUBMIT JOB INSERT OVERWRITE adb_oss_import_test SELECT * FROM oss_import_test_external_table;
返回结果如下:
+---------------------------------------+ | job_id | +---------------------------------------+ | 2020112122202917203100908203303****** |
关于异步提交任务详情,请参见异步提交导入任务。
OSS外表语法
OSS非分区外表
CREATE TABLE [IF NOT EXISTS] table_name
(column_name column_type[, …])
ENGINE='OSS'
TABLE_PROPERTIES='{
"endpoint":"endpoint",
"url":"OSS_LOCATION",
"accessid":"accesskey_id",
"accesskey":"accesskey_secret",
"format":"text|orc|parquet",
"delimiter":";",
"skip_header_line_count":1,
"charset":"utf-8"
}';
外表类型 | 参数 | 是否必填 | 说明 |
CSV格式、Parquet格式或OSS ORC格式外表 | ENGINE='OSS' | 是 | 表引擎,固定填写为OSS。 |
endpoint | OSS的EndPoint(地域节点)。 目前仅支持AnalyticDB for MySQL通过VPC网络访问OSS。 说明 您可登录OSS控制台,单击目标Bucket,在Bucket概览页面查看EndPoint(地域节点)。 | ||
url | 指定OSS文件或目录所在的路径。
| ||
accessid | 阿里云账号或者具备OSS管理权限的RAM用户的AccessKey ID。 如何获取AccessKey ID,请参见账号与权限。 | ||
accesskey | 阿里云账号或者具备OSS管理权限的RAM用户的AccessKey Secret。 如何获取AccessKey Secret,请参见账号与权限。 | ||
CSV格式外表 | delimiter | 定义CSV数据文件的列分隔符。 | |
Parquet格式、OSS ORC格式外表 | format | 数据文件的格式。
说明
| |
CSV格式外表 | null_value | 否 | 定义CSV数据文件的 重要 仅内核版本为3.1.4.2及以上的集群支持配置该参数。 |
ossnull | 选择CSV数据文件中
说明 上述各示例的前提为 | ||
skip_header_line_count | 定义导入数据时需要在开头跳过的行数。CSV文件第一行为表头,若设置该参数为1,导入数据时可自动跳过第一行的表头。 默认取值为0,即不跳过。 | ||
oss_ignore_quote_and_escape | 是否忽略字段值中的引号和转义。默认取值为false,即不忽略字段值中的引号和转义。 重要 仅内核版本为3.1.4.2及以上的集群支持配置该参数。 | ||
charset | OSS外表字符集,取值说明:
重要 仅内核版本为3.1.10.4及以上的集群支持配置该参数。 |
外表创建语句中的列名需与Parquet或ORC文件中该列的名称完全相同(可忽略大小写),且列的顺序需要一致。
创建外表时,可以仅选择Parquet或ORC文件中的部分列作为外表中的列,未被选择的列不会被导入。
如果创建外表创建语句中出现了Parquet或ORC文件中不存在的列,针对该列的查询结果均会返回NULL。
Parquet文件、ORC文件与AnalyticDB for MySQL的数据类型映射关系
Parquet文件与AnalyticDB for MySQL的数据类型映射关系
Parquet基本类型 | Parquet的logicalType类型 | AnalyticDB for MySQL的数据类型 |
BOOLEAN | 无 | BOOLEAN |
INT32 | INT_8 | TINYINT |
INT32 | INT_16 | SMALLINT |
INT32 | 无 | INT或INTEGER |
INT64 | 无 | BIGINT |
FLOAT | 无 | FLOAT |
DOUBLE | 无 | DOUBLE |
| DECIMAL | DECIMAL |
BINARY | UTF-8 |
|
INT32 | DATE | DATE |
INT64 | TIMESTAMP_MILLIS | TIMESTAMP或DATETIME |
INT96 | 无 | TIMESTAMP或DATETIME |
Parquet格式外表暂不支持STRUCT
类型,会导致建表失败。
ORC文件与AnalyticDB for MySQL的数据类型映射关系
ORC文件中的数据类型 | AnalyticDB for MySQL中的数据类型 |
BOOLEAN | BOOLEAN |
BYTE | TINYINT |
SHORT | SMALLINT |
INT | INT或INTEGER |
LONG | BIGINT |
DECIMAL | DECIMAL |
FLOAT | FLOAT |
DOUBLE | DOUBLE |
|
|
TIMESTAMP | TIMESTAMP或DATETIME |
DATE | DATE |
ORC格式外表暂不支持LIST
、STRUCT
和UNION
等复合类型,会导致建表失败。ORC格式外表的列使用MAP
类型可以建表,但ORC的查询会失败。
AnalyticDB for MySQL支持通过OSS的CSV格式的外表读写Hive TEXT文件。建表语句如下:
CREATE TABLE adb_csv_hive_format_oss (
a tinyint,
b smallint,
c int,
d bigint,
e boolean,
f float,
g double,
h varchar,
i varchar, -- binary
j timestamp,
k DECIMAL(10, 4),
l varchar, -- char(10)
m varchar, -- varchar(100)
n date
) ENGINE = 'OSS' TABLE_PROPERTIES='{
"format": "csv",
"endpoint":"oss-cn-hangzhou-internal.aliyuncs.com",
"accessid":"LTAIF****5FsE",
"accesskey":"Ccw****iWjv",
"url":"oss://testBucketname/adb_data/",
"delimiter": "\\1",
"null_value": "\\\\N",
"oss_ignore_quote_and_escape": "true",
"ossnull": 2
}';
在创建OSS的CSV格式的外表来读取Hive TEXT文件时,需注意如下几点:
Hive TEXT文件的默认列分隔符为
\1
。若您需要通过OSS的CSV格式的外表读写Hive TEXT文件,您可以在配置delimiter
参数时将其转义为\\1
。Hive TEXT文件的默认
NULL
值为\N
。若您需要通过OSS的CSV格式的外表读写Hive TEXT文件,您可以在配置null_value
参数时将其转义为\\\\N
。Hive的其他基本数据类型(如
BOOLEAN
)与AnalyticDB for MySQL的数据类型一一对应,但BINARY
、CHAR(n)
和VARCHAR(n)
类型均对应AnalyticDB for MySQL中的VARCHAR
类型。
OSS分区外表
如果OSS数据源是包含分区的,会在OSS上形成一个分层目录,类似如下内容:
parquet_partition_classic/
├── p1=2020-01-01
│ ├── p2=4
│ │ ├── p3=SHANGHAI
│ │ │ ├── 000000_0
│ │ │ └── 000000_1
│ │ └── p3=SHENZHEN
│ │ └── 000000_0
│ └── p2=6
│ └── p3=SHENZHEN
│ └── 000000_0
├── p1=2020-01-02
│ └── p2=8
│ ├── p3=SHANGHAI
│ │ └── 000000_0
│ └── p3=SHENZHEN
│ └── 000000_0
└── p1=2020-01-03
└── p2=6
├── p2=HANGZHOU
└── p3=SHENZHEN
└── 000000_0
上述数据中p1为第1级分区,p2为第2级分区,p3为第3级分区。对应这种数据源,一般都希望以分区的模式进行查询,那么就需要在创建OSS外表时指明分区列。以Parquet格式为例,创建带有分区的OSS外表的语句如下:
CREATE TABLE [IF NOT EXISTS] table_name
(column_name column_type[, …])
ENGINE='OSS'
TABLE_PROPERTIES='{
"endpoint":"endpoint",
"url":"OSS_LOCATION",
"accessid":"accesskey_id",
"accesskey":"accesskey_secret",
"format":"parquet",
"partition_column":"p1, p2, p3"
}';
TABLE_PROPERTIES
中的partition_column
参数用于指定分区列(本例中的p1、p2、p3)。且partition_column
参数中的分区列必须按照第1级、第2级、第3级的顺序声明(本例中p1为第1级分区,p2为第2级分区,p3为第3级分区)。列定义中必须定义分区列(本例中的p1、p2、p3)及类型,且分区列需要置于列定义的末尾。
列定义中分区列的先后顺序需要与
partition_column
中分区列的顺序保持一致。分区列支持的数据类型包括:
BOOLEAN
、TINYINT
、SMALLINT
、INT
、INTEGER
、BIGINT
、FLOAT
、DOUBLE
、DECIMAL
、VARCHAR
、STRING
、DATE
、TIMESTAMP
。查询数据时,分区列和其它数据列的展示和用法没有区别。
不指定format时,默认格式为CSV。
其他参数的详细说明,请参见参数说明。