Clickhouse 表引擎 —— MergeTree

参考文档 ReplacingMergetree

-- MergeTree 原理:
-- 底层使用类似LSM树的方式提供数据的快速读写功能。即新的数据(包括更新以及删除的数据)并不会影响原有的数据,
-- 而是会记录在一个新开辟的临时数据块中。查询时通过版本号查询最新的一条结果。
-- 新开辟的数据需要等到后台进行数据合并时,才会进入到主数据中(减少数据碎片化)。

CREATE TABLE t_stock
(
    id           UInt32,
    sku_id       String,
    total_amount Decimal(16, 2),
    create_time  Datetime
)
    ENGINE = MergeTree
        PARTITION BY toYYYYMMDD(create_time)
        PRIMARY KEY id
        ORDER BY (id, sku_id);

INSERT INTO t_stock VALUES
                        (101,'sku_002',2000.00,'2020-06-01 11:00:00'),
                        (102,'sku_004',2500.00,'2020-06-01 12:00:00'),
                        (103,'sku_002',2000.00,'2020-06-02 13:00:00'),
                        (104,'sku_002',12000.00,'2020-06-03 13:00:00'),
                        (105,'sku_002',600.00,'2020-06-04 12:00:00');


-- ReplacingMergeTree 去重逻辑:
-- 根据 order by 作为判断重复的标准。
-- 只在分区内去重。
-- 保留版本字段最大的一条数据。如果没有指定版本,或者版本值重复,则保留最后插入的一条数据。
-- 同一批插入数据时会对数据进行去重。多批次插入可能有重复,需要等待后台数据合并。

CREATE TABLE t_stock_merge
(
    id           UInt32,
    sku_id       String,
    total_amount Decimal(16, 2),
    create_time  Datetime
)
    ENGINE = ReplacingMergeTree(create_time) -- create_time 是版本字段
        PARTITION BY toYYYYMMDD(create_time)
        PRIMARY KEY id
        ORDER BY (id, sku_id);

INSERT INTO t_stock_merge
VALUES (101, 'sku_001', 1000.00, '2020-06-01 12:00:00'),
       (102, 'sku_002', 2000.00, '2020-06-01 11:00:00'),
       (102, 'sku_004', 2500.00, '2020-06-01 12:00:00'),
       (102, 'sku_002', 2000.00, '2020-06-01 13:00:00'),
       (102, 'sku_002', 12000.00, '2020-06-01 13:00:00'),
       (102, 'sku_002', 600.00, '2020-06-02 12:00:00');


其它

CoalescingMergeTree

支持按列级别“持久化最新非 NULL 值”,实现列级的更新,非常适用于部分字段变更的场景。

适用场景

  1. 仅部分字段更新,其他字段保持不变,但你又不想每次写入都带上完整行。
  2. 想要实现轻量级、增量式的列级 upsert。

CollapsingMergeTree

通过 Sign 签名列支持“软删除”与状态更新,保留历史版本,适合需要历史追踪场景

适用场景

  1. 追踪对象状态变化历史,同时希望只保留当前有效状态。
  2. 有删除/更新需求,但不想执行昂贵的 UPDATE 操作

posted on 2025-04-09 13:35  Lemo_wd  阅读(32)  评论(0)    收藏  举报

导航