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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

clickhouse物化视图优缺点_ClickHouse 适用场景

發布時間:2025/3/13 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 clickhouse物化视图优缺点_ClickHouse 适用场景 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Clickhouse是一個用于聯機分析處理(OLAP)的列式數據庫管理系統(columnar DBMS)。
傳統數據庫在數據大小比較小,索引大小適合內存,數據緩存命中率足夠高的情形下能正常提供服務。但殘酷的是,這種理想情形最終會隨著業務的增長走到盡頭,查詢會變得越來越慢。你可能通過增加更多的內存,訂購更快的磁盤等等來解決問題(縱向擴展),但這只是拖延解決本質問題。如果你的需求是解決怎樣快速查詢出結果,那么ClickHouse也許可以解決你的問題。

應用場景:1.絕大多數請求都是用于讀訪問的2.數據需要以大批次(大于1000行)進行更新,而不是單行更新;或者根本沒有更新操作3.數據只是添加到數據庫,沒有必要修改4.讀取數據時,會從數據庫中提取出大量的行,但只用到一小部分列5.表很“寬”,即表中包含大量的列6.查詢頻率相對較低(通常每臺服務器每秒查詢數百次或更少)7.對于簡單查詢,允許大約50毫秒的延遲8.列的值是比較小的數值和短字符串(例如,每個URL只有60個字節)9.在處理單個查詢時需要高吞吐量(每臺服務器每秒高達數十億行)10.不需要事務11.數據一致性要求較低12.每次查詢中只會查詢一個大表。除了一個大表,其余都是小表13.查詢結果顯著小于數據源。即數據有過濾或聚合。返回結果不超過單個服務器內存大小

相應地,使用ClickHouse也有其本身的限制:

1.不支持真正的刪除/更新支持 不支持事務(期待后續版本支持)2.不支持二級索引3.有限的SQL支持,join實現與眾不同4.不支持窗口功能5.元數據管理需要人工干預維護


常用SQL語法


-?列出數據庫列表show databases;-- 列出數據庫中表列表show tables;-- 創建數據庫create database test;-- 刪除一個表drop table if exists test.t1;-- 創建第一個表create /*temporary*/ table /*if not exists*/ test.m1 (id UInt16,name String) ENGINE = Memory;-- 插入測試數據insert into test.m1 (id, name) values (1, 'abc'), (2, 'bbbb');-- 查詢select * from test.m1;

默認值


默認值 的處理方面, ClickHouse 中,默認值總是有的,如果沒有顯示式指定的話,會按字段類型處理:

數字類型, 0
字符串,空字符串
數組,空數組
日期, 0000-00-00
時間, 0000-00-00 00:00:00
注:NULLs 是不支持的

數據類型


1.整型:UInt8,UInt16,UInt32,UInt64,Int8,Int16,Int32,Int64
范圍U開頭-2N/2~2N-1;非U開頭0~2^N-12.枚舉類型:Enum8,Enum16
Enum('hello'=1,'test'=-1),Enum是有符號的整型映射的,因此負數也是可以的3.字符串型:FixedString(N),String
N是最大字節數,不是字符長度,如果是UTF8字符串,那么就會占3個字節,GBK會占2字節;String可以用來替換VARCHAR,BLOB,CLOB等數據類型4.時間類型:Date5.數組類型:Array(T)
T是一個基本類型,包括arry在內,官方不建議使用多維數組6.元組:Tuple7.結構:Nested(name1 Type1,name2 Type2,...)
類似一種map的結

物化列


指定 MATERIALIZED 表達式,即將一個列作為物化列處理了,這意味著這個列的值不能從insert?語句獲取,只能是自己計算出來的。同時,
物化列也不會出現在?select *?的結果中:

drop table if exists test.m2;create table test.m2 (a MATERIALIZED (b+1),b UInt16) ENGINE = Memory;insert into test.m2 (b) values (1);select * from test.m2;select a, b from test.m2;

表達式列


