0


大数据ClickHouse(九):MergeTree系列表引擎之ReplacingMergeTree

文章目录

MergeTree系列表引擎之ReplacingMergeTree

一、****ReplacingMergeTree基本讲解

以上MergeTree不能对相同主键的数据进行去重,ClickHouse提供了ReplacingMergeTree引擎,可以针对同分区内相同主键的数据进行去重,它能够在合并分区时删除重复的数据。值得注意的是,ReplacingMergeTree只是在一定程度上解决了数据重复问题,由于自动分区合并机制在后台定时执行,所以并不能完全保障数据不重复。ReplacingMergeTree 适用于在后台清除重复的数据以节省空间。

  • ReplaceingMergeTree建表语句:
  1. CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
  2. (
  3. name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
  4. name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
  5. ...
  6. ) ENGINE = ReplacingMergeTree([ver])
  7. [PARTITION BY expr]
  8. [ORDER BY expr]
  9. [SAMPLE BY expr]
  10. [SETTINGS name=value, ...]

以上建表语句的解释如下:

  • [ver] :可选参数,指定列的版本,可以是UInt*、Date或者DateTime类型的字段作为版本号。该参数决定了数据去重的方式。当没有指定[ver]时,保留最后插入的数据,也就是最新的数据;如果指定了具体的[ver]列,则保留最大版本数据。

二、使用ReplacingMergeTree是需要注意以下几点

  • 如何判断数据重复

ReplacingMergeTree在去除重复数据时,是以ORDERBY排序键为基准的,而不是PRIMARY KEY。

  • 何时删除重复数据

在执行分区合并时,会触发删除重复数据。optimize的合并操作是在后台执行的,无法预测具体执行时间点,除非是手动执行。

  • 不同分区的重复数据不会被去重

ReplacingMergeTree是以分区为单位删除重复数据的。只有在相同的数据分区内重复的数据才可以被删除,而不同数据分区之间的重复数据依然不能被剔除。

  • 数据去重的策略是什么

如果没有设置[ver]版本号,则保留同一组重复数据中的最新插入的数据;如果设置了[ver]版本号,则保留同一组重复数据中ver字段取值最大的那一行。

  • optimize命令使用

一般在数据量比较大的情况,尽量不要使用该命令。因为在海量数据场景下,执行optimize要消耗大量时间。

三、测试实例

1、测试去重按照Order by 字段进行去重,而不是按照primary 主键字段进行去重

  1. #创建表 t_replacing_mt ,使用ReplacingMergeTree引擎
  2. node1 :) create table t_replacing_mt(
  3. :-] id UInt8,
  4. :-] name String,
  5. :-] age UInt8,
  6. :-] gender String
  7. :-] ) engine = ReplacingMergeTree()
  8. :-] order by (id,age)
  9. :-] primary key id
  10. :-] partition by gender;
  11. #向表 t_replacing_mt 中插入以下数据:
  12. node1 :) insert into t_replacing_mt values (1,'张三',18,'男'),
  13. :-] (2,'李四',19,'女'),
  14. :-] (3,'王五',20,'男');
  15. #查询表 t_replacing_mt 中的数据:
  16. node1 :) select * from t_replacing_mt;
  17. ┌─id─┬─name─┬─age─┬─gender─┐
  18. 2 李四 19
  19. └───┴────┴────┴──────┘
  20. ┌─id─┬─name─┬─age─┬─gender─┐
  21. 1 张三 18
  22. 3 王五 20
  23. └───┴────┴────┴──────┘
  24. #向表 t_replacing_mt 中插入id 为1的一行数据
  25. node1 :) insert into t_replacing_mt values (1,'张三',10,'男');
  26. #查询表 t_replacing_mt 数据:
  27. node1 :) select * from t_replacing_mt;
  28. ┌─id─┬─name─┬─age─┬─gender─┐
  29. 1 张三 10
  30. └────┴──────┴─────┴────────┘
  31. ┌─id─┬─name─┬─age─┬─gender─┐
  32. 1 张三 18
  33. 3 王五 20
  34. └────┴──────┴─────┴────────┘
  35. ┌─id─┬─name─┬─age─┬─gender─┐
  36. 2 李四 19
  37. └────┴──────┴─────┴────────┘
  38. #执行 optimize命令手动合并分区数据
  39. node1 :) optimize table t_replacing_mt;
  40. #查询表 t_replacing_mt 数据,发现没有按照primary key 去重。
  41. node1 :) select * from t_replacing_mt;
  42. ┌─id─┬─name─┬─age─┬─gender─┐
  43. 2 李四 19
  44. └────┴──────┴─────┴────────┘
  45. ┌─id─┬─name─┬─age─┬─gender─┐
  46. 1 张三 10
  47. 1 张三 18
  48. 3 王五 20
  49. └────┴──────┴─────┴────────┘
  50. #再次向表 t_replacing_mt 插入数据:
  51. node1 :) insert into t_replacing_mt values (1,'张三三',18,'男');
  52. #查询表 t_replacing_mt 数据
  53. node1 :) select * from t_replacing_mt;
  54. ┌─id─┬─name───┬─age─┬─gender─┐
  55. 1 张三三 18
  56. └───┴──────┴────┴──────┘
  57. ┌─id─┬─name─┬─age─┬─gender─┐
  58. 2 李四 19
  59. └───┴────┴────┴──────┘
  60. ┌─id─┬─name─┬─age─┬─gender─┐
  61. 1 张三 10
  62. 1 张三 18
  63. 3 王五 20
  64. └───┴─────┴───┴──────┘
  65. #再次执行 optimize命令手动合并分区数据
  66. node1 :) optimize table t_replacing_mt;
  67. #查询表 t_replacing_mt 数据
  68. node1 :) select * from t_replacing_mt;
  69. ┌─id─┬─name─┬─age─┬─gender─┐
  70. 2 李四 19
  71. └───┴────┴────┴──────┘
  72. ┌─id─┬─name───┬─age─┬─gender─┐
  73. 1 张三 10
  74. 1 张三三 18
  75. 3 王五 20
  76. └───┴──────┴────┴─────┘

