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

art*_*ski 5 sql yandex yandex-metrika clickhouse

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

我需要相同的行为才能在 ClickHouse 存储中的结果表中保留。(即在选择查询和/或使用过滤和聚合子句时解析 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;
Run Code Online (Sandbox Code Playgroud)

这是如何存储 JSON 可序列化数据的好选择?有任何想法吗?

也许最好将 JSON 数据存储为普通数据,String而不是Nested使用特殊函数来处理它?

vla*_*mir 8

  1. 虽然 ClickHouse 使用快速 JSON 库(例如simdjsonrapidjson)来解析,但我认为嵌套字段应该更快。

  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)
..
Run Code Online (Sandbox Code Playgroud)

一方面,它可以显着增加行数和磁盘空间,另一方面,它应该显着提高性能(尤其是在正确的索引中)。此外,可以使用LowCardinality-typeCodecs减小磁盘大小。

  1. 其他一些评论:
..
ORDER BY (created_at, uuid);
Run Code Online (Sandbox Code Playgroud)
  • 考虑使用聚合引擎来显着提高计算聚合值的速度
  1. 在任何情况下,在做出最终决定之前都需要对数据子集进行手动测试(这适用于选择模式(json 作为字符串/嵌套类型/非规范化方式),作为选择列编解码器)。