ALIAS 表達式列某方面跟物化列相同,就是它的值不能從 insert 語句獲取。不同的是, 物化列 是會真正保存數據(這樣查詢時不需要再計算),
而表達式列不會保存數據(這樣查詢時總是需要計算),只是在查詢時返回表達式的結果。

create table test.m3 (a ALIAS (b+1), b UInt16) ENGINE = Memory;insert into test.m3(b) values (1);select * from test.m3;select a, b from test.m3;

引擎/engine


引擎是clickhouse設計的精華部分

TinyLog


最簡單的一種引擎,每一列保存為一個文件,里面的內容是壓縮過的,不支持索引
這種引擎沒有并發控制,所以,當你需要在讀,又在寫時,讀會出錯。并發寫,內容都會壞掉。

應用場景:
a. 基本上就是那種只寫一次
b. 然后就是只讀的場景。
c. 不適用于處理量大的數據,官方推薦,使用這種引擎的表最多 100 萬行的數據

drop table if exists test.tinylog;create table test.tinylog (a UInt16, b UInt16) ENGINE = TinyLog;insert into test.tinylog(a,b) values (7,13);

Log


這種引擎跟 TinyLog 基本一致
它的改進點,是加了一個 __marks.mrk 文件,里面記錄了每個數據塊的偏移
這樣做的一個用處,就是可以準確地切分讀的范圍,從而使用并發讀取成為可能
但是,它是不能支持并發寫的,一個寫操作會阻塞其它讀寫操作
Log 不支持索引,同時因為有一個 __marks.mrk 的冗余數據,所以在寫入數據時,一旦出現問題,這個表就廢了

應用場景:
同 TinyLog 差不多,它適用的場景也是那種寫一次之后,后面就是只讀的場景,臨時數據用它保存也可以

drop table if exists test.log;create table test.log (a UInt16, b UInt16) ENGINE = Log;insert into test.log(a,b) values (7,13);

Memory


內存引擎,數據以未壓縮的原始形式直接保存在內存當中,服務器重啟數據就會消失
可以并行讀,讀寫互斥鎖的時間也非常短
不支持索引,簡單查詢下有非常非常高的性能表現

應用場景:
a. 進行測試
b. 在需要非常高的性能,同時數據量又不太大(上限大概 1 億行)的場景

Merge


一個工具引擎,本身不保存數據,只用于把指定庫中的指定多個表鏈在一起。
這樣,讀取操作可以并發執行,同時也可以利用原表的索引,但是,此引擎不支持寫操作
指定引擎的同時,需要指定要鏈接的庫及表,庫名可以使用一個表達式,表名可以使用正則表達式指定

create table test.tinylog1 (id UInt16, name String) ENGINE=TinyLog;create table test.tinylog2 (id UInt16, name String) ENGINE=TinyLog;create table test.tinylog3 (id UInt16, name String) ENGINE=TinyLog;insert into test.tinylog1(id, name) values (1, 'tinylog1');insert into test.tinylog2(id, name) values (2, 'tinylog2');insert into test.tinylog3(id, name) values (3, 'tinylog3');use test;create table test.merge (id UInt16, name String) ENGINE=Merge(currentDatabase(), '^tinylog[0-9]+');select _table,* from test.merge order by id desc

Distributed


與 Merge 類似, Distributed 也是通過一個邏輯表,去訪問各個物理表,設置引擎時的樣子是:

Distributed(remote_group, database, table [, sharding_key])

Null


空引擎,寫入的任何數據都會被忽略,讀取的結果一定是空。

但是注意,雖然數據本身不會被存儲,但是結構上的和數據格式上的約束還是跟普通表一樣是存在的,同時,你也可以在這個引擎上創建視圖

Buffer


1.Buffer 引擎,像是Memory 存儲的一個上層應用似的(磁盤上也是沒有相應目錄的)2.它的行為是一個緩沖區,寫入的數據先被放在緩沖區,達到一個閾值后,這些數據會自動被寫到指定的另一個表中3.和Memory 一樣,有很多的限制,比如沒有索引4.Buffer 是接在其它表前面的一層,對它的讀操作,也會自動應用到后面表,但是因為前面說到的限制的原因,一般我們讀數據,就直接從源表讀就好了,緩沖區的這點數據延遲,只要配置得當,影響不大的5.Buffer 后面也可以不接任何表,這樣的話,當數據達到閾值,就會被丟棄掉

