跳到主要内容

在 ClickHouse 中使用原生和二进制格式

ClickHouse 支持多种二进制格式,这些格式可以提高性能和空间效率。二进制格式在字符编码方面也是安全的,因为数据以二进制形式保存。

我们将使用 some_data 数据 进行演示,您可以随意在您的 ClickHouse 实例上复制它们。

以原生 ClickHouse 格式导出

在 ClickHouse 节点之间导出和导入数据的最有效数据格式是 原生 格式。导出使用 INTO OUTFILE 子句完成

SELECT * FROM some_data
INTO OUTFILE 'data.clickhouse' FORMAT Native

这将在原生格式中创建 data.clickhouse 文件。

从原生格式导入

要导入数据,我们可以使用 file() 导入较小的文件或进行探索。

DESCRIBE file('data.clickhouse', Native);
┌─name──┬─type───┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐
│ path │ String │ │ │ │ │ │
│ month │ Date │ │ │ │ │ │
│ hits │ UInt32 │ │ │ │ │ │
└───────┴────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘
提示

使用 file() 函数时,在 ClickHouse Cloud 中,您需要在包含该文件的机器上运行 clickhouse client 中的命令。另一种选择是使用 clickhouse-local 在本地探索文件。

在生产环境中,我们使用 FROM INFILE 导入数据

INSERT INTO sometable
FROM INFILE 'data.clickhouse'
FORMAT Native

原生格式压缩

我们还可以使用 COMPRESSION 子句在将数据导出到原生格式(以及大多数其他格式)时启用压缩

SELECT * FROM some_data
INTO OUTFILE 'data.clickhouse'
COMPRESSION 'lz4'
FORMAT Native

我们使用了 LZ4 压缩进行导出。导入数据时必须指定它

INSERT INTO sometable
FROM INFILE 'data.clickhouse'
COMPRESSION 'lz4'
FORMAT Native

导出到 RowBinary

支持的另一种二进制格式是 RowBinary,它允许以二进制表示的行导入和导出数据

SELECT * FROM some_data
INTO OUTFILE 'data.binary' FORMAT RowBinary

这将在二进制行格式中生成 data.binary 文件。

探索 RowBinary 文件

此格式不支持自动模式推断,因此在加载之前进行探索时,我们必须明确定义模式

SELECT *
FROM file('data.binary', RowBinary, 'path String, month Date, hits UInt32')
LIMIT 5
┌─path───────────────────────────┬──────month─┬─hits─┐
│ Bangor_City_Forest │ 2015-07-01 │ 34 │
│ Alireza_Afzal │ 2017-02-01 │ 24 │
│ Akhaura-Laksam-Chittagong_Line │ 2015-09-01 │ 30 │
│ 1973_National_500 │ 2017-10-01 │ 80 │
│ Attachment │ 2017-09-01 │ 1356 │
└────────────────────────────────┴────────────┴──────┘

考虑使用 RowBinaryWithNames,它还会添加包含列列表的标题行。 RowBinaryWithNamesAndTypes 还将添加包含列类型的附加标题行。

从 RowBinary 文件导入

要从 RowBinary 文件加载数据,我们可以使用 FROM INFILE 子句

INSERT INTO sometable
FROM INFILE 'data.binary'
FORMAT RowBinary

使用 RawBLOB 导入单个二进制值

假设我们想要读取整个二进制文件并将它保存到表中的一个字段中。当可以使用 RawBLOB 格式 时,这种情况适用。此格式只能与单个列表一起使用

CREATE TABLE images(data String) Engine = Memory

让我们将图像文件保存到 images 表中

cat image.jpg | clickhouse-client -q "INSERT INTO images FORMAT RawBLOB"

我们可以检查 data 字段的长度,它将等于原始文件的大小

SELECT length(data) FROM images
┌─length(data)─┐
│ 6121 │
└──────────────┘

导出 RawBLOB 数据

此格式还可用于使用 INTO OUTFILE 子句导出数据

SELECT * FROM images LIMIT 1
INTO OUTFILE 'out.jpg'
FORMAT RawBLOB

请注意,我们必须使用 LIMIT 1,因为导出多个值将创建损坏的文件。

MessagePack

ClickHouse 支持使用 MsgPack 导入和导出到 MessagePack。要导出到 MessagePack 格式

SELECT *
FROM some_data
INTO OUTFILE 'data.msgpk'
FORMAT MsgPack

要从 MessagePack 文件 导入数据

INSERT INTO sometable
FROM INFILE 'data.msgpk'
FORMAT MsgPack

Protocol Buffers

要使用 Protocol Buffers,我们首先需要定义一个 模式文件

syntax = "proto3";

message MessageType {
string path = 1;
date month = 2;
uint32 hits = 3;
};

此模式文件的路径(在本例中为 schema.proto)在 Protobuf 格式的 format_schema 设置选项中设置

SELECT * FROM some_data
INTO OUTFILE 'proto.bin'
FORMAT Protobuf
SETTINGS format_schema = 'schema:MessageType'

这将数据保存到 proto.bin 文件中。ClickHouse 还支持导入 Protobuf 数据以及嵌套消息。考虑使用 ProtobufSingle 来处理单个 Protocol Buffer 消息(在这种情况下,长度分隔符将被省略)。

Cap’n Proto

ClickHouse 支持的另一种流行的二进制序列化格式是 Cap’n Proto。与 Protobuf 格式类似,我们必须在我们的示例中定义一个模式文件 (schema.capnp)

@0xec8ff1a10aa10dbe;

struct PathStats {
path @0 :Text;
month @1 :UInt32;
hits @2 :UInt32;
}

现在,我们可以使用 CapnProto 格式和此模式导入和导出

SELECT
path,
CAST(month, 'UInt32') AS month,
hits
FROM some_data
INTO OUTFILE 'capnp.bin'
FORMAT CapnProto
SETTINGS format_schema = 'schema:PathStats'

请注意,我们必须将 Date 列转换为 UInt32匹配相应的类型

其他格式

ClickHouse 引入了对许多格式的支持,包括文本格式和二进制格式,以涵盖各种场景和平台。在以下文章中探索更多格式和使用它们的方法

还可以查看 clickhouse-local - 一款便携式功能齐全的工具,可在不启动 ClickHouse 服务器的情况下处理本地/远程文件。