注意:通过以上测试发现ClickHouse ReplacingMergeTree中****去除重复数据时,是以ORDERBY排序键为基准的,而不是PRIMARY KEY。

2、测试不指定[ver]列时,插入相同排序字段的数据,保留最新一条数据

  1. #删除表 t_replacing_mt 重建,使用ReplacingMergeTree引擎
  2. node1 :) create table t_replacing_mt(
  3. :-] id UInt8,
  4. :-] name String,
  5. :-] age UInt8,
  6. :-] gender String
  7. :-] ) engine = ReplacingMergeTree()
  8. :-] order by id
  9. :-] primary key id
  10. :-] partition by gender;
  11. #向表 t_replacing_mt 中插入以下数据
  12. node1 :) insert into t_replacing_mt values (1,'张三',18,'男'),
  13. :-] (2,'李四',19,'女'),
  14. :-] (3,'王五',20,'男');
  15. #查询表 t_replacing_mt 中的数据
  16. node1 :) select * from t_replacing_mt ;
  17. ┌─id─┬─name─┬─age─┬─gender─┐
  18. 2 李四 19
  19. └────┴──────┴─────┴────────┘
  20. ┌─id─┬─name─┬─age─┬─gender─┐
  21. 1 张三 18
  22. 3 王五 20
  23. └────┴──────┴─────┴────────┘
  24. #向表 t_replacing_mt 中插入排序字段相同的一行数据
  25. node1 :) insert into t_replacing_mt values (1,'张三',10,'男');
  26. #查询表 t_replacing_mt 中的数据
  27. node1 :) select * from t_replacing_mt;
  28. ┌─id─┬─name─┬─age─┬─gender─┐
  29. 1 张三 10
  30. └────┴──────┴─────┴────────┘
  31. ┌─id─┬─name─┬─age─┬─gender─┐
  32. 2 李四 19
  33. └────┴──────┴─────┴────────┘
  34. ┌─id─┬─name─┬─age─┬─gender─┐
  35. 1 张三 18
  36. 3 王五 20
  37. └────┴──────┴─────┴────────┘
  38. #执行 optimize命令手动合并分区数据
  39. node1 :) optimize table t_replacing_mt;
  40. #查询表 t_replacing_mt 中的数据
  41. node1 :) select * from t_replacing_mt;
  42. ┌─id─┬─name─┬─age─┬─gender─┐
  43. 2 李四 19
  44. └────┴──────┴─────┴────────┘
  45. ┌─id─┬─name─┬─age─┬─gender─┐
  46. 1 张三 10
  47. 3 王五 20
  48. └────┴──────┴─────┴────────┘

注意:通过以上测试可以发现,ClickHouse ReplacingMergeTree中不指定[ver]列时,当插入排序字段相同的数据时,保留最新一条数据。