一些特點:

  • 如果一次寫入的數據太大或太多,超過了 max 條件,則會直接寫入源表。

  • 刪源表或改源表的時候,建議 Buffer 表刪了重建。

  • “友好重啟”時, Buffer 數據會先落到源表,“暴力重啟”, Buffer 表中的數據會丟失。

  • 即使使用了 Buffer ,多次的小數據寫入,對比一次大數據寫入,也 慢得多 (幾千行與百萬行的差距)

-- 創建源表create table test.mergetree (sdt Date, id UInt16, name String, point UInt16) ENGINE=MergeTree(sdt, (id, name), 10);-- 創建 Buffer表-- Buffer(database, table, num_layers, min_time, max_time, min_rows, max_rows, min_bytes, max_bytes)create table test.mergetree_buffer as test.mergetree ENGINE=Buffer(test, mergetree, 16, 3, 20, 2, 10, 1, 10000);insert into test.mergetree (sdt, id, name, point) values ('2017-07-10', 1, 'a', 20);insert into test.mergetree_buffer (sdt, id, name, point) values ('2017-07-10', 1, 'b', 10);select * from test.mergetree;select '------';select * from test.mergetree_buffer;

Set


Set 這個引擎有點特殊,因為它只用在 IN 操作符右側,你不能對它 select

create table test.set(id UInt16, name String) ENGINE=Set;insert into test.set(id, name) values (1, 'hello');-- select 1 where (1, 'hello') in test.set; -- 默認UInt8 需要手動進行類型轉換select 1 where (toUInt16(1), 'hello') in test.set;

Join


TODO

MergeTree


這個引擎是 ClickHouse 的重頭戲,它支持一個日期和一組主鍵的兩層式索引,還可以實時更新數據。同時,索引的粒度可以自定義,外加直接支持采樣功能

MergeTree(EventDate, (CounterID, EventDate), 8192)MergeTree(EventDate, intHash32(UserID), (CounterID, EventDate, intHash32(UserID)), 8192)

SummingMergeTree


1.SummingMergeTree 就是在 merge 階段把數據sum求和2.sum求和的列可以指定,不可加的未指定列,會取一個最先出現的值

create table test.summingmergetree (sdt Date, name String, a UInt16, b UInt16) ENGINE=SummingMergeTree(sdt, (sdt, name), 8192, (a));insert into test.summingmergetree (sdt, name, a, b) values ('2018-06-10', 'a', 1, 20);insert into test.summingmergetree (sdt, name, a, b) values ('2018-06-10', 'b', 2, 11);insert into test.summingmergetree (sdt, name, a, b) values ('2018-06-11', 'b', 3, 18);insert into test.summingmergetree (sdt, name, a, b) values ('2018-06-11', 'b', 3, 82);insert into test.summingmergetree (sdt, name, a, b) values ('2018-06-11', 'a', 3, 11);insert into test.summingmergetree (sdt, name, a, b) values ('2018-06-12', 'c', 1, 35);-- 手動觸發一下 merge 行為optimize table test.summingmergetree;select * from test.summingmergetree;

AggregatingMergeTree


AggregatingMergeTree 是在 MergeTree 基礎之上,針對聚合函數結果,作增量計算優化的一個設計,它會在 merge 時,針對主鍵預處理聚合的數據
應用于AggregatingMergeTree 上的聚合函數除了普通的 sum, uniq等,還有 sumState , uniqState ,及 sumMerge , uniqMerge 這兩組

1.聚合數據的預計算
是一種“空間換時間”的權衡,并且是以減少維度為代價的

dim1dim2dim3measure1
aaaaa11
aaaab21
bbbbb31
ccccb21
ccccc11
ddddc21
dddda11

假設原始有三個維度,一個需要 count 的指標

dim1dim2dim3measure1
aaaaa11
aaaab21
bbbbb31
ccccb21
ccccc11
ddddc21
dddda11

通過減少一個維度的方式,來以 count 函數聚合一次 M

dim2dim3count(measure1)
a13
b22
b31
c11
c21

2.聚合數據的增量計算

對于 AggregatingMergeTree 引擎的表,不能使用普通的 INSERT 去添加數據,可以用:a.?INSERT SELECT 來插入數據b.?更常用的,是可以創建一個物化視圖

drop table if exists test.aggregatingmergetree;create table test.aggregatingmergetree(sdt Date, dim1 String, dim2 String, dim3 String, measure1 UInt64) ENGINE=MergeTree(sdt, (sdt, dim1, dim2, dim3), 8192);-- 創建一個物化視圖,使用 AggregatingMergeTreedrop table if exists test.aggregatingmergetree_view;create materialized view test.aggregatingmergetree_viewENGINE = AggregatingMergeTree(sdt,(dim2, dim3), 8192)asselect sdt,dim2, dim3, uniqState(dim1) as uvfrom test.aggregatingmergetreegroup by sdt,dim2, dim3;insert into test.aggregatingmergetree (sdt, dim1, dim2, dim3, measure1) values ('2018-06-10', 'aaaa', 'a', '10', 1);insert into test.aggregatingmergetree (sdt, dim1, dim2, dim3, measure1) values ('2018-06-10', 'aaaa', 'a', '10', 1);insert into test.aggregatingmergetree (sdt, dim1, dim2, dim3, measure1) values ('2018-06-10', 'aaaa', 'b', '20', 1);insert into test.aggregatingmergetree (sdt, dim1, dim2, dim3, measure1) values ('2018-06-10', 'bbbb', 'b', '30', 1);insert into test.aggregatingmergetree (sdt, dim1, dim2, dim3, measure1) values ('2018-06-10', 'cccc', 'b', '20', 1);insert into test.aggregatingmergetree (sdt, dim1, dim2, dim3, measure1) values ('2018-06-10', 'cccc', 'c', '10', 1);insert into test.aggregatingmergetree (sdt, dim1, dim2, dim3, measure1) values ('2018-06-10', 'dddd', 'c', '20', 1);insert into test.aggregatingmergetree (sdt, dim1, dim2, dim3, measure1) values ('2018-06-10', 'dddd', 'a', '10', 1);-- 按 dim2 和 dim3 聚合 count(measure1)select dim2, dim3, count(measure1) from test.aggregatingmergetree group by dim2, dim3;-- 按 dim2 聚合 UVselect dim2, uniq(dim1) from test.aggregatingmergetree group by dim2;-- 手動觸發mergeOPTIMIZE TABLE test.aggregatingmergetree_view;select * from test.aggregatingmergetree_view;-- 查 dim2 的 uvselect dim2, uniqMerge(uv) from test.aggregatingmergetree_view group by dim2 order by dim2;

CollapsingMergeTree

是專門為 OLAP 場景下,一種“變通”存數做法而設計的,在數據是不能改,更不能刪的前提下,通過“運算”的方式,去抹掉舊數據的影響,把舊數據“減”去即可,從而解決"最終狀態"類的問題,比如?當前有多少人在線?

“以加代刪”的增量存儲方式,帶來了聚合計算方便的好處,代價卻是存儲空間的翻倍,并且,對于只關心最新狀態的場景,中間數據都是無用的

CollapsingMergeTree 在創建時與 MergeTree 基本一樣,除了最后多了一個參數,需要指定 Sign 位(必須是 Int8 類型)

create table test.collapsingmergetree(sign Int8, sdt Date, name String, cnt UInt16) ENGINE=CollapsingMergeTree(sdt, (sdt, name), 8192, sign);

身邊有些朋友面試找不到工作,我就干脆弄一個免費知識星球?,分享一下我平時看的技術文章,大家一起監督學習,共同進步

總結

以上是生活随笔為你收集整理的clickhouse物化视图优缺点_ClickHouse 适用场景的全部內容,希望文章能夠幫你解決所遇到的問題。

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