日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Clickhouse如何实现数据更新

發布時間:2023/12/8 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Clickhouse如何实现数据更新 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Clickhouse作為一個OLAP數據庫,它對事務的支持非常有限。Clickhouse提供了MUTATION操作(通過ALTER TABLE語句)來實現數據的更新、刪除,但這是一種“較重”的操作,它與標準SQL語法中的UPDATE、DELETE不同,是異步執行的,對于批量數據不頻繁的更新或刪除比較有用 。除了MUTATION操作,Clickhouse還可以通過CollapsingMergeTree、VersionedCollapsingMergeTree、ReplacingMergeTree結合具體業務數據結構來實現數據的更新、刪除,這三種方式都通過INSERT語句插入最新的數據,新數據會“抵消”或“替換”掉老數據,但是“抵消”或“替換”都是發生在數據文件后臺Merge時,也就是說,在Merge之前,新數據和老數據會同時存在。因此,我們需要在查詢時做一些處理,避免查詢到老數據。Clickhouse官方文檔提供了使用CollapsingMergeTree、VersionedCollapsingMergeTree的指導 。相比于CollapsingMergeTree、VersionedCollapsingMergeTree需要標記位字段、版本字段,用ReplacingMergeTree來實現數據的更新刪除會更加方便,這里著重介紹一下如何用ReplacingMergeTree來實現數據的更新刪除。

我們假設一個需要頻繁數據更新的場景,如某市用戶用電量的統計,我們知道,用戶的用電量每分每秒都有可能發生變化,所以會涉及到數據頻繁的更新。首先,創建一張表來記錄某市所有用戶的用電量。

CREATE TABLE IF NOT EXISTS default.PowerConsumption_local ON CLUSTER default_cluster (User_ID UInt64 COMMENT '用戶ID',Record_Time DateTime DEFAULT toDateTime(0) COMMENT '電量記錄時間',District_Code UInt8 COMMENT '用戶所在行政區編碼',Address String COMMENT '用戶地址',Power UInt64 COMMENT '用電量',Deleted BOOLEAN DEFAULT 0 COMMENT '數據是否被刪除' ) ENGINE = ReplicatedReplacingMergeTree('/clickhouse/tables/default.PowerConsumption_local/{shard}', '{replica}', Record_Time) ORDER BY (User_ID, Address) PARTITION BY District_Code; CREATE TABLE default.PowerConsumption ON CLUSTER default_cluster AS default.PowerConsumption_local ENGINE = Distributed(default_cluster, default, PowerConsumption_local, rand());

PowerConsumption_local為本地表,PowerConsumption為對應的分布式表。其中PowerConsumption_local使用ReplicatedReplacingMergeTree表引擎,第三個參數‘Record_Time’表示相同主鍵的多條數據,只會保留Record_Time最大的一條,我們正是利用ReplacingMergeTree的這一特性來實現數據的更新刪除。因此,在選擇主鍵時,我們需要確保主鍵唯一。這里我們選擇(User_ID, Address)來作為主鍵,因為用戶ID加上用戶的地址可以確定唯一的一個電表,不會出現第二個相同的電表,所以對于某個電表多條數據,只會保留電量記錄時間最新的一條。

然后我們向表中插入10條數據:

INSERT INTO default.PowerConsumption VALUES (0, '2021-10-30 12:00:00', 3, 'Yanta', rand64() % 1000 + 1, 0); INSERT INTO default.PowerConsumption VALUES (1, '2021-10-30 12:10:00', 2, 'Beilin', rand64() % 1000 + 1, 0); INSERT INTO default.PowerConsumption VALUES (2, '2021-10-30 12:15:00', 1, 'Weiyang', rand64() % 1000 + 1, 0); INSERT INTO default.PowerConsumption VALUES (3, '2021-10-30 12:18:00', 1, 'Gaoxin', rand64() % 1000 + 1, 0); INSERT INTO default.PowerConsumption VALUES (4, '2021-10-30 12:23:00', 2, 'Qujiang', rand64() % 1000 + 1, 0); INSERT INTO default.PowerConsumption VALUES (5, '2021-10-30 12:43:00', 3, 'Baqiao', rand64() % 1000 + 1, 0); INSERT INTO default.PowerConsumption VALUES (6, '2021-10-30 12:45:00', 1, 'Lianhu', rand64() % 1000 + 1, 0); INSERT INTO default.PowerConsumption VALUES (7, '2021-10-30 12:46:00', 3, 'Changan', rand64() % 1000 + 1, 0); INSERT INTO default.PowerConsumption VALUES (8, '2021-10-30 12:55:00', 1, 'Qianhan', rand64() % 1000 + 1, 0); INSERT INTO default.PowerConsumption VALUES (9, '2021-10-30 12:57:00', 4, 'Fengdong', rand64() % 1000 + 1, 0);

表中數據如圖所示:

假如現在我們要行政區編碼為1的所有用戶數據都需要更新,我們插入最新的數據:

INSERT INTO default.PowerConsumption VALUES (2, now(), 1, 'Weiyang', rand64() % 100 + 1, 0); INSERT INTO default.PowerConsumption VALUES (3, now(), 1, 'Gaoxin', rand64() % 100 + 1, 0); INSERT INTO default.PowerConsumption VALUES (6, now(), 1, 'Lianhu', rand64() % 100 + 1, 0); INSERT INTO default.PowerConsumption VALUES (8, now(), 1, 'Qianhan', rand64() % 100 + 1, 0);

插入最新數據后,表中數據如圖所示:

可以看到,此時新插入的數據與老數據同時存在于表中,因為后臺數據文件還沒有進行Merge,“替換”還沒有發生,這時就需要對查詢語句做一些處理來過濾掉老數據,函數argMax(a, b)可以按照b的最大值取a的值,所以通過如下查詢語句就可以只獲取到最新數據:

SELECTUser_ID,max(Record_Time) AS R_Time,District_Code,Address,argMax(Power, Record_Time) AS Power,argMax(Deleted, Record_Time) AS Deleted FROM default.PowerConsumption GROUP BYUser_ID,Address,District_Code HAVING Deleted = 0;

查詢結果如下圖:

為了更方便我們查詢,這里可以創建一個視圖:

CREATE VIEW PowerConsumption_view ON CLUSTER default_cluster AS SELECTUser_ID,max(Record_Time) AS R_Time,District_Code,Address,argMax(Power, Record_Time) AS Power,argMax(Deleted, Record_Time) AS Deleted FROM default.PowerConsumption GROUP BYUser_ID,Address,District_Code HAVING Deleted = 0;

通過該視圖,可以查詢到最新的數據:

假如現在我們又需要刪除用戶ID為0的數據,我們需要插入一條User_ID字段為0,Deleted字段為1的數據:

INSERT INTO default.PowerConsumption VALUES (0, now(), 3, 'Yanta', null, 1);

查詢視圖,發現User_ID為0的數據已經查詢不到了:

通過如上方法,我們可以實現Clickhouse數據的更新、刪除,就好像在使用OLTP數據庫一樣,但我們應該清楚,實際上老數據真正的刪除是在數據文件Merge時發生的,只有在Merge后,老數據才會真正物理意義上的刪除掉。

本文由華為云發布。

總結

以上是生活随笔為你收集整理的Clickhouse如何实现数据更新的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。