ClickHouse 分布式表数据去重
- ClickHouse
- 2020-07-11
- 235热度
- 0评论
场景
有一个部署在两台机器上的 ClickHouse 集群,里面有张分布式表。一部分数据存在机器 A 的 Shard 表上,一部分数据在机器 B 的 Shard 表上。访问任意一台机器,都可以看到全量的表数据。(更多细节略过)
这张分布式表里有一些重复数据,想要去重。怎么处理呢?
思路
创建一张临时的分布式表,从原表中查出去重后的数据,插入到临时表中。清空原表数据,然后再从临时表插回原表。
SQL
下面用具体的 SQL 举例子。
// 设定: // 1. 数据库是 hello_db // 2. 正式表是 hello // 3. 正式 Shard 表是 helloShard // 4. 临时表是 hello_temp // 5. 临时 Shard 表是 hello_tempShard // 6. 根据 timestamp 和 id 的组合做去重 // 创建临时表 create table if not exists hello_tempShard on cluster '{cluster}' (`id` Int64, `name` String, `meta` String, `timestamp` Int64, `dates` Array(Int64)) ENGINE = MergeTree PARTITION BY toYYYYMM(toDateTime(toUInt32(timestamp))) ORDER BY (timestamp, id) // 清空临时表 truncate table hello_tempShard on cluster '{cluster}' // 创建分布式临时表 create table if not exists hello_temp on cluster '{cluster}' (`id` Int64, `name` String, `meta` String, `timestamp` Int64, `dates` Array(Int64)) ENGINE = Distributed('{cluster}', hello_db, hello_tempShard, xxHash64(id)) // 正式表去重导临时表 insert into hello_temp select id, any(name), any(meta), timestamp, any(dates) from hello group by (id, timestamp) // 清空正式表 truncate table helloShard on cluster '{cluster}' // 临时表导正式表 insert into hello select * from hello_temp // 删除临时表 drop table if exists hello_temp on cluster '{cluster}' drop table if exists hello_tempShard on cluster '{cluster}'
参考链接:https://clickhouse.tech/docs/zh/engines/table-engines/special/distributed/