文档

文件分析

更新时间:

云数据库 SelectDB 版支持表函数功能(Table-Value-Function或TVF),可以将S3、HDFS等常见远端存储中的文件数据,映射成云数据库 SelectDB 版中的表,从而对这些文件数据进行分析。

S3表函数

S3表函数可以让您像访问关系型数据库一样,读取并访问S3兼容的对象存储上的文件内容。目前支持CVS、CSV_with_names、CVS_with_names_and_types、Json、Parquet、ORC文件格式。

语法

s3(
  "uri" = "..",
  "s3.access_key" = "...",
  "s3.secret_key" = "...",
  "s3.region" = "...",
  "format" = "csv",
  "keyn" = "valuen",
  ...
);

参数说明

S3 TVF中的每一个参数都是一个"key"="value"键值对。常用参数如下:

参数名称

参数说明

uri

访问S3的URI。S3表函数会根据use_path_style参数来决定是否使用Path Style访问方式,默认为Virtual-hosted Style方式。必选参数。

s3.access_key

访问S3的用户身份密钥。必选参数。

s3.secret_key

访问S3的用户加密认证字符串。必选参数。

s3.region

默认使用us-east-1。如果Minio服务设置了其他的Region,必选参数。

s3.session_token

访问S3的用户临时会话token。若启用临时会话验证,必选参数。

use_path_style

S3 SDK默认使用Virtual-hosted Style方式。但某些对象存储系统可能未开启或不支持Virtual-hosted Style方式的访问,此时您可以添加use_path_style参数来强制使用Path Style方式。比如Minio默认情况下只允许Path Style访问方式,所以在访问Minio时要加上use_path_style=true

本参数为可选参数,默认为false

说明

URI目前支持三种schema:http://https://s3://

  • 如果使用http://https://,则会根据use_path_style参数来决定是否使用Path Style方式访问S3。

  • 如果使用s3://,则会使用Virtual-hosted Style方式访问S3。

  • 如果URI路径不存在或文件都是空文件,S3 TVF将返回空集合。

format

目前支持CVS、CSV_with_names、CVS_with_names_and_types、Json、Parquet、ORC文件格式,必选参数。

column_separator

列分割符,可选参数,默认为,

line_delimiter

行分割符,可选参数,默认为\n

compress_type

可选参数,目前支持UNKNOWN/PLAIN/GZ/LZO/BZ2/LZ4FRAME/DEFLATE。默认值为UNKNOWN, 将会根据uri的后缀自动推断类型。

read_json_by_line

以行为单位读取JSON数据。可选参数,默认为true。

num_as_string

数字类型按照String处理。可选参数,默认为false。

fuzzy_parse

加速JSON数据的导入效率。可选参数,默认为false。

jsonpaths

当导入数据格式为JSON时,可通过jsonpaths指定抽取JSON数据中的字段。

