- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
MergeTree 系列的引擎被设计用于插入极大量的数据到一张表当中。数据可以以数据片段的形式一个接着一个的快速写入,数据片段在后台按照一定的规则进行合并。相比在插入时不断修改(重写)已存储的数据,这种策略会高效很多.
ReplacingMergeTree 引擎和 MergeTree 的不同之处在于它会删除排序键值相同的重复项。 数据的去重只会在数据合并期间进行。合并会在后台一个不确定的时间进行,因此你无法预先作出计划。有一些数据可能仍未被处理。尽管你可以调用 OPTIMIZE 语句发起计划外的合并,但请不要依靠它,因为 OPTIMIZE 语句会引发对数据的大量读写.
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE = ReplacingMergeTree([ver])
[PARTITION BY expr]
[PRIMARY KEY expr]
[ORDER BY expr]
[SAMPLE BY expr]
[TTL expr [DELETE|TO DISK 'xxx'|TO VOLUME 'xxx'], ...]
[SETTINGS name=value, ...]
参数介绍 。
ver — 版本列。类型为 UInt*, Date 或 DateTime。可选参数。 在数据合并的时候,ReplacingMergeTree 从所有具有相同排序键的行中选择一行留下: 1.如果 ver 列未指定,保留最后一条。 2.如果 ver 列已指定,保留 ver 值最大的版本.
PRIMARY KEY expr 主键。如果要 选择与排序键不同的主键,在这里指定,可选项。 默认情况下主键跟排序键(由 ORDER BY 子句指定)相同。 因此,大部分情况下不需要再专门指定一个 PRIMARY KEY 子句.
SAMPLE BY EXPR 用于抽样的表达式,可选项 。
PARTITION BY expr 分区键 。
ORDER BY expr 排序键 。
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE = Distributed(cluster, database, table[, sharding_key[, policy_name]])
[SETTINGS name=value, ...]
参数介绍 。
Clickhouse的部署,分为单机模式和集群模式,还可以开启副本。两种模式,数据表在创建语法、创建步骤和后续的使用方式上,存在一定的差异.
在定义表结构时,需要指定不同的键,作用如下.
分片:所有分片节点的权重加和得到S,可以理解为sharing动作取模的依据,权重X=W/S。分片键 Mod S 得到的值,与哪个分片节点匹配,则会写入哪个分片。不同分片可能存在于不同的集群节点,即便不同分片在同一节点,但ck在merge时,维度是同一分区+同一分片,这是物理文件的合并范围。 如果我们权重分别设置为1,2,3 那么总权重是6,那么总区间就是[0,6),排在shard配置第一位的node01,权重占比为1/6,所以属于区间[0,1),排在shard配置第二位的node02,占比2/6,所以区间为[1,3),至于最后的node03就是[3,6).所以如果rand()产生的数字除以6取余落在哪个区间,数据就会分发到哪个shard,通过权重配置,可以实现数据按照想要的比重分配. 。
在分布式模式下,ClickHouse会将数据分为多个分片,并且分布到不同节点上。不同的分片策略在应对不同的SQL Pattern时,各有优势。ClickHouse提供了丰富的- - - sharding策略,让业务可以根据实际需求选用.
以MySQL的分库分表场景为例:
这个MySQL的例子,与CK的分区+分片+副本在逻辑上基本一致。分区理解为数据写入哪个表,分片可以理解为数据写入哪个库,副本则是从节点的拷贝.
Clickhouse分片是集群模式下的概念,可以类比MySQL的Sharding逻辑,副本是为了解决Sharing方案下的高可用场景所存在的。 下图描述了一张Merge表的各类键的关系,也能反映出一条记录的写入过程.
理清了分区与分片的概念,也就明白CK的数据合并,为什么要限制相同分区、相同分片,因为它们影响数据的存储位置,merge操作只能针对相同物理位置(分区目录)的数据进行操作,而分片会影响数据存储在哪个节点上。 一句话,使用CK的ReplacingMergeTree引擎的去重特性,期望去重的数据,必须满足拥有 相同排序键、同一分区、同一分片。 接下来针对这一要求,在数据上进行验证.
这里是要验证上面的结论,“ 期望去重的数据,必须满足在相同排序键、同一分区、同一分片 ”; 首先拥有相同排序键才会在merge操作时进行判断为重复,因此保证测试数据的排序键相同;剩余待测试场景则是分区与分片。 由此进行场景设置:
场景1: 相同记录,能够写入同一分区、同一分片 。
一次执行3条插入,插入本地表 [main_id=101,sku_id=SKU0002;barnd_code=BC01,BC02,BC03] select * from test_ps.sku_detail_same_partition_same_shard_all,
分三次执行,插入本地表 [main_id=101,sku_id=SKU0001;barnd_code=BC01,BC02,BC03] select * from test_ps.sku_detail_same_partition_same_shard_all,
分三次执行,插入分布式表 [main_id=101,sku_id=SKU0001;barnd_code=BC001,BC002,BC003] select * from test_ps.sku_detail_same_partition_same_shard_all,
select * from test_ps.sku_detail_same_partition_same_shard_all final,
结论1 1.采用分布式表插入数据,保证分片键、分区键的值相同,才能保证merge去重成功 排除本地表插入场景 2.采用本地表插入数据,在分片键、分区键相同的情况下,无法保证merge去重 。
后面直接验证插入分布式表场景.
场景2:相同记录,能够写入同一分区,不同分片 。
分三次执行,插入分布式表 [main_id=103,sku_id=SKU0003;barnd_code=BC301,BC302,BC303] 检查数据插入状态 select * from test_ps.sku_detail_same_partition_diff_shard_all where main_id =103 ,
检查merge的去重结果 select * from test_ps.sku_detail_same_partition_diff_shard_all final where main_id =103 ,
分五次执行,插入分布式表 [main_id=104,sku_id=SKU0004;barnd_code=BC401,BC402,BC403,BC404,BC405] 检查数据插入状态 select * from test_ps.sku_detail_same_partition_diff_shard_all where main_id =104 ,
检查merge的去重结果 select * from test_ps.sku_detail_same_partition_diff_shard_all final where main_id =104 ,
结论2 。
采用分布式表插入数据,保证分区键的值相同、分片键的值随机,无法保证merge去重 。
场景3:相同记录,能够写入不同分区,不同分片 。
分五次执行,插入分布式表 [main_id=105,sku_id=SKU0005;barnd_code=BC501,BC502,BC503,BC504,BC505] 。
检查数据插入状态 select * from test_ps.sku_detail_diff_partition_diff_shard_all where main_id =105 ,
检查merge的去重结果 select * from test_ps.sku_detail_diff_partition_diff_shard_all final where main_id =105,
结论3 采用分布式表插入数据,分区键的值与排序键不一致、分片键的值随机,无法保证merge去重 。
场景4:相同记录,能够写入 不同分区、相同分片 。
分六次执行,插入分布式表 [main_id=106,sku_id=SKU0006;barnd_code=BC601,BC602,BC603,BC604,BC605,BC606] 。
检查数据插入状态 select * from test_ps.sku_detail_diff_partition_same_shard_all where main_id =106 ,
检查merge的去重结果 select * from test_ps.sku_detail_diff_partition_same_shard_all final where main_id =106,
此场景,经过第二天检索,数据并没有进行merge,而是用final关键字依然能检索出去重后的结果。也就是说final关键字只是在内存中进行去重,由于所在分区不同,文件是没有进行merge合并的,也就没有去重。反观相同分区、相同分片的数据表,数据已经完成了merge合并,普通检索只能得到一条记录.
结论4 采用分布式表插入数据,分区键的值与排序键不一致、分片键的值固定,无法实现merge去重 。
以下均采用普通查询,发现如下情况 。
select * from test_ps.sku_detail_same_partition_same_shard_all,
select * from test_ps.sku_detail_same_partition_diff_shard_all,
select * from test_ps.sku_detail_diff_partition_diff_shard_all,
select * from test_ps.sku_detail_diff_partition_same_shard_all,
根据测试结果,在不同场景下的合并情况:
在Clickhouse的ReplacingMergeTree进行merge操作时,是根据排序键(order by)来识别是否重复、是否需要合并。而分区和分片,影响的是数据的存储位置,在哪个集群节点、在哪个文件目录。那么最终ReplacingMergeTree表引擎在合并时,只会在当前节点、且物理位置在同一表目录下的数据进行merge操作.
最后,我们在设计表时,如果期望利用到ReplacingMergeTree自动去重的特性,那么 必须使其存储在相同分区、相同分片下; 而在设置分区键、分片键时,二者不要求必须相同,但必须稳定,稳定的含义是入参相同出参必须相同.
。
最后此篇关于Clickhouse表引擎探究-ReplacingMergeTree的文章就讲到这里了,如果你想了解更多关于Clickhouse表引擎探究-ReplacingMergeTree的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有一台 MySQL 服务器和一台 PostgreSQL 服务器。 需要从多个表中复制或重新插入一组数据 MySQL 流式传输/同步到 PostgreSQL 表。 这种复制可以基于时间(Sync)或事
如果两个表的 id 彼此相等,我尝试从一个表中获取数据。这是我使用的代码: SELECT id_to , email_to , name_to , status_to
我有一个 Excel 工作表。顶行对应于列名称,而连续的行每行代表一个条目。 如何将此 Excel 工作表转换为 SQL 表? 我使用的是 SQL Server 2005。 最佳答案 这取决于您使用哪
我想合并两个 Django 模型并创建一个模型。让我们假设我有第一个表表 A,其中包含一些列和数据。 Table A -------------- col1 col2 col3 col
我有两个表:table1,table2,如下所示 table1: id name 1 tamil 2 english 3 maths 4 science table2: p
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 1 年前。 Improve th
下面两个语句有什么区别? newTable = orginalTable 或 newTable.data(originalTable) 我怀疑 .data() 方法具有性能优势,因为它在标准 AX 中
我有一个表,我没有在其中显式定义主键,它并不是真正需要的功能......但是一位同事建议我添加一个列作为唯一主键以随着数据库的增长提高性能...... 谁能解释一下这是如何提高性能的? 没有使用索引(
如何将表“产品”中的产品记录与其不同表“图像”中的图像相关联? 我正在对产品 ID 使用自动增量。 我觉得不可能进行关联,因为产品 ID 是自动递增的,因此在插入期间不可用! 如何插入新产品,获取产品
我有一个 sql 表,其中包含关键字和出现次数,如下所示(尽管出现次数并不重要): ____________ dog | 3 | ____________ rat | 7 | ____
是否可以使用目标表中的LAST_INSERT_ID更新源表? INSERT INTO `target` SELECT `a`, `b` FROM `source` 目标表有一个自动增量键id,我想将其
我正在重建一个搜索查询,因为它在“我看到的”中变得多余,我想知道什么 (albums_artists, artists) ( ) does in join? is it for boosting pe
以下是我使用 mysqldump 备份数据库的开关: /usr/bin/mysqldump -u **** --password=**** --single-transaction --databas
我试图获取 MySQL 表中的所有行并将它们放入 HTML 表中: Exam ID Status Assigned Examiner
如何查询名为 photos 的表中的所有记录,并知道当前用户使用单个查询将哪些结果照片添加为书签? 这是我的表格: -- -- Table structure for table `photos` -
我的网站都在 InnoDB 表上运行,目前为止运行良好。现在我想知道在我的网站上实时发生了什么,所以我将每个页面浏览量(页面、引荐来源网址、IP、主机名等)存储在 InnoDB 表中。每秒大约有 10
我在想我会为 mysql 准备两个表。一个用于存储登录信息,另一个用于存储送货地址。这是传统方式还是所有内容都存储在一张表中? 对于两个表...有没有办法自动将表 A 的列复制到表 B,以便我可以引用
我不是程序员,我从这个表格中阅读了很多关于如何解决我的问题的内容,但我的搜索效果不好 我有两张 table 表 1:成员 id*| name | surname -------------------
我知道如何在 ASP.NET 中显示真实表,例如 public ActionResult Index() { var s = db.StaffInfoDBSet.ToList(); r
我正在尝试运行以下查询: "insert into visits set source = 'http://google.com' and country = 'en' and ref = '1234
我是一名优秀的程序员,十分优秀!