首先,答案取决于您使用的表引擎。ClickHouse上最常见的是MergeTree系列。
如果您使用任何MergeTree系列表、MaterializedView或Buffer引擎,您可以使用OPTIMIZE查询:
OPTIMIZE TABLE table DEDUPLICATE BY name
https://clickhouse.com/docs/en/sql-reference/statements/optimize/
在您考虑上述查询作为答案之前,您必须了解为什么以及为什么这不是正确的方法。
在Clickhouse中,对于相同的主键,有多个行是正常的,与大多数DB引擎不同,在插入行时根本没有检查。这允许在表中非常快速地插入数据。
"MergeTree"的名称不是无意义的,实际上,当Clickhouse认为有必要或/和有时间时,表会自动进行“优化”。
在ClickHouse中,“优化”是什么意思?
此操作只是强制表合并其数据。根据您构建表的方式,ClickHouse将查找重复的行,基于您的设置,并应用您请求的函数。
两个例子:
create table radios
(
id UInt64,
datetime DateTime,
name Nullable(String) default NULL
)
engine = ReplicatedReplacingMergeTree(datetime)
ORDER BY id
INSERT INTO radios VALUES (1, now(), 'Some name'), (1, now(), 'New name')
id, datetime, name
1, '2022-04-04 15:15:00', 'New name'
create table radio_data
(
datetime DateTime,
id UInt64,
power SimpleAggregateFunction(anyLast, Nullable(Float64)) default NULL,
access SimpleAggregateFunction(sum, Nullable(UInt64)) default NULL
)
engine = ReplicatedAggregatingMergeTree()
ORDER BY (id, datetime)
INSERT INTO radio_data VALUES ('2022-04-04 15:15:00', 1, NULL, 1), ('2022-04-04 15:15:00', 1, 12, 2)
datetime , id, power, access
2022-04-04 15:15:00, 1, 12, 3
您选择的表格和函数必须与最终要处理的数据非常接近。如果您要在更新时替换所有行,则使用ReplacingMergeTree是最好的选择;如果您要部分更新一行并对其应用某些函数,则AggregatingMergeTree是最佳选择...等等。
话虽如此,您可能会遇到一些需要使您的数据保持“新鲜”而不重复的情况。
当您的表格配置良好时,简单的“OPTIMIZE TABLE ...”就足够了。但是这是很昂贵的,如果您不想破坏服务器性能,必须明智地进行操作。
您也可以实时合并数据,但同样昂贵,必须针对一小部分数据进行操作,否则最好进行优化。
SELECT * FROM radio_data FINAL WHERE id = 1
例如,我们对所有未合并的分区进行优化,这些分区“过去”了,例如前一天。目标是尽可能少地执行OPTIMIZE操作。
我最后要说的是关于ALTER TABLE语句的使用。它允许DELETE和UPDATE。但它们是变异(
https://clickhouse.com/docs/en/sql-reference/statements/alter/#mutations),不是同步的!如果您需要新鲜数据,请不要依赖它们。
您可以在此处找到更多材料:
https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree/#mergetree
https://clickhouse.com/docs/en/sql-reference/statements/optimize/
https://clickhouse.com/docs/en/sql-reference/statements/alter/