格式:jsonpaths: [\"$.k2\", \"$.k1\"]

strip_outer_array

当导入数据格式为JSON时,strip_outer_array为true表示JSON数据以数组的形式展现,数据中的每一个元素将被视为一行数据。默认值是false。

格式:strip_outer_array: true

json_root

当导入数据格式为JSON时,可以通过json_root指定JSON数据的根节点。SelectDB将通过json_root抽取根节点的元素进行解析。默认为空。

格式:json_root: $.RECORDS

path_partition_keys

指定文件路径中携带的分区列名,可选参数。例如/path/to/city=beijing/date="2023-07-09",则填写path_partition_keys="city,date"。此时SelectDB将会自动从路径中读取相应列名和列值进行导入。

示例

读取并访问S3兼容的对象存储上的CSV格式文件:

SELECT * FROM s3("uri" = "http://127.0.0.1:9312/test2/student1.csv",
                "s3.access_key"= "minioadmin",
                "s3.secret_key" = "minioadmin",
                "format" = "csv",
                "use_path_style" = "true") ORDER BY c1;

可以配合DECS FUNCTION使用。

MySQL [(none)]> Desc FUNCTION s3("uri" = "http://127.0.0.1:9312/test2/student1.csv",
                 "s3.access_key"= "minioadmin",
                 "s3.secret_key" = "minioadmin",
                 "format" = "csv",
                 "use_path_style" = "true");

HDFS表函数

HDFS表函数可以让您像访问关系表格式数据一样,读取并访问HDFS上的文件内容。目前支持CVS、CSV_with_names、CVS_with_names_and_types、Json、Parquet、ORC文件格式。

语法

hdfs(
  "uri" = "..",
  "fs.defaultFS" = "...",
  "hadoop.username" = "...",
  "format" = "csv",
  "keyn" = "valuen" 
  ...
);

参数说明

HDFS TVF中的每一个参数都是一个"key"="value"键值对。常用参数如下:

参数名称

参数说明

uri

要访问的HDFS的URI。如果URI路径不存在或文件都是空文件,HDFS TVF将返回空集合。必选参数。

fs.defaultFS

要访问的HDFS的主机和端口号。必选参数。

hadoop.username

要访问的HDFS用户名,可以是任意字符串,但不能为空。

hadoop.security.authentication

要访问的HDFS认证方式。可选Simple或者Kerberos。可选参数。

hadoop.kerberos.principal

要访问的HDFS启用Kerberos验证的场合,指定Principal。可选参数。

hadoop.kerberos.keytab

要访问的HDFS启用Kerberos验证的场合,指定Keytab。可选参数。

dfs.client.read.shortcircuit

HDFS短路本地读取开关。布尔类型。可选参数。

dfs.domain.socket.path

一个指向UNIX域套接字的路径,用于DataNode和本地HDFS客户端通信。如果在该路径中出现了字符串"_PORT",会被替换成DataNode的TCP端口。可选参数。

dfs.nameservices

提供服务的NS逻辑名称,与core-site.xml里相应字段对应。

dfs.ha.namenodes.your-nameservices

dfs.nameservices下的NameNode逻辑名称。

dfs.namenode.rpc-address.your-nameservices.your-namenode

每个NameNode监听的HTTP地址。

dfs.client.failover.proxy.provider.your-nameservices

客户端连接可用状态的NameNode所用的代理类。

read_json_by_line

以行为单位读取JSON数据。可选参数,默认为true。

num_as_string

数字类型按照String处理。可选参数,默认为false。

fuzzy_parse

加速JSON数据的导入效率。可选参数,默认为false。

jsonpaths

当导入数据格式为JSON时,可通过jsonpaths指定抽取JSON数据中的字段。

格式:jsonpaths: [\"$.k2\", \"$.k1\"]

strip_outer_array

当导入数据格式为JSON时,strip_outer_array为true表示JSON数据以数组的形式展现,数据中的每一个元素将被视为一行数据。默认值是false。

格式:strip_outer_array: true

json_root

当导入数据格式为JSON时,可以通过json_root指定JSON数据的根节点。SelectDB将通过json_root抽取根节点的元素进行解析。默认为空。

格式:json_root: $.RECORDS

trim_double_quotes

布尔类型,可选参数,默认值为false。为true时表示裁剪掉CSV文件每个字段最外层的双引号。

skip_lines

整数类型,可选参数,默认值为0。含义为跳过CSV文件的前几行。当format设置为csv_with_namescsv_with_names_and_types时,该参数会失效。

path_partition_keys

指定文件路径中携带的分区列名,可选参数。例如/path/to/city=beijing/date="2023-07-09",则填写path_partition_keys="city,date"。此时SelectDB将会自动从路径中读取相应列名和列值进行导入。

示例

读取并访问HDFS存储上的CSV格式文件:

MySQL [(none)]> SELECT * FROM hdfs(
            "uri" = "hdfs://127.0.0.1:842/user/doris/csv_format_test/student.csv",
            "fs.defaultFS" = "hdfs://127.0.0.1:8424",
            "hadoop.username" = "doris",
            "format" = "csv");
            
-- 返回示例   
+------+---------+------+
| c1   | c2      | c3   |
+------+---------+------+
| 1    | alice   | 18   |
| 2    | bob     | 20   |
| 3    | jack    | 24   |
| 4    | jackson | 19   |
| 5    | liming  | 18   |
+------+---------+------+

读取并访问HA模式的HDFS存储上的CSV格式文件:

MySQL [(none)]> SELECT * FROM hdfs(
            "uri" = "hdfs://127.0.0.1:842/user/doris/csv_format_test/student.csv",
            "fs.defaultFS" = "hdfs://127.0.0.1:8424",
            "hadoop.username" = "doris",
            "format" = "csv",
            "dfs.nameservices" = "my_hdfs",
            "dfs.ha.namenodes.my_hdfs" = "nn1,nn2",
            "dfs.namenode.rpc-address.my_hdfs.nn1" = "nanmenode01:8020",
            "dfs.namenode.rpc-address.my_hdfs.nn2" = "nanmenode02:8020",
            "dfs.client.failover.proxy.provider.my_hdfs" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider");

-- 返回示例
+------+---------+------+
| c1   | c2      | c3   |
+------+---------+------+
| 1    | alice   | 18   |
| 2    | bob     | 20   |
| 3    | jack    | 24   |
| 4    | jackson | 19   |
| 5    | liming  | 18   |
+------+---------+------+

可以配合DECS FUNCTION使用:

MySQL [(none)]> DECS FUNCTION hdfs(
            "uri" = "hdfs://127.0.0.1:8424/user/doris/csv_format_test/student_with_names.csv",
            "fs.defaultFS" = "hdfs://127.0.0.1:8424",
            "hadoop.username" = "doris",
            "format" = "csv_with_names");

使用方法

本章节将通过S3 TVF举例说明如何进行文件分析。

自动推断文件列类型

目前支持对Parquet、ORC、CSV、JSON格式进行分析和列类型推断。

> DESC FUNCTION s3 (
    "URI" = "http://127.0.0.1:9312/test2/test.snappy.parquet",
    "s3.access_key"= "ak",
    "s3.secret_key" = "sk",
    "format" = "parquet",
    "use_path_style"="true"
);

-- 返回示例
+---------------+--------------+------+-------+---------+-------+
| Field         | Type         | Null | Key   | Default | Extra |
+---------------+--------------+------+-------+---------+-------+
| p_partkey     | INT          | Yes  | false | NULL    | NONE  |
| p_name        | TEXT         | Yes  | false | NULL    | NONE  |
| p_mfgr        | TEXT         | Yes  | false | NULL    | NONE  |
| p_brand       | TEXT         | Yes  | false | NULL    | NONE  |
| p_type        | TEXT         | Yes  | false | NULL    | NONE  |
| p_size        | INT          | Yes  | false | NULL    | NONE  |
| p_container   | TEXT         | Yes  | false | NULL    | NONE  |
| p_retailprice | DECIMAL(9,0) | Yes  | false | NULL    | NONE  |
| p_comment     | TEXT         | Yes  | false | NULL    | NONE  |
+---------------+--------------+------+-------+---------+-------+

可以看到,对于Parquet文件,SelectDB会根据文件内的元信息自动推断列类型。

CSV Schema

默认情况下,CSV格式文件的所有列类型均会被SelectDB视为String。您可以通过csv_schema属性单独指定列名和列类型。SelectDB会使用指定的列类型进行文件读取。格式如下:

name1:type1;name2:type2;...

对于格式不匹配的列(比如文件中实际为字符串,假设您定义为int),或缺失列(比如文件中实际存在4列,假设您定义了5列),则这些列将返回null。当前支持的列类型为:

名称

映射类型

tinyint

tinyint

smallint

smallint

int

int

bigint

bigint

largeint

largeint

float

float

double

double

decimal(p,s)

decimalv3(p,s)

date

datev2

datetime

datetimev2

char

string

varchar

string

string

string

boolean

boolean

示例:

s3 (
    "URI" = "https://bucket1/inventory.dat",
    "s3.access_key"= "ak",
    "s3.secret_key" = "sk",
    "format" = "csv",
    "column_separator" = "|",
    "csv_schema" = "k1:int;k2:int;k3:int;k4:decimal(38,10)",
    "use_path_style"="true"
)

查询分析

您可以使用任意的SQL语句,对TVF进行分析:

SELECT * FROM s3(
    "URI" = "http://127.0.0.1:9312/test2/test.snappy.parquet",
    "s3.access_key"= "ak",
    "s3.secret_key" = "sk",
    "format" = "parquet",
    "use_path_style"="true")
LIMIT 5;

-- 返回示例
+-----------+------------------------------------------+----------------+----------+-------------------------+--------+-------------+---------------+---------------------+
| p_partkey | p_name                                   | p_mfgr         | p_brand  | p_type                  | p_size | p_container | p_retailprice | p_comment           |
+-----------+------------------------------------------+----------------+----------+-------------------------+--------+-------------+---------------+---------------------+
|         1 | goldenrod lavender spring chocolate lace | Manufacturer#1 | Brand#13 | PROMO BURNISHED COPPER  |      7 | JUMBO PKG   |           901 | ly. slyly ironi     |
|         2 | blush thistle blue yellow saddle         | Manufacturer#1 | Brand#13 | LARGE BRUSHED BRASS     |      1 | LG CASE     |           902 | lar accounts amo    |
|         3 | spring green yellow purple cornsilk      | Manufacturer#4 | Brand#42 | STANDARD POLISHED BRASS |     21 | WRAP CASE   |           903 | egular deposits hag |
|         4 | cornflower chocolate smoke green pink    | Manufacturer#3 | Brand#34 | SMALL PLATED BRASS      |     14 | MED DRUM    |           904 | p furiously r       |
|         5 | forest brown coral puff cream            | Manufacturer#3 | Brand#32 | STANDARD POLISHED TIN   |     15 | SM PKG      |           905 |  wake carefully     |
+-----------+------------------------------------------+----------------+----------+-------------------------+--------+-------------+---------------+---------------------+

TVF可以出现在SQL中Table能出现的任意位置,如CTE的WITH子句中或者FROM子句中,您可以把文件当做一张普通的表进行任意分析。

您也可以通过CREATE VIEW语句为TVF创建一个逻辑视图。这样您可以像其他视图一样,对这个TVF进行访问、权限管理等操作,也可以让其他用户访问这个TVF。

CREATE VIEW v1 AS 
SELECT * FROM s3(
    "URI" = "http://127.0.0.1:9312/test2/test.snappy.parquet",
    "s3.access_key"= "ak",
    "s3.secret_key" = "sk",
    "format" = "parquet",
    "use_path_style"="true");

DESC v1;

SELECT * FROM v1;

GRANT SELECT_PRIV ON db1.v1 TO user1;

数据导入

配合INSERT INTO SELECT语法,您可以方便将文件导入到SelectDB表中进行更快速的分析:

-- 1. 创建SelectDB内部表
CREATE TABLE IF NOT EXISTS test_table
(
    id int,
    name varchar(50),
    age int
)
DISTRIBUTED BY HASH(id) BUCKETS 4
PROPERTIES("replication_num" = "1");

-- 2. 使用S3 Table Value Function插入数据
INSERT INTO test_table (id,name,age)
SELECT cast(id as INT) as id, name, cast (age as INT) as age
FROM s3(
    "uri" = "http://127.0.0.1:9312/test2/test.snappy.parquet",
    "s3.access_key"= "ak",
    "s3.secret_key" = "sk",
    "format" = "parquet",
    "use_path_style" = "true");

注意事项

  • 如果S3或HDFS TVF指定的URI匹配不到文件,或者匹配到的所有文件都是空文件,那么S3或HDFS TVF将会返回空结果集。在这种情况下使用DESC FUNCTION查看这个文件的Schema,会得到一列虚假的列__dummy_col,可忽略这一列。

  • 如果指定TVF的format为CSV,所读文件不为空文件但文件第一行为空,则会提示错误The first line is empty, can not parse column numbers

  • 本页导读 (1)
文档反馈