目錄
一、 MergeTree系列引擎
1、MergeTree
數據TTL
(1) 列級別 TTL
(2) 表級別 TTL
存儲策略
2、ReplacingMergeTree
3、CollapsingMergeTree
4、VersionedCollapsingMergeTree
5、SummingMergeTree
6、AggregatingMergeTree
二、 外部存儲類引擎
1、HDFS表引擎
2、mysql表引擎
3、JDBC表引擎
4、Kafka 表引擎
5、File表引擎
三、內存類型引擎
1、memory表引擎
2、set表引擎
3、join表引擎
4、buffer表引擎
四、日志類型引擎
1、TinyLog表引擎
2、StripeLog 表引擎
3、Log表引擎
?五、接口類型引擎
1、Merge 表引擎
2、Dictionary 表引擎
3、Distributed 表引擎
六、其他引擎
1、live view
2、Null
3、URL
? ? ? ? ?在大數據分析領域,ClickHouse以其卓越的查詢性能和高效的列式存儲機制而著稱。其背后的核心技術之一便是多樣化的表引擎,它們針對不同的數據訪問模式和存儲需求進行了優化。本文旨在深入探討ClickHouse中的各種表引擎,幫助你更好地理解它們的特性和應用場景
一、 MergeTree系列引擎
????????MergeTree系列是ClickHouse中最為強大和常用的引擎,適用于大規模數據的高效存儲和查詢,特別是時間序列數據。這類引擎的特點是支持高效的寫入和合并操作,能夠處理高吞吐量的數據插入和復雜查詢。
1、MergeTree
?????????MergeTree 作為家族系列最基礎的表引擎,提供了數據分區、一級索引和二級索引等功能。
數據TTL
????????TTL 即 Time To Live,表示數據的存活時間,而在 MergeTree 中可以為某個列字段或整張表設置 TTL。當時間到達時,如果是列字段級別的 TTL,則會刪除這一列的數據;如果是整張表級別的 TTL,則會刪除整張表的數據;如果同時設置,則會以先到期的為主。
????????無論是列級別還是表級別的 TTL,都需要依托某個 DateTime 或 Date 類型的字段,通過對這個時間字段的 INTERVAL 操作來表述 TTL 的過期時間,下面我們看一下設置的方式。
(1) 列級別 TTL
????????需要在定義表字段的時候,為它們聲明了 TTL 表達式,主鍵字段不能被聲明 TTL。
CREATE TABLE ttl_table_v1 (id String,create_time DateTime,code String TTL create_time + INTERVAL 10 SECOND,type UInt8 TTL create_time + INTERVAL 10 SECOND
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(create_time)
ORDER BY id
(2) 表級別 TTL
CREATE TABLE ttl_table_v2 (id String,create_time DateTime,code String TTL create_time + INTERVAL 1 MINUTE,type UInt8
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(create_time)
ORDER BY create_time
TTL create_time + INTERVAL 1 DAY
?????????建表的時候增加表級別的 TTL ,當觸發 TTL 清理時,那些滿足過期時間的數據行將被整行刪除。TTL 支持修改,例如:
ALTER TABLE ttl_table_v2 MODIFY TTL create_time INTERVAL + 3 DAY
????????表級別的 TTL 不支持取消。
存儲策略
?????????ClickHouse 19.15 版本之前,MergeTree 只支持但路徑存儲,所有的數據都會被寫入 config.xml 配置中 path 指定的路徑下,即使服務器掛載了多塊磁盤,也無法有效利用這些存儲空間。19.15版本之后 MergeTree 實現了自定義存儲策略的功能,支持以數據分區為最小移動單位,將分區目錄寫入多塊磁盤目錄。
三大存儲側策略:
- 默認策略:MergeTree 原本的存儲策略,無須任何配置,所有分區會自動保存到 config.xml 配置中 path 指定的路徑下。
- JBOD 策略:這種策略適合服務器掛載了多塊磁盤,但沒有做 RAID 的場景。數據可靠性需要利用副本機制保障。
- HOT/COLD 策略:這種策略適合服務器掛載了不同類型磁盤的場景。HOT 區域使用 SSD 這類高性能存儲媒介,注重存儲性能;COLD 區域使用 HDD 這類高容量存儲媒介,注重存取經濟性。數據會先寫入 HOT 累積到閾值之后自行移動到 COLD 區。
2、ReplacingMergeTree
?????????支持數據的更新和刪除,通過版本控制來標記過期數據,?MergeTree 擁有主鍵,但沒有唯一約束,如果不希望數據表中有重復數據的場景可以使用 ReplacingMergeTree ,它可以在合并分區時刪除重復的數據
。
創建方式:
ENGINE = ReplacingMergeTree(ver)
????????里面的參數 ver 是選填的,可以指定一個整型、Date、DateTime 的字段作為版本號,這個參數決定了去除重復數據時所使用的算法。
????????創建一個ReplacingMergeTree 數據表:
CREATE TABLE replace_table (id String,code String,create_time DateTime
) ENGINE = ReplacingMergeTree()
PARTITION BY toYYYYMM(create_time)
ORDER BY (id, code)
PRIMARY KEY id
上文中的order by 是去除重復數據的關鍵,數據會基于id 和 code 兩個字段進行去重
測試如下
INSERT INTO replace_table
VALUES ('A001', 'C1', '2020-11-10 15:00:00'),('A001', 'C1', '2020-11-11 15:00:00'),('A001', 'C100', '2020-11-12 15:00:00'),('A001', 'C200', '2020-11-13 15:00:00'),('A002', 'C2', '2020-11-14 15:00:00'),('A003', 'C3', '2020-11-15 15:00:00')
????????create_time 為 2020-11-10 15:00:00、2020-11-11 15:00:00 的兩條數據的 id 和 code 是重復的,因此會進行去重,只保留重復數據的最后一條
觸發所有分區合并:
optimize TABLE table_name FINAL
總結一下 ReplacingMergeTree 的使用邏輯:
- ?使用 ORDER BY 排序鍵作為判斷數據重復的唯一鍵;
- ?當導入同一分區目錄時,會直接進行去重;
- ?當導入不同分區目錄時,不會進行去重,只有當分區目錄合并時,屬于同一分區內的重復數據才會去重;但是不同分區內的重復數據不會被刪除;
- 在進行數據去重時,因為分區內的數據已經是基于 ORDER BY 排好序的,所以能很容易地找到那些相鄰的重復的數據;
- 數據去重策略有兩種:如果沒有設置 ver 版本號,則保留同一組重復數據中的最后一條;如果設置了 ver 版本號,則保留同一組重復數據中 ver 字段取值最大的那一行。
3、CollapsingMergeTree
?????????CollapsingMergeTree(折疊合并樹) 就是一種通過以增代刪的思路,支持行級數據修改和刪除的表引擎。它通過定義一個 sign 標記位字段,記錄數據行的狀態。如果 sign 標記為 1,則表示這是一行有效數據;如果 sign 標記為 -1,則表示這行數據要被刪除。當 CollapsingMergeTree 分區合并時,同一數據分區內,sign 標記為 1 和 -1 的一組數據(ORDER BY 字段對應的值相同)會被抵消刪除。
創建方法
ENGINE = CollapsingMergeTree(sign)
??sign 用于指定一個 Int8 類型的標志位字段,一個完整的 CollapsingMergeTree 數據表聲明如下:
CREATE TABLE collapse_table (id String,code Int32,create_time DateTime,sign Int8
) ENGINE = CollapsingMergeTree(sign)
PARTITION BY toYYYYMM(create_time)
ORDER BY id
CollapsingMergeTree 在折疊數據時遵循如下規則:
- 如果 sign = 1 比 sign = -1 的數據多一行,則保留最后一行 sign = 1 的數據
- 如果 sign = -1 比 sign = 1 的數據多一行,則保留第一行 sign = -1 的數據
- 如果 sign = 1 和 sign = -1 的數據行一樣多,并且最后一行是 sign = 1,則保留第一行 sign = -1 和最后一行 sign = 1 的數據
- 如果 sign = 1 和 sign = -1 的數據行一行多,并且最后一行是 sign = -1,則什么也不保留
- 其余情況,ClickHouse 會打印告警日志,但不會報錯,在這種情形下打印結果不可預知
?
????????當然折疊數據并不是實時觸發的,和所有的其它 MergeTree 變種表引擎一樣,這項特性只有在多個分區目錄合并的時候才會觸發,觸發時屬于同一分區的數據會進行折疊。而在分區合并之前,用戶還是可以看到舊數據的,就像上面演示的那樣。
如果不想看到舊數據,那么可以在聚合的時候可以改變一下策略:
-- 原始 SQL 語句
SELECT id, sum(code), count(code), avg(code), uniq(code)
FROM collapse_table GROUP BY id-- 改成如下
SELECT id, sum(code * sign), count(code * sign), avg(code * sign), uniq(code * sign)
FROM collapse_table GROUP BY id HAVING sum(sign) > 0
????????或者在查詢數據之前使用?optimize TABLE table_name FINAL 命令強制分區合并,但是這種方法效率極低,在實際生產環境中慎用
。
注意:
CollapsingMergeTree 的處理機制所要求 sign = 1 和 sign = -1 的數據相鄰,而分區內的數據嚴格按照
ORDER BY 排序,要實現 sign = 1 和 sign = -1 的數據相鄰,則只能嚴格按照順序寫入。
如果數據的寫入順序是單線程執行的,則能夠比較好的控制寫入順序;但如果需要處理的數據量很大,數據的寫入程序通常是多線程的,那么此時就不能保障數據的寫入順序了。而在這種情況下,CollapsingMergeTree 的工作機制就會出現問題?
???????4、VersionedCollapsingMergeTree
? ????????VersionedCollapsingMergeTree 表引擎的作用和 CollapsingMergeTree 完全相同,它們的不同之處在于 VersionedCollapsingMergeTree 對數據的寫入順序沒有要求,在同一個分區內,任意順序的數據都可以完成折疊操作。那么 VersionedCollapsingMergeTree 是如何做到這一點的呢?其實從它的名字就能看出來,因為相比 CollapsingMergeTree 多了一個 Versioned,那么顯然就是通過版本號(version)解決的。
在定義 VersionedCollapsingMergeTree 數據表的時候,除了指定 sign 標記字段之外,還需要額外指定一個 UInt8 類型的 ver 版本號字段。
ENGINE = VersionedCollapsingMergeTree(sign, ver)
一個完整的 VersionedCollapsingMergeTree 表定義如下:
CREATE TABLE ver_collapse_table (id String,code Int32,create_time DateTime,sign Int8,ver UInt8
) ENGINE = CollapsingMergeTree(sign, ver)
PARTITION BY toYYYYMM(create_time)
ORDER BY id
????????提問:VersionedCollapsingMergeTree 是如何使用版本號字段的呢?
????????答:在定義 ver 字段之后,VersionedCollapsingMergeTree 會自動將 ver 作為排序條件并增加到 ORDER BY 的末端。以上面的 ver_collapse_table 為例,在每個分區內,數據會按照 ORDER BY id, ver DESC 排序。所以,無論寫入時數據的順序如何,在折疊處理時,都能回到正確的順序。
5、SummingMergeTree
?????????能夠在合并分區的時候按照預先定義的條件聚合匯總數據,減少查詢時的計算開銷和數據行數。
主要使用的場景是用戶只關心匯總結果,不關心明細數據,并且數據匯總條件是預先明確的場景(GROUP BY 條件明確,且不會隨意改變)
創建方法
ENGINE = SummingMergeTree((col1, col2, col3, ...))
????????其中 col1、col2 為 columns 參數值,這是一個選填參數,用于設置除主鍵外的其它數值類型字段,以指定被 SUM 匯總的列字段。如果不填寫此參數,則會將所有非主鍵的數值類型字段進行匯總,下面就來創建一張 SummingMergeTree 表:
CREATE TABLE summing_table (id String,city String,v1 UInt32,v2 Float64,create_time DateTime
) ENGINE = SummingMergeTree()
PARTITION BY toYYYYMM(create_time)
PRIMARY KEY id
ORDER BY (id, city)
????????如果導入同一分區目錄的數據有重復的,那么直接就聚合了,不同分區目錄則不會聚合,而是在合并生成新分區目錄的時候,再對屬于同一分區的多個分區目錄里的數據進行聚合。另外 SummingMergeTree 也支持嵌套類型的字段,在使用嵌套類型字段時,需要被 SUM 匯總的字段必須以以 Map 后綴結尾。
總結
- 只有 ORDER BY 排序鍵作為聚合數據的條件 Key
- 寫入同一分區目錄的數據會聚合之后在寫入,而屬于同一分區的不同分區目錄的數據,則會在合并觸發時進行匯總
- 不同分區的數據不會匯總到一起
- 如果在定義引擎時指定了 columns 匯總列(非主鍵的數值類型字段),則 SUM 會匯總這些列字段;如果未指定,則聚合所有非主鍵的數值類型字段
- 在進行數據匯總時,因為分區內的數據已經基于 ORDER BY 進行排序,所以很容易找到相鄰也擁有相同 Key 的數據
- 在匯總數據時,同一分區內相同聚合 key 的多行數據會合并成一行,其中匯總字段會進行 SUM 計算;對于那些非匯總字段,則會使用第一行數據的取值
- 支持嵌套結構,但列字段名稱必須以 Map 后綴結尾,并且默認以第一個字段作為聚合 Key。并且除了第一個字段以外,任何名稱以 key、Id 或者 Type 為后綴結尾的字段都會和第一個字段組成復合 Key
?
6、AggregatingMergeTree
????????專為聚合查詢設計,能夠在插入數據時進行預聚合,加快GROUP BY查詢。
????????AggregatingMergeTree 是 SummingMergeTree 升級版,有些數據立方體的意思,核心思想是以空間換時間的方法提升查詢性能。首先,它能夠在合并分區的時候按照預先定義的條件聚合數據。同時,根據預先定義的聚合函數計算數據并通過二進制的格式存入表內。通過將同一分組下的多行數據預先聚合成一行,既減少了數據行,又降低了后續聚合查詢的開銷。
創建方法
ENGINE = AggregatingMergeTree()
????????AggregatingMergeTree 沒有任何額外的設置參數,在分區合并時,在每個數據分區內,會按照 ORDER BY 聚合。經常結合物化視圖方式實現,首先創建底表:
CREATE TABLE agg_table_basic (id String,city String,code String,value UInt32
) ENGINE = MergeTree()
PARTITION BY city
ORDER BY (id, city)
????????通常使用 MergeTree 作為底表,用于存儲全量的明細數據,并以此對外提供實時查詢。接著,創建一張物化視圖:
CREATE MATERIALIZED VIEW agg_view
ENGINE = AggregatingMergeTree()
PARTITION BY city
ORDER BY (id, city)
AS SELECTid, city,uniqState(code) AS code,sumState(value) AS value
FROM agg_table_basic
GROUP BY id, city
????????物化視圖使用 AggregatingMergeTree 表引擎,用于特定場景的數據查詢,相比 MergeTree,它擁有更高的性能。數據會自動同步到物化視圖,并按照 AggregatingMergeTree 的引擎的規則進行處理,查詢只對 agg_view 查詢即可。
二、 外部存儲類引擎
????????這類引擎用于與外部數據源的集成,使得ClickHouse可以直接讀寫其他數據庫或文件系統中的數據。
1、HDFS表引擎
注意:我們需要關閉 HDFS 的 Kerberos 認證,因為 HDFS 表引擎還不支持 Kerberos,然后在 HDFS 上創建用于存放文件的目錄。
CREATE TABLE hdfs_table1 (id UInt32,code String,name String
) ENGINE = HDFS('hdfs://localhost:6666/clickhouse/hdfs_table1', 'CSV')
-- HDFS('HDFS 的文件存儲路徑', '文件格式,如 CSV、TSV、JSON 等等')
-- 注:數據表的名字和 HDFS 文件系統上的文件名可以不一致
2、mysql表引擎
CREATE TABLE clickhouse_trade_info (id UInt32,column1 type,column2 type,......
) ENGINE = MySQL('localhost:3306', 'default', 'trade_info', 'root', '123456')
-- 顯然這幾個參數的含義不需要多說,但還有兩個可選參數 replace_query 和 on_duplicate_clause
-- replace_query 默認為 0,如果設置為 1,會用 REPLACE INTO 代替 INSERT INTO
-- on_duplicate_clause 默認為 0,對應 MySQL 的 ON DUPLICATE KEY 語法,如果想啟用該設置,那么需要設置為 1
3、JDBC表引擎
?????????相對于 MySQL 表引擎而言,JDBC 表引擎不僅可以對接 MySQL 數據庫還能夠與 PostgreSQL、SQLite 和 H2 數據庫對接。但是,JDBC 表引擎無法單獨完成所有的工作,他需要依賴名為 clickhouse-jdbc-bridge 的查詢代理服務。自行研究吧
ENGINE = JDBC('jdbc:url', 'database', 'table')
4、Kafka 表引擎
clickhouse支持kafka表引擎,kafka有三種語義
最多一次(At Most Once):可能出現消息丟失的情況,因為在這種情形下,一條消息在消費端最多被接收一次
最少一次(At Least Once):可能出現消息重復的情況,因為在這種情形下,一條消息在消費端允許被接收多次
精確一次(Exactly Once):數據不多不少,一條消息在消費端恰好被消費一次,這也是最理想的情況,因為消息不可能百分之百不丟失
kafka表引擎目前還不支持精確一次(Exactly Once)
ENGINE = Kafka()
SETTINGS kafka_broker_list = 'host:port,...',kafka_topic_list = 'topic1,topic2',kafka_group_name = 'group_name',kafka_format = 'data_format[,]',[kafka_row_delimiter = 'delimiter_symbol',][kafka_schema = '',][kafka_num_consumers = N,][kafka_skip_broken_message = N,][kafka_commit_every_batch = N]
其中帶有方括號的表示選填項,下面依次介紹這些參數的作用:
- kafka_broker_list:表示 Broker 服務的地址列表,多個地址之間使用逗號分割
- kafka_topic_list:表示訂閱的消息主題的名稱列表,多個主題之間使用逗號分割,多個主題中的數據均被消費
- kafka_group_name:表示消費者組的名稱,表引擎會依據此名稱創建消費者組
- kafka_format:表示用于解析消息的數據格式,在消息的發送端,必須按照此格式發送消息。而數據格式也必須是 ClickHouse 提供的格式之一,例如 TSV、JSONEachRow 和 CSV 等
- kafka_row_delimiter:表示判定一行數據的結束符,默認為 '\0'
- kafka_schema:對應 Kafka 的 schema 參數
- kafka_num_consumers:表示消費者的數據量,默認值為 1,表引擎會依據此參數在消費者組中開啟相應數量的消費者線程,當然線程數不要超過分區數,否則沒有意義。因為在 kafka 的主題中,一個分區只能被某個消費者組里面的一個消費者消費(如果想被多個消費者消費,那么這些消費者一定要隸屬于不同的消費者組)
- kafka_skip_broken_message:當表引擎按照預定格式解析數據出現錯誤時,允許跳過失敗的數據的行數,默認值為 0,即不允許任何格式錯誤的情形發生。在此種情形下,只要 kafka 主題中存在無法解析的數據,數據表都將不會接收任何數據。如果將其設置成非 0 的正整數,例如設置為 10,則表示只要 kafka 主題中存在無法解析的數據的總數小于 10,數據表就能正常接收消息數據,而解析錯誤的數據會被自動跳過
- kafka_commit_every_batch:表示執行 kafka commit 的頻率,因此這里提交偏移量的方式是手動提交,默認值為 0,即當一整個 Block 塊完全寫入數據表后才執行一次 commit。如果設置為 1,則每寫完一個 Batch 批次的數據就會執行一次 kakfa commit(一次 Block 寫入操作,由多次 Batch 寫入操作而成)
5、File表引擎
????????File 表引擎能夠直接讀取本地文件的數據,例如系統生成的文件,還可以將數據導出為本地文件
File 表引擎的聲明方式如下:
ENGINE = File(clickhouse支持的數據格式,例如TSV,CSV,JSONeachRow等),例如CREATE TABLE test_file_table
(`id` UInt32,`name` String
)
ENGINE = File('CSV')
????????由上可見沒有文件路徑,因為?File 表引擎的數據文件只能保存在 config.xml 配置中由 path 指定的路徑下,也就是和其它的數據表在同一個路徑下。
????????每張 File 數據表均由目錄和文件組成,其中目錄以表的名稱命名,而數據文件則以 data.<format> 命名,比如 data.CSV、data.TSV 等等
三、內存類型引擎
????????除了 Memory 表引擎之外,其余的幾款內存表引擎都會將數據寫入磁盤,因為為了防止數據丟失,所以也提供了這種故障恢復手段。而在數據表被加載時,它們會將數據全部加載至內存,以供查詢。
1、memory表引擎
? ????????Memory 表引擎直接將數據保存在內存中,數據即不會被壓縮也不會被格式轉換,因為基于內存,所以服務重啟后會丟失。常見用途為測試和clickhouse內部用來集群間分發數據的存儲載體
Memory 表引擎測試表:
CREATE TABLE test_memory_table
(`id` UInt32,`name` String
)
ENGINE = Memory()
????????當數據被寫入后,磁盤上不會創建任何文件,如果服務重啟那這張表也會消失
2、set表引擎
????????Set 表引擎是擁有物理存儲的,數據首先會被寫入內存,然后被同步到磁盤文件中。所以服務重啟之后它的數據不會丟失,當數據表被重新狀態時,文件數據會再次被全量加載到內存中,
CREATE TABLE test_set_table
(`id` UInt32
)
ENGINE = Set()
set表支持insert,不支持select,常用在查詢條件的in查詢里,如下
select age,name,id from tmp_table where arr in set_table
3、join表引擎
????????join表數據也會先寫入內存,然后同步到磁盤,且支持select操作,它的主要用途是在內存中緩存較小的數據集,以便可以快速地與較大的數據集進行JOIN操作。Join
表引擎不是用于存儲大量數據的主要表,而是作為輔助表,以加速查詢性能
CREATE TABLE test_join_table
(`id` UInt32,`name` String
)
ENGINE = Join(join_strictness, join_type, key1[, key2, ...])案例如下
CREATE TABLE test_join_table
(`id` UInt32,`name` String
)
ENGINE = Join(ANY,LEFT,id)
其中各參數的含義如下:
join_strictness:連接精度,它決定了 JOIN 查詢在連接數據時所使用的策略,目前支持 ALL、ANY、SEMI、ANTI 四種類型
join_type:連接類型,它決定了 JOIN 查詢在組合左右兩個數據集合的策略,目前支持 INNER、LEFT、RIGHT 和 FULL 四種類型
join_key:連接鍵,它決定了使用哪個列字段進行關聯
4、buffer表引擎
???? Buffer 表引擎完全使用內存裝載數據,不支持文件的持久化存儲,所以當服務重啟之后,表內的數據會被清空。Buffer 表引擎不是為了面向查詢場景而設計的,它的作用是充當緩沖區的角色。
Buffer 表引擎的聲明方式如下:
ENGINE = Buffer(database, table, num_layers, min_time, max_time, min_rows, max_rows, min_bytes, max_bytes)
里面參數的作用如下:
database:目標表的數據庫
table:目標表,Buffer 表內的數據會自動刷新到目標表
num_layers:可以理解為線程數,Buffer 表會按照 num_layers 的數量開啟線程,以并行的方式將數據刷新到目標表,官方建議設置為 16
????????Buffer 表并不是實時刷新數據的,只有在閾值條件滿足時才會刷新,閾值條件由三個最小和最大值組成,含義如下:
min_time 和 max_time:時間條件的最小值和最大值,單位為秒,從第一次向表內寫入數據時開始計算
min_rows 和 max_rows:數據行數條件的最小值和最大值
min_bytes 和 max_bytes:數據大小的最小值和最大值,單位為字節
針對以上條件,Buffer 表刷新數據的判斷依據有三個,滿足其中任意一個就會刷新數據:
三組條件中所有最小閾值都已滿足,則觸發刷新動作
三組條件中有一個最大閾值滿足(這里是超過最大值),則觸發刷新動作
如果寫入一批數據的行數大運 max_rows 或者數據大小大于 max_bytes,則數據直接寫入目標表
四、日志類型引擎
????????日志的表引擎也有一些共性特征:比如均不支持索引、分區等高級特性,不支持并發讀寫等等。當針對一張日志表寫入數據時,針對這張表的查詢會被阻塞,直至寫入動作結束。但它們同時也擁有切實的物理存儲,數據會被保存到本地文件中
1、TinyLog表引擎
?????????TinyLog 是日志家族系列中性能最低的表引擎,它的存儲結構由數據文件和元數據兩部分組成。
TinyLog 表引擎測試表:
CREATE TABLE test_tinylog_table
(`id` UInt32,`name` String
)
ENGINE = TinyLog()
2、StripeLog 表引擎
?????????StripeLog 對比 TinyLog 擁有更高的查詢性能。
StripeLog 表引擎測試表:
CREATE TABLE test_stripelog_table
(`id` UInt32,`name` String
)
ENGINE = StripeLog()
3、Log表引擎
??????????Log 表引擎結合了 TinyLog 表引擎和 StripeLog 表引擎的長處,是日志引擎中性能最高的表引擎。由于擁有數據標記且各列數據獨立存儲,所以 Log 既能夠支持并行查詢,又能夠按列按需讀取。Log 表引擎測試表:
CREATE TABLE test_log_table
(`id` UInt32,`name` String
)
ENGINE = Log()
?五、接口類型引擎
1、Merge 表引擎
????????Merge 表引擎就如同一層使用了門面模式的代理,它本身不存儲任何數據,也不支持數據寫入,它的作用就如同它的名字,即負責合并多個查詢結果集。
Merge 表引擎的聲明方式如下:
ENGINE = Merge(database, table_name)
????????其中 database 為數據庫的名稱,table_name 為數據表的名稱,它支持使用正式則表達式,比如 ^ 表示合并所有以 test 為前綴的數據表
????????例如有日期分區命名的表test_table_2019、test_table_2020、test_table_2021、test_table_2022、test_table_2023、test_table_2024
-- test_table_2019 保存了 2019 年的數據
CREATE TABLE test_table_2019 (id String,create_time DateTime,code String
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(create_time)
ORDER BY id;2020-2024同上然后創建 Merge 表將上面兩張表結合,這里的 AS 相當于為 merge_test_table_2019_2024 指定表結構
顯然這里會復制 test_table_2019 的表結構
CREATE TABLE merge_test_table_2019_2024 AS test_table_2019
ENGINE = Merge(currentDatabase(), '^test_table_20')
-- currentDatabase() 表示獲取當前的數據庫
上面的語句是將所有以^test_table_20開頭的數據表合并。
2、Dictionary 表引擎
????????Dictionary 表引擎是數據字段的一層代理封裝,它可以取代字典函數,讓用戶通過數據表查詢字典。字典內的數據被加載后,會全部保存到內存中,所以使用 Dictionary 表對字典表性能不會有任何影響。
Dictionary 表引擎測試表:
CREATE TABLE tb_test_flat_dict
(`id` UInt32,`code` String,`name` String
)
ENGINE = Dictionary(dict_name)
?dict_name對應一個已被加載的字典名稱
3、Distributed 表引擎
???? Distributed 表引擎自身不存儲任何數據,它能作為分布式表的一層透明代理,在集群內部自動開展數據的寫入分發以及查詢路由工作。
六、其他引擎
1、live view
????????從 19.14 版本開始,ClickHouse 提供了一種全新的視圖:Live View。
????????Live View 是一種特殊的視圖,雖然它并不屬于表引擎,但是因為它與數據表息息相關,所以還是把 LiveView 歸類到了這里。Live View 的作用類似事件監聽器,它能夠將一條 SQL 查詢結果作為監控目標,當目標數據增加時,LiveView 可以及時發出響應。若要使用 Live View,首先需要將 allow_experimental_live_view 參數設置為 1
原始表
CREATE TABLE origin_table1
(`id` UInt32,`name` String
)
ENGINE = Log()
創建一張 Live View 表示:
CREATE LIVE VIEW lv_origin AS SELECT COUNT(*) FROM orign_table1
如此一來,Live View 就進入監聽模式了。接著通過下面的命令可以看出實時監控結果:
WATCH lv_origin
2、Null
? ? ????????Null 表引擎的功能和作用,與 Unix 系統的空設備 /dev/null 很相似。如果用戶向 Null 表寫入數據,系統會正確返回,但是 Null 表會自動忽略數據,永遠不會將它保存。如果不希望保留源表的數據,那么將原表設置成 Null 引擎將會是極好的選擇。
3、URL
? ? ????????URL 表引擎的作用等價于 HTTP 客戶端,他可以通過 HTTP/HTTPS 協議,直接訪問遠端的 REST 服務。當執行 SELECT 查詢的時候,底層會將其轉換成 GET 請求的遠程調用。而執行 INSERT 查詢的時候,會將其轉換為 POST 請求的遠程調用。URL 表引擎的聲明方式如下:
ENGINE = URL(url, format)
????????其中,url 表示遠端的服務地址,而 format 則是 Clickhouse 支持的數據格式,如 TSV、CSV 和 JSON 等。