ClickHouse写入数据重复,你们一般是如何处理的?

1 个回答

  • 齐昊
    垆边人似月,皓腕凝霜雪。
    ClickHouse写入数据重复的处理方式主要取决于数据的业务场景和表的引擎类型,常见的处理方案如下: ### 1. **使用 `ReplacingMergeTree` 引擎** 如果你的表使用 `ReplacingMergeTree`,可以指定一个去重列(如 `version` 或 `updated_at`),让 ClickHouse 在 `Merge` 过程中自动删除重复数据。例如: ```sql CREATE TABLE example ( id UInt64, value String, version UInt64 ) ENGINE = ReplacingMergeTree(version) ORDER BY id; ``` 在 `Merge` 阶段,ClickHouse 会保留相同 `id` 记录中 `version` 最大的一条。 **注意**: - `ReplacingMergeTree` 并不会立即去重,而是需要等待 `Merge` 过程触发。 - 在查询时,可使用 `FINAL` 强制触发去重: ```sql SELECT * FROM example FINAL; ``` ### 2. **使用 `SummingMergeTree` 进行聚合** 如果你的数据可以按某个数值列进行合并(如求和),可以使用 `SummingMergeTree`: ```sql CREATE TABLE example ( id UInt64, amount Float64 ) ENGINE = SummingMergeTree() ORDER BY id; ``` 在 `Merge` 过程中,相同 `id` 的 `amount` 会自动合并。 **适用场景**:适用于金额、计数等需要合并数值的情况。 ### 3. **使用 `Deduplication` 机制** 如果数据是通过 `ReplicatedMergeTree` 写入的,ClickHouse 自带去重机制: - **默认情况下**,`INSERT` 相同的 `INSERT_ID` 会被去重。 - 你可以手动控制去重: ```sql SET insert_deduplicate=1; -- 启用去重 SET insert_deduplicate=0; -- 关闭去重 ``` - 也可以用 `OPTIMIZE` 手动触发 `Merge`: ```sql OPTIMIZE TABLE example FINAL; ``` **适用场景**:适用于分布式表或 `ReplicatedMergeTree` 需要去重的情况。 --- ### 4. **使用 `ALTER TABLE DELETE` 进行手动去重** 如果已经写入了重复数据,可以使用 `ALTER TABLE DELETE` 进行删除。例如: ```sql ALTER TABLE example DELETE WHERE id IN ( SELECT id FROM ( SELECT id, COUNT(*) as cnt FROM example GROUP BY id HAVING cnt > 1 ) ); ``` **适用场景**:当表本身不支持去重引擎,需要手动清理重复数据时。 ### 5. **在 `INSERT` 阶段进行去重** - **使用 `INSERT SELECT DISTINCT`** ```sql INSERT INTO example SELECT DISTINCT * FROM source_table; ``` - **使用 `GROUP BY` 方式** ```sql INSERT INTO example SELECT id, MAX(value) FROM source_table GROUP BY id; ``` **适用场景**:适用于数据导入时想要主动去重的情况。 ### 6. **使用 `CollapsingMergeTree` 处理幂等写入** 如果你的数据是可撤销的(如日志型数据),可以使用 `CollapsingMergeTree`,通过 `Sign` 机制删除重复或无效数据: ```sql CREATE TABLE example ( id UInt64, value String, Sign Int8 ) ENGINE = CollapsingMergeTree(Sign) ORDER BY id; ``` **适用场景**:适用于撤销、幂等数据写入的场景。 ### 7. **使用 `Materialized View` 去重** 可以创建一个 `Materialized View`,写入时自动去重: ```sql CREATE MATERIALIZED VIEW example_mv TO example AS SELECT id, any(value) as value, max(version) as version FROM source_table GROUP BY id; ``` **适用场景**:适用于数据需要定期去重、并行写入的情况。 ## **总结** | 方式 | 适用场景 | 备注 | |------|--------|------| | `ReplacingMergeTree` | 需要基于 `version` 替换的场景 | 需要 `Merge` 触发去重 | | `SummingMergeTree` | 适用于数值累加的场景 | 仅适用于数值列 | | `ReplicatedMergeTree` | 分布式去重 | 需要 `insert_deduplicate=1` | | `ALTER TABLE DELETE` | 手动删除重复数据 | 影响性能 | | `INSERT SELECT DISTINCT` | 插入时去重 | 适用于数据批量导入 | | `CollapsingMergeTree` | 日志/撤销式数据 | 需要 `Sign` 字段 | | `Materialized View` | 自动去重 | 适用于定期清理 | 你可以根据你的业务场景选择合适的方式来处理 ClickHouse 的数据重复问题。
    发布于 2025-03-24 12:40 •IP属地 上海
    举报
    评论
    收藏