通过外表导入至数仓版

如果您需要将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        

操作步骤

  1. AnalyticDB for MySQL中创建数据库。

    CREATE DATABASE adb_demo;
  2. 创建外表。使用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"
    }'; 
  3. 查询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;
  4. AnalyticDB for MySQL中创建表,用于存储从OSS外表导入的数据。

    CREATE TABLE IF NOT EXISTS adb_oss_import_test
    (
        uid string,
        other string
    )
    DISTRIBUTED BY HASH(uid);
  5. 执行INSERT语句将OSS外表数据导入AnalyticDB for MySQL

    重要

    使用INSERT INTOINSERT 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文件或目录所在的路径。

  • OSS文件需填写绝对路径。例如:oss://testBucketname/adb/oss_import_test_data.csv

  • 目录路径以正斜线(/)结尾。例如:oss://testBucketname/adb/

    说明

    若指定为目录路径,成功创建外表后,外表中的数据为该文件夹下的所有数据。

  • 路径末尾支持通配符*,用于匹配该路径下所有符合该模式的文件或文件夹。例如:oss://testBucketname/adb/list_file_with_prefix/test*

    说明

    该模糊查询示例将匹配到满足前缀条件的所有文件和文件夹,例如:oss://testBucketname/adb/list_file_with_prefix/testfile1

    oss://testBucketname/adb/list_file_with_prefix/test1/file2

accessid

阿里云账号或者具备OSS管理权限的RAM用户的AccessKey ID。

如何获取AccessKey ID,请参见账号与权限

accesskey

阿里云账号或者具备OSS管理权限的RAM用户的AccessKey Secret。

如何获取AccessKey Secret,请参见账号与权限

CSV格式外表

delimiter

定义CSV数据文件的列分隔符。

Parquet格式、OSS ORC格式外表

format

数据文件的格式。

  • 创建Parquet格式文件的外表时需设置为parquet

  • 创建ORC格式文件的外表时需设置为orc

说明
  • 仅创建OSS Parquet格式或OSS ORC格式外表填写该参数。

  • 不指定format时,默认格式为CSV。

CSV格式外表

null_value

定义CSV数据文件的NULL值。默认将空值定义为NULL,即"null_value": ""

重要

仅内核版本为3.1.4.2及以上的集群支持配置该参数。

ossnull

选择CSV数据文件中NULL值的对应规则。取值如下:

  • 1(默认值):表示EMPTY_SEPARATORS,即仅将空值定义为NULL

    示例:a,"",,c --> "a","",NULL,"c"

  • 2:表示EMPTY_QUOTES,即仅将""定义为NULL

    示例:a,"",,c --> "a",NULL,"","c"

  • 3:表示BOTH,即同时将空值和""定义为NULL

    示例:a,"",,c --> "a",NULL,NULL,"c"

  • 4:表示NEITHER,即空值和""均不定义为NULL

    示例:a,"",,c --> "a","","","c"

说明

上述各示例的前提为"null_value": ""

skip_header_line_count

定义导入数据时需要在开头跳过的行数。CSV文件第一行为表头,若设置该参数为1,导入数据时可自动跳过第一行的表头。

默认取值为0,即不跳过。

oss_ignore_quote_and_escape

是否忽略字段值中的引号和转义。默认取值为false,即不忽略字段值中的引号和转义。

重要

仅内核版本为3.1.4.2及以上的集群支持配置该参数。

charset

OSS外表字符集,取值说明:

  • utf-8(默认值)

  • gbk

重要

仅内核版本为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

  • FIXED_LEN_BYTE_ARRAY

  • BINARY

  • INT64

  • INT32

DECIMAL

DECIMAL

BINARY

UTF-8

  • VARCHAR

  • STRING

  • JSON(如果已知Parquet该列内容为JSON格式)

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

  • BINARY

  • STRING

  • VARCHAR

  • VARCHAR

  • STRING

  • JSON(如果已知ORC该列内容为JSON格式)

TIMESTAMP

TIMESTAMP或DATETIME

DATE

DATE

重要

ORC格式外表暂不支持LISTSTRUCTUNION等复合类型,会导致建表失败。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的数据类型一一对应,但BINARYCHAR(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中分区列的顺序保持一致。

  • 分区列支持的数据类型包括:BOOLEANTINYINTSMALLINTINTINTEGERBIGINTFLOATDOUBLEDECIMALVARCHARSTRINGDATETIMESTAMP

  • 查询数据时,分区列和其它数据列的展示和用法没有区别。

  • 不指定format时,默认格式为CSV。

  • 其他参数的详细说明,请参见参数说明