09_ClickHouse,ReplacingMergeTree,案例,根據排序鍵去重,使用版本引數的去重(學習筆記)

to.to發表於2020-12-09

7.ReplacingMergeTree
7.1.ReplacingMergeTree
7.2.案例
7.2.1.示例1:根據排序鍵去重
7.2.2.示例2:使用版本引數的去重

7.ReplacingMergeTree

7.1.ReplacingMergeTree

  1. 刪除具有相同排序鍵值的重複項。
  2. 資料去重是在合併期間進行的。
  3. 後臺的合併操作在未知的時間觸發,因此使用者無法對合並進行計劃。
  4. 可使用OPTIMIZE語句執行計劃外的合併,但OPTIMIZE是一個很重的操作。
  5. ReplacingMergeTree適合清除後臺的重複資料以節省空間。

指定表引擎:
ENGINE = ReplacingMergeTree([ver])
引數:ver,版本列。版本列的型別為UInt*、Date或DateTime。可選引數。

合併的時候,ReplacingTree從所有相同主鍵的行中選擇一行留下:如果ver未指定,選擇最後一條。如果指定了ver列,選擇ver值最大的版本。

7.2.案例

7.2.1.示例1:根據排序鍵去重

建表:

DROP TABLE replacingMergeTreeDemo;
CREATE TABLE replacingMergeTreeDemo
(
    UserID UInt32,
    CounterID UInt32,
    UserName String,
    EventDate Date
) ENGINE = ReplacingMergeTree()
ORDER BY (UserID, CounterID)
PRIMARY KEY (UserID);

執行效果:

xxxxx :) CREATE TABLE replacingMergeTreeDemo
:-] (
:-]     UserID UInt32,
:-]     CounterID UInt32,
:-]     UserName String,
:-]     EventDate Date
:-] ) ENGINE = ReplacingMergeTree()
:-] ORDER BY (UserID, CounterID)
:-] PRIMARY KEY (UserID);

CREATE TABLE replacingMergeTreeDemo
(
    `UserID` UInt32,
    `CounterID` UInt32,
    `UserName` String,
    `EventDate` Date
)
ENGINE = ReplacingMergeTree()
PRIMARY KEY UserID
ORDER BY (UserID, CounterID)

Ok.

0 rows in set. Elapsed: 0.055 sec. 

xxxxx :)

2 插入資料
分三批次插入資料,為了觀察效果,下面的三段指令碼依次按順序分別執行,不要一起執行:
批次1:

insert into replacingMergeTreeDemo values(1,100,'xiaohe1','2020-04-21');
insert into replacingMergeTreeDemo values(2,100,'xiaohe2','2020-04-22');
insert into replacingMergeTreeDemo values(3,102,'xiaohe3','2020-04-23');

插入後的效果為:

xxxxx :) select * from replacingMergeTreeDemo;

SELECT *
FROM replacingMergeTreeDemo

┌─UserID─┬─CounterID─┬─UserName─┬──EventDate─┐
│      3102 │ xiaohe3  │ 2020-04-23 │
└────────┴───────────┴──────────┴────────────┘
┌─UserID─┬─CounterID─┬─UserName─┬──EventDate─┐
│      2100 │ xiaohe2  │ 2020-04-22 │
└────────┴───────────┴──────────┴────────────┘
┌─UserID─┬─CounterID─┬─UserName─┬──EventDate─┐
│      1100 │ xiaohe1  │ 2020-04-21 │
└────────┴───────────┴──────────┴────────────┘

3 rows in set. Elapsed: 0.009 sec. 

xxxxx :)

批次2:

insert into replacingMergeTreeDemo values(3,103,'xiaohe3','2020-04-23');
insert into replacingMergeTreeDemo values(2,101,'xiaohe2','2020-04-24');
insert into replacingMergeTreeDemo values(1,100,'xiaohe1','2020-04-20');

插入後的效果為:

xxxxx :) select * from replacingMergeTreeDemo;

SELECT *
FROM replacingMergeTreeDemo

┌─UserID─┬─CounterID─┬─UserName─┬──EventDate─┐
│      1100 │ xiaohe1  │ 2020-04-20 │
└────────┴───────────┴──────────┴────────────┘
┌─UserID─┬─CounterID─┬─UserName─┬──EventDate─┐
│      1100 │ xiaohe1  │ 2020-04-21 │
│      2100 │ xiaohe2  │ 2020-04-22 │
│      2101 │ xiaohe2  │ 2020-04-24 │
│      3102 │ xiaohe3  │ 2020-04-23 │
│      3103 │ xiaohe3  │ 2020-04-23 │
└────────┴───────────┴──────────┴────────────┘

批次3:

insert into replacingMergeTreeDemo values(2,100,'xiaohe2','2020-04-23');

插入後的效果:

xxxxx :) select * from replacingMergeTreeDemo;
SELECT *
FROM replacingMergeTreeDemo