3、测试指定[ver]列时,插入相同排序字段的数据,保留当前[ver]列最大值

  1. #删除表 t_replacing_mt 重新创建,使用ReplacingMergeTree引擎,指定[ver]
  2. node1 :) create table t_replacing_mt(
  3. :-] id UInt8,
  4. :-] name String,
  5. :-] age UInt8,
  6. :-] gender String
  7. :-] ) engine = ReplacingMergeTree(age)
  8. :-] order by id
  9. :-] primary key id
  10. :-] partition by gender;
  11. #向表 t_replacing_mt 中插入数据:
  12. node1 :) insert into t_replacing_mt values (1,'张三',18,'男'),
  13. :-] (2,'李四',19,'女'),
  14. :-] (3,'王五',20,'男');
  15. #查询表 t_replacing_mt中数据:
  16. node1 :) select * from t_replacing_mt ;
  17. ┌─id─┬─name─┬─age─┬─gender─┐
  18. 1 张三 18
  19. 3 王五 20
  20. └────┴──────┴─────┴────────┘
  21. ┌─id─┬─name─┬─age─┬─gender─┐
  22. 2 李四 19
  23. └────┴──────┴─────┴────────┘
  24. #向表 t_replacing_mt 中插入排序字段相同的一行数据
  25. node1 :) insert into t_replacing_mt values (1,'张三',10,'男');
  26. #查看表 t_replacing_mt中的数据
  27. node1 :) select * from t_replacing_mt;
  28. ┌─id─┬─name─┬─age─┬─gender─┐
  29. 1 张三 10
  30. └────┴──────┴─────┴────────┘
  31. ┌─id─┬─name─┬─age─┬─gender─┐
  32. 1 张三 18
  33. 3 王五 20
  34. └────┴──────┴─────┴────────┘
  35. ┌─id─┬─name─┬─age─┬─gender─┐
  36. 2 李四 19
  37. └────┴──────┴─────┴────────┘
  38. #对表 t_replacing_mt中的数据执行手动分区合并
  39. node1 :) optimize table t_replacing_mt;
  40. #查看表 t_replacing_mt中的数据
  41. node1 :) select * from t_replacing_mt;
  42. ┌─id─┬─name─┬─age─┬─gender─┐
  43. 2 李四 19
  44. └────┴──────┴─────┴────────┘
  45. ┌─id─┬─name─┬─age─┬─gender─┐
  46. 1 张三 18
  47. 3 王五 20
  48. └────┴──────┴─────┴────────┘

注意:通过以上测试可以发现,在ClickHouse中创建ReplacingMergeTree时,如果指定了[ver]列,当存在Order by字段重复时,会保留ver列最大值对应的行。

4、测试不同分区中有相同的Order by 字段时,不去重

  1. #删除表 t_replacing_mt ,重新创建
  2. node1 :) create table t_replacing_mt(
  3. :-] id UInt8,
  4. :-] name String,
  5. :-] age UInt8,
  6. :-] gender String
  7. :-] ) engine = ReplacingMergeTree()
  8. :-] order by id
  9. :-] primary key id
  10. :-] partition by gender;
  11. #向表 t_replacing_mt 中插入以下数据:
  12. node1 :) insert into t_replacing_mt values (1,'张三',18,'男'),
  13. :-] (2,'李四',19,'女'),
  14. :-] (3,'王五',20,'男');
  15. #再次向表 t_replacing_mt 中插入以下数据:
  16. node1 :) insert into t_replacing_mt values (1,'张三三',10,'女');
  17. #对表 t_replacing_mt中的数据执行手动分区合并
  18. node1 :) optimize table t_replacing_mt;
  19. #查看表中的数据
  20. node1 :) select * from t_replacing_mt;
  21. ┌─id─┬─name───┬─age─┬─gender─┐
  22. 1 张三三 10
  23. 2 李四 19
  24. └───┴──────┴────┴─────┘
  25. ┌─id─┬─name─┬─age─┬─gender─┐
  26. 1 张三 18
  27. 3 王五 20
  28. └───┴────┴────┴─────┘

注意:通过以上测试可以发现,在ClickHouse中创建ReplacingMergeTree时,不同分区中相同的Order by 字段不会去重。


  • 📢博客主页:https://lansonli.blog.csdn.net
  • 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
  • 📢本文由 Lansonli 原创,首发于 CSDN博客🙉
  • 📢停下休息的时候不要忘了别人还在奔跑,希望大家抓紧时间学习,全力奔赴更美好的生活✨

本文转载自: https://blog.csdn.net/xiaoweite1/article/details/126246334
版权归原作者 Lansonli 所有, 如有侵权,请联系我们删除。

“大数据ClickHouse(九):MergeTree系列表引擎之ReplacingMergeTree”的评论:

还没有评论