ClickHouse:如何以正确的方式存储 JSON 数据?

ClickHouse: How to store JSON data the right way?

我打算将数据从 PostgreSQL 数据库迁移到 Yandex 的 ClickHouse。 源 table 中的字段之一是类型 JSON - 称为 additional_data。因此,PostgreSQL 允许我 在例如期间访问 json 属性 SELECT ... 查询 ->>-> 等等。

我需要相同的行为 以在我的结果 table 中保存 在 ClickHouse 存储中。 (即在使用过滤和聚合子句时 select 查询 and/or 期间解析 JSON 的能力)

这是我在 CREATE TABLE ... 期间在 ClickHouse 客户端中所做的:

create table if not exists analytics.events
(
    uuid UUID,
    ...,
    created_at DateTime,
    updated_at DateTime,
    additional_data Nested (
        message Nullable(String),
        eventValue Nullable(String),
        rating Nullable(String),
        focalLength Nullable(Float64)
        )
)
engine = MergeTree

ORDER BY (uuid, created_at)
PRIMARY KEY uuid;

如何存储 JSON 可序列化数据是一个不错的选择吗?有什么想法吗?

也许最好将 JSON 数据存储为普通 String 而不是 Nested 并使用 special functions?

  1. 尽管 ClickHouse 使用快速 JSON 库(例如 simdjson and rapidjson)来解析我认为 Nesting-fields 应该更快。

  2. 如果JSON结构是固定的或可预测地改变尝试考虑非规范化数据的方式:

..
    created_at DateTime,
    updated_at DateTime,
    additional_data_message Nullable(String),
    additional_data_eventValue Nullable(String),
    additional_data_rating Nullable(String),
    additional_data_focalLength Nullable(Float64)
..

一方面,它可以显着增加行数和磁盘数量space,另一方面,它应该会显着提高性能(尤其是在正确的索引方面)。此外,可以使用 LowCardinality-type and Codecs.

减小磁盘大小
  1. 其他一些评论:
..
ORDER BY (created_at, uuid);
  1. 无论如何在做出最终决定之前需要对数据子集进行手动测试(这适用于选择架构(json as string/Nested type/denormalized 方式),选择列编解码器)。

从 22.3 开始,有一个 JSON 数据类型 https://clickhouse.com/blog/clickhouse-newsletter-april-2022-json-json-json/