┌─UserID─┬─CounterID─┬─UserName─┬──EventDate─┐
│      2100 │ xiaohe2  │ 2020-04-23 │
└────────┴───────────┴──────────┴────────────┘
┌─UserID─┬─CounterID─┬─UserName─┬──EventDate─┐
│      1100 │ xiaohe1  │ 2020-04-20 │
└────────┴───────────┴──────────┴────────────┘
┌─UserID─┬─CounterID─┬─UserName─┬──EventDate─┐
│      1100 │ xiaohe1  │ 2020-04-21 │
│      2100 │ xiaohe2  │ 2020-04-22 │
│      2101 │ xiaohe2  │ 2020-04-24 │
│      3102 │ xiaohe3  │ 2020-04-23 │
│      3103 │ xiaohe3  │ 2020-04-23 │
└────────┴───────────┴──────────┴────────────┘

7 rows in set. Elapsed: 0.007 sec. 

xxxxx :) 

如上所示,它並沒有合併資料,這時候需要手工執行計劃外合併。

這時候就要手工執行計劃外合併:
執行命令:optimize table replacingMergeTreeDemo

xxxxx :) optimize table replacingMergeTreeDemo;

OPTIMIZE TABLE replacingMergeTreeDemo

Ok.

0 rows in set. Elapsed: 0.003 sec. 

xxxxx :) select * from replacingMergeTreeDemo;

SELECT *
FROM replacingMergeTreeDemo

┌─UserID─┬─CounterID─┬─UserName─┬──EventDate─┐
│      1100 │ xiaohe1  │ 2020-04-20 │
│      2100 │ xiaohe2  │ 2020-04-23 │
│      2101 │ xiaohe2  │ 2020-04-24 │
│      3102 │ xiaohe3  │ 2020-04-23 │
│      3103 │ xiaohe3  │ 2020-04-23 │
└────────┴───────────┴──────────┴────────────┘

5 rows in set. Elapsed: 0.006 sec. 

xxxxx :)

從這個示例可以發現,ReplacingMergeTree是根據排序項對資料去重的,而不是根據主鍵。

7.2.2.示例2:使用版本引數的去重

在示例1中, 我們簡單觀察可以發現, 去重後,保留的記錄是最後一條記錄。
如果指定了版本,則保留版本列的值最大的記錄。
1.建表
使用EventDate列作為版本欄位。

DROP TABLE replacingMergeTreeDemo;
CREATE TABLE replacingMergeTreeDemo
(
    UserID UInt32,
    CounterID UInt32,
    UserName String,
    EventDate Date
) ENGINE = ReplacingMergeTree(EventDate)
ORDER BY (UserID, CounterID)
PRIMARY KEY (UserID);

2.插入資料
批次1:

insert into replacingMergeTreeDemo values(1,100,'xiaohe1','2020-06-21');
insert into replacingMergeTreeDemo values(2,100,'xiaohe2','2020-11-27');
insert into replacingMergeTreeDemo values(3,102,'xiaohe3','2020-04-23');

批次2:

insert into replacingMergeTreeDemo values(3,103,'xiaohe3','2020-04-23');
insert into replacingMergeTreeDemo values(2,101,'xiaohe2','2020-04-24');
insert into replacingMergeTreeDemo values(1,100,'xiaohe1','2020-04-20');

批次3:

insert into replacingMergeTreeDemo values(2,100,'xiaohe2','2020-04-23');

檢視資料:

xxxxx :) select * from replacingMergeTreeDemo;

SELECT *
FROM replacingMergeTreeDemo

┌─UserID─┬─CounterID─┬─UserName─┬──EventDate─┐
│      2100 │ xiaohe2  │ 2020-04-23 │
└────────┴───────────┴──────────┴────────────┘
┌─UserID─┬─CounterID─┬─UserName─┬──EventDate─┐
│      1100 │ xiaohe1  │ 2020-04-20 │
└────────┴───────────┴──────────┴────────────┘
┌─UserID─┬─CounterID─┬─UserName─┬──EventDate─┐
│      1100 │ xiaohe1  │ 2020-06-21 │
│      2100 │ xiaohe2  │ 2020-11-27 │
│      2101 │ xiaohe2  │ 2020-04-24 │
│      3102 │ xiaohe3  │ 2020-04-23 │
│      3103 │ xiaohe3  │ 2020-04-23 │
└────────┴───────────┴──────────┴────────────┘

7 rows in set. Elapsed: 0.009 sec. 

xxxxx :) optimize table replacingMergeTreeDemo;

OPTIMIZE TABLE replacingMergeTreeDemo

Ok.

0 rows in set. Elapsed: 0.002 sec. 

xxxxx :) select * from replacingMergeTreeDemo;

SELECT *
FROM replacingMergeTreeDemo

┌─UserID─┬─CounterID─┬─UserName─┬──EventDate─┐
│      1100 │ xiaohe1  │ 2020-06-21 │
│      2100 │ xiaohe2  │ 2020-11-27 │
│      2101 │ xiaohe2  │ 2020-04-24 │
│      3102 │ xiaohe3  │ 2020-04-23 │
│      3103 │ xiaohe3  │ 2020-04-23 │
└────────┴───────────┴──────────┴────────────┘

5 rows in set. Elapsed: 0.005 sec. 

xxxxx :)

經過上面案例,可以看出,最終保留了如下資料:

2100 │ xiaohe2  │ 2020-11-27

從這個示例可以發現, ReplacingMergeTree根據排序項對資料去重的, 保留版本欄位列對應的最大值的記錄。

相關文章