clickHouse的ReplacingMergeTree存儲引擎使用


一、ReplacingMergeTree作用
​ ClickHouse中最常用也是最基礎的表引擎為MergeTree,在它的功能基礎上添加特定功能就構成了MergeTree系列引擎。MergeTree支持主鍵,但主鍵主要用來縮小查詢范圍,且不具備唯一性約束,可以正常寫入相同主鍵的數據。但在一些情況下,可能需要表中沒有主鍵重復的數據。ReplacingMergeTree就是在MergeTree的基礎上加入了去重的功能,但它僅會在合並分區時,去刪除重復的數據,寫入相同數據時並不會引發異常。(主要應用於記錄分區內記錄唯一時刻狀態,用於分析用戶系統較多【例如用戶某日最后登錄時間】)

二、功能示例
創建一張ReplacingMergeTree的表和創建MergeTree類似,修改引擎即可。ReplacingMergeTree引擎創建規范為:ENGINE = ReplacingMergeTree([ver]),其中ver為選填參數,它需要指定一個UInt8/UInt16、Date或DateTime類型的字段,它決定了數據去重時所用的算法,如果沒有設置該參數,合並時保留分組內的最后一條數據;如果指定了該參數,則保留ver字段取值最大的那一行。

1、不指定ver參數 

-- 創建未指定ver參數ReplacintMergeTree引擎的表
CREATE TABLE replac_merge_test
(
    `id` String, 
    `code` String, 
    `create_time` DateTime
)
ENGINE = ReplacingMergeTree()
PARTITION BY toYYYYMM(create_time)
PRIMARY KEY id
ORDER BY (id, code)

 

ReplacingMergeTree會根據ORDER BY所聲明的表達式去重

-- 在上述表中插入數據
insert into replac_merge_test values ('A000', 'code1', now()),('A000', 'code1', now()), ('A001', 'code1', now()), ('A001', 'code2', now()), ('A0002', 'code2', now()); 

-- 查詢當前數據 select * from replac_merge_test;
┌─id────┬─code──┬─────────create_time─┐
│ A000 │ code1 │
2020-07-28 21:23:48
│ A000 │ code1 │
2020-07-28 21:30:00
│ A0002 │ code2 │
2020-07-28 21:23:48
│ A001 │ code1 │
2020-07-28 21:23:48
│ A001 │ code2 │
2020-07-28 21:30:00
└───────┴───────┴─────────────────────┘

-- 強制進行分區合並 optimize table replac_merge_test FINAL;

-- 再次查詢數據 select * from replac_merge_test;
┌─id────┬─code──┬─────────create_time─┐
│ A000 │ code1 │
2020-07-28 21:30:00
│ A0002 │ code2 │
2020-07-28 21:23:48
│ A001 │ code1 │
2020-07-28 21:23:48
│ A001 │ code2 │
2020-07-28 21:30:00
└───────┴───────┴─────────────────────┘

 

通過上面示例可以看到,id、code相同的字段’A000’,'code1’被去重剩余一條數據,由於創建表時沒有設置ver參數,故保留分組內的最后一條數據(create_time字段)

 

-- 再次使用insert插入一條數據
insert into replac_merge_test values ('A001', 'code1', '2020-07-28 21:30:00');
 
-- 查詢表中數據
select * from replac_merge_test;
┌─id────┬─code──┬─────────create_time─┐
│ A000  │ code1 │ 2020-07-28 21:30:00 │
│ A0002 │ code2 │ 2020-07-28 21:23:48 │
│ A001  │ code1 │ 2020-07-28 21:23:48 │
│ A001  │ code2 │ 2020-07-28 21:30:00 │
└───────┴───────┴─────────────────────┘
┌─id───┬─code──┬─────────create_time─┐
│ A001 │ code1 │ 2020-07-28 21:30:00 │
└──────┴───────┴─────────────────────┘

 

可以看到,再次插入重復數據時,查詢仍然會存在重復。在ClickHouse中,默認一條insert插入的數據為同一個數據分區,不同insert插入的數據為不同的分區,所以ReplacingMergeTree是以分區為單位進行去重的,也就是說只有在相同的數據分區內,重復數據才可以被刪除掉。只有數據合並完成后,才可以使用引擎特性進行去重。

2、指定ver參數 

-- 創建指定ver參數ReplacingMergeTree引擎的表
CREATE TABLE replac_merge_ver_test
(
    `id` String, 
    `code` String, 
    `create_time` DateTime
)
ENGINE = ReplacingMergeTree(create_time)
PARTITION BY toYYYYMM(create_time)
PRIMARY KEY id
ORDER BY (id, code)
 
-- 插入測試數據
insert into replac_merge_ver_test values('A000', 'code1', '2020-07-10 21:35:30'),('A000', 'code1', '2020-07-15 21:35:30'),('A000', 'code1', '2020-07-05 21:35:30'),('A000', 'code1', '2020-06-05 21:35:30');
 
-- 查詢數據
select * from replac_merge_ver_test;
┌─id───┬─code──┬─────────create_time─┐
│ A000 │ code1 │ 2020-06-05 21:35:30 │
└──────┴───────┴─────────────────────┘
┌─id───┬─code──┬─────────create_time─┐
│ A000 │ code1 │ 2020-07-10 21:35:30 │
│ A000 │ code1 │ 2020-07-15 21:35:30 │
│ A000 │ code1 │ 2020-07-05 21:35:30 │
└──────┴───────┴─────────────────────┘
 
-- 強制進行分區合並
optimize table replac_merge_ver_test FINAL;
 
-- 查詢數據
select * from replac_merge_ver_test;
┌─id───┬─code──┬─────────create_time─┐
│ A000 │ code1 │ 2020-07-15 21:35:30 │
└──────┴───────┴─────────────────────┘
┌─id───┬─code──┬─────────create_time─┐
│ A000 │ code1 │ 2020-06-05 21:35:30 │
└──────┴───────┴─────────────────────┘

 

由於上述創建表是以create_time的年月來進行分區的,可以看出不同的數據分區,ReplacingMergeTree並不會進行去重,並且在相同數據分區內,指定ver參數后,會保留同一組數據內create_time時間最大的那一行數據。

三、ReplacingMergeTree引擎總結
①使用ORDER BY排序鍵,作為判斷數據是否重復的唯一鍵
②只有在合並分區時,才會觸發數據的去重邏輯
③刪除重復數據,是以數據分區為單位。同一個數據分區的重復數據才會被刪除,不同數據分區的重復數據仍會保留
④在進行數據去重時,由於已經基於ORDER BY排序,所以可以找到相鄰的重復數據
故數據去重策略為:
       1)若指定了ver參數,則會保留重復數據中,ver字段最大的那一行
       2)若未指定ver參數,則會保留重復數據中最末的那一行數據


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM