在Clickhouse中更新数据

18

我仔细查阅了Clickhouse的文档,未找到更新和删除选项。看起来这是一个仅追加的系统。 是否有可能更新现有记录,或者是否有一些解决方法,比如截断包含已更改记录的分区,然后重新插入该分区的所有数据?

6个回答

22

通过Clickhouse中的Alter查询,我们可以删除/更新表格中的行。

删除:查询应构建为

ALTER TABLE testing.Employee DELETE  WHERE  Emp_Name='user4';
更新:查询应按以下结构构建。
ALTER TABLE testing.employee UPDATE AssignedUser='sunil' where AssignedUser='sunny';

19

更新:本回答已经过时,请查看这个https://dev59.com/ZFoU5IYBdhLWcg3wCjrx#55298764

ClickHouse不支持真正的UPDATE/DELETE。 但是有一些可能的解决方案:

  1. 尝试以不需要进行更新的方式组织数据。您可以将更新事件的日志写入表中,然后从该日志计算报告。因此,与其更新现有记录,您可以将新记录附加到表中。

  2. 使用在合并期间后台执行数据转换的表引擎。例如 (相当特定的) CollapsingMergeTree 表引擎:https://clickhouse.yandex/reference_en.html#CollapsingMergeTree。还有 ReplacingMergeTree 表引擎(尚未记录在文档中,但您可以在测试中找到示例:https://github.com/yandex/ClickHouse/blob/master/dbms/tests/queries/0_stateless/00325_replacing_merge_tree.sql)。 缺点是您不知道何时进行后台合并,或者它是否会被执行。

还可以查看samdoj的答案。


2
从2018年6月28日的1.1.54388版本开始,您可以改变数据。请参考https://clickhouse.yandex/docs/en/changelog/#clickhouse-release-1-1-54388-2018-06-28。 - Anton Manevskiy

5

5
您可以删除并创建新表,但根据其大小,这可能非常耗时。您可以像这样操作:
对于删除,可以使用以下内容:
  INSERT INTO tableTemp SELECT * from table1 WHERE  rowID != @targetRowID;
    DROP table1;
    INSERT INTO table1 SELECT * from tableTemp;

同样地,要更新一行数据,你可以先以这种方式将其删除,然后再添加它。

但是我如何更新一个非常大的表呢?例如,如果我的过程是收集大量记录,然后“纠正”其中15%的记录,该怎么办? - Jonathan
1
基本上只需更新和删除多行?你可以先将这些行选择到一个临时表中,然后将where子句更改为WHERE rowID is not in (SELECT rowID FROM targetTable)。在这里,您的限制仅取决于您可以选择哪些内容。 - samdoj
1
重命名表格比执行“INSERT INTO table1 SELECT * from tableTemp;”更加高效。 - Darth Kotik

3

这是一个古老的问题,但现在ClickHouse已经支持了更新操作。需要注意的是,出于性能原因,不建议进行过多的小修改,但是确实是可以实现的。

语法:

ALTER TABLE [db.]table UPDATE column1 = expr1 [, ...] WHERE filter_expr

ClickHouse UPDATE 文档


0
要更新值,您可以使用ReplacingMergeTree引擎
在表上使用此引擎时,如果您尝试追加具有已存在于表中的排序键的行,则会替换具有相同排序键的先前记录(类似于upsert)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接