ReplacingMergeTree
该引擎与 MergeTree 的不同之处在于它会删除具有相同 排序键 值的重复条目(ORDER BY
表部分,而不是 PRIMARY KEY
)。
数据去重仅在合并期间发生。合并在后台以未知时间进行,因此无法进行规划。某些数据可能仍未处理。尽管可以通过 OPTIMIZE
查询运行未调度的合并,但请不要依赖于它,因为 OPTIMIZE
查询将读取和写入大量数据。
因此,ReplacingMergeTree
适合在后台清除重复数据以节省空间,但并不能保证没有重复项。
有关 ReplacingMergeTree 的详细指南,包括最佳实践和如何优化性能,可以在 这里 查阅。
创建表
有关请求参数的描述,请参阅 语句描述。
行的唯一性由 ORDER BY
表部分决定,而不是 PRIMARY KEY
。
ReplacingMergeTree 参数
ver
ver
— 版本号列。类型为 UInt*
、Date
、DateTime
或 DateTime64
。可选参数。
合并时,ReplacingMergeTree
会从所有具有相同排序键的行中只保留一行:
- 如果未设置
ver
,则选择中的最后一行。选择是参与合并的一组分区片段中的一组行。最近创建的分区(最新插入的)将在选择中排最后。因此,去重后,每个唯一排序键的最新插入的行将保留。 - 如果指定了
ver
,则保留最大版本的行。如果ver
对于多行相同,则将对它们应用“如果未指定ver
”的规则,即最新插入的行将保留。
示例:
is_deleted
is_deleted
— 在合并时用于确定这一行中的数据是否表示状态或要删除的列的名称;1
是“已删除”行,0
是“状态”行。
列数据类型 — UInt8
。
仅当使用 ver
时,is_deleted
才能启用。
无论对数据进行何种操作,版本都应增加。如果两个插入的行具有相同的版本号,则保留最后插入的行。
默认情况下,ClickHouse 将保留某个键的最后一行,即使该行是删除行。这是为了确保可以安全插入任何版本较低的未来行,删除行仍然会被应用。
要永久删除此类删除行,请启用表设置 allow_experimental_replacing_merge_with_cleanup
,并且:
-
设置表设置
enable_replacing_merge_with_cleanup_for_min_age_to_force_merge
、min_age_to_force_merge_on_partition_only
和min_age_to_force_merge_seconds
。如果分区中的所有部分都大于min_age_to_force_merge_seconds
,ClickHouse 将将它们全部合并为一个部分并删除任何删除行。 -
手动运行
OPTIMIZE TABLE table [PARTITION partition | PARTITION ID 'partition_id'] FINAL CLEANUP
。
示例:
查询子句
在创建 ReplacingMergeTree
表时,与创建 MergeTree
表时所需的 子句 相同。
创建表的弃用方法
在新项目中不要使用此方法,如果可能的话,将旧项目切换到上述描述的方法。
除 ver
之外的所有参数在 MergeTree
中具有相同的含义。
ver
- 版本列。可选参数。有关描述,请参见上述文本。
查询时间去重与 FINAL
在合并时,ReplacingMergeTree 识别重复行,使用 ORDER BY
列的值(用于创建表)作为唯一标识符,并仅保留最高版本。但是,这仅提供最终的正确性 - 它不保证行会被去重,因此您不应依赖它。因此,由于更新和删除行在查询中的考虑,查询可能会产生不正确的答案。
为了获得正确的答案,用户需要通过查询时间去重和删除移除来补充后台合并。这可以通过使用 FINAL
操作符来实现。例如,考虑以下示例:
没有使用 FINAL
的查询会产生不正确的计数(确切结果将根据合并而有所不同):
添加 FINAL
会产生正确的结果:
有关 FINAL
的更多详细信息,包括如何优化 FINAL
性能,我们建议阅读我们的 详细指南关于 ReplacingMergeTree。