Parquet 是一种高效的文件格式,可按列式方式存储数据。 ClickHouse 支持读取和写入 Parquet 文件。
从 Parquet 导入
在加载数据之前,我们可以使用 file() 函数查看示例 Parquet 文件的结构:
DESCRIBE TABLE file('data.parquet', Parquet);我们将 Parquet 用作第二个参数,这样 ClickHouse 就能识别文件格式。这将输出带类型的列:
┌─name─┬─type─────────────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐
│ path │ Nullable(String) │ │ │ │ │ │
│ date │ Nullable(String) │ │ │ │ │ │
│ hits │ Nullable(Int64) │ │ │ │ │ │
└──────┴──────────────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘我们还可以在真正导入数据之前,借助 SQL 的强大能力先分析文件:
SELECT *
FROM file('data.parquet', Parquet)
LIMIT 3;┌─path──────────────────────┬─date───────┬─hits─┐
│ Akiba_Hebrew_Academy │ 2017-08-01 │ 241 │
│ Aegithina_tiphia │ 2018-02-01 │ 34 │
│ 1971-72_Utah_Stars_season │ 2016-10-01 │ 1 │
└───────────────────────────┴────────────┴──────┘导入到现有表
先创建一个用于导入 Parquet 数据的表:
CREATE TABLE sometable
(
`path` String,
`date` Date,
`hits` UInt32
)
ENGINE = MergeTree
ORDER BY (date, path);现在可以使用 FROM INFILE 子句导入数据:
INSERT INTO sometable
FROM INFILE 'data.parquet' FORMAT Parquet;
SELECT *
FROM sometable
LIMIT 5;┌─path──────────────────────────┬───────date─┬─hits─┐
│ 1988_in_philosophy │ 2015-05-01 │ 70 │
│ 2004_Green_Bay_Packers_season │ 2015-05-01 │ 970 │
│ 24_hours_of_lemans │ 2015-05-01 │ 37 │
│ 25604_Karlin │ 2015-05-01 │ 20 │
│ ASCII_ART │ 2015-05-01 │ 9 │
└───────────────────────────────┴────────────┴──────┘请注意,ClickHouse 会自动将 Parquet 字符串 (date 列中的字符串) 转换为 Date 类型。这是因为 ClickHouse 会根据目标表中的类型自动进行类型转换。
将本地文件插入远程服务器
如果你想将本地 Parquet 文件插入远程 ClickHouse 服务器,可以像下面这样通过管道将文件内容传给 clickhouse-client:
clickhouse client -q "INSERT INTO sometable FORMAT Parquet" < data.parquet从 Parquet 文件创建新表
由于 ClickHouse 会读取 Parquet 文件的 schema,因此我们可以动态创建表:
CREATE TABLE imported_from_parquet
ENGINE = MergeTree
ORDER BY tuple() AS
SELECT *
FROM file('data.parquet', Parquet)这会根据给定的 Parquet 文件自动创建并填充一张表:
DESCRIBE TABLE imported_from_parquet;┌─name─┬─type─────────────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐
│ path │ Nullable(String) │ │ │ │ │ │
│ date │ Nullable(String) │ │ │ │ │ │
│ hits │ Nullable(Int64) │ │ │ │ │ │
└──────┴──────────────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘默认情况下,ClickHouse 会严格校验列名、类型和值。但有时,我们可以在导入时跳过不存在的列或不受支持的值。这可以通过 Parquet 设置 来控制。
导出为 Parquet 格式
要将任意表或查询结果导出为 Parquet 文件,可以使用 INTO OUTFILE 子句:
SELECT *
FROM sometable
INTO OUTFILE 'export.parquet'
FORMAT Parquet这会在当前工作目录中创建 export.parquet 文件。
ClickHouse 和 Parquet 数据类型
ClickHouse 和 Parquet 的数据类型大多相同,但仍略有差异。例如,ClickHouse 会将 DateTime 类型导出为 Parquet 的 int64。如果再将其导入回 ClickHouse,我们看到的将是数字 (time.parquet file):
SELECT * FROM file('time.parquet', Parquet);┌─n─┬───────time─┐
│ 0 │ 1673622611 │
│ 1 │ 1673622610 │
│ 2 │ 1673622609 │
│ 3 │ 1673622608 │
│ 4 │ 1673622607 │
└───┴────────────┘此时可使用类型转换:
SELECT
n,
toDateTime(time) <--- int to time
FROM file('time.parquet', Parquet);┌─n─┬────toDateTime(time)─┐
│ 0 │ 2023-01-13 15:10:11 │
│ 1 │ 2023-01-13 15:10:10 │
│ 2 │ 2023-01-13 15:10:09 │
│ 3 │ 2023-01-13 15:10:08 │
│ 4 │ 2023-01-13 15:10:07 │
└───┴─────────────────────┘延伸阅读
ClickHouse 支持多种格式,包括文本格式和二进制格式,以适应各种场景和平台。你可以在以下文章中进一步了解更多格式及其使用方式:
另外,也可以查看 clickhouse-local——这是一个便携且功能完整的工具,可用于处理本地/远程文件,无需 ClickHouse 服务器。