Clickhouse MergeTree家族


參考博客:

 

1、MergeTree:它擁有主鍵,但是它的主鍵卻沒有唯一鍵的約束,即可以寫入重復數據

  1.1 場景

MergeTree用於存儲全量的明細數據,對外提供實時查詢

  1.2 特性

a)只有MergeTree系列的表引擎才支持主鍵索引,數據分區,數據副本,數據采樣這些特性,只有此系列的表引擎才支持ALTER操作
b)MergeTree表引擎在寫入一批數據的時候,數據總會以數據片段的形式寫入磁盤,並且數據片段不可修改。為了避免片段過多,
  clickhouse會通過后台的線程,定期合並這些數據片段,屬於不同分區的數據片段會被合並成一個新的片段。

  1.3 建表必填項

建表必填項:
  1.ENGINE:創建MergeTree的表引擎指定ENGINE = MergeTree()   2.ORDER BY語句:sorting key 排序鍵,用於指定在一個數據片段內數據以何種標准排序。默認情況下是主鍵primary key   與排序鍵相同。排序鍵可以單個列字段,也可以多個列字段。 選填項: 1.PARTITION BY :分區鍵 用於指定表數據以何種標准進行分區。分區鍵可以單個列字段,也可以是通過元祖形式使用的多個列字段,還可以支持使用列表達式。 若不聲明分區鍵則clickhouse會生成一個名為all的分區。合理使用分區 可以有效減少查詢數據文件的掃描范圍。 2.primary key:主鍵 聲明后會按照主鍵字段生成一級索引,用於加速表查詢。默認情況下主鍵與排序鍵相同, 所以通常直接使用order by 指定主鍵,無須刻意通過primary key聲明。在一般情況下,在單個數據片段內 數據與一級索引以相同的規則升序排列。 MergeTree主鍵允許存在重復數據(ReplacingMergeTree可以去重)3.sample by:抽樣表達式,用於聲明數據以何種標准進行采樣。若使用了此配置選項則在主鍵的配置中也需要聲明同樣的表達式。 抽樣表達式需要配合sample by 子查詢使用,這項功能對於選取抽樣數據十分有用。 4.TTL:指定表級別的數據存活策略

  1.4 MergeTree表引擎中的數據是擁有物理存儲的,數據會按照分區目錄的形式存儲到磁盤之上

  1.partition 分區目錄partition_n目錄下的各類數據文件都是以分區形式被組織存放的,屬於相同分區的數據最終會被合並到同一個分區目錄內。
  2.checksums.txt:校驗文件,使用二進制存儲,保存了各類文件的size大小和size的哈希值,用於快速校驗文件的完整性和正確性。
  3.columns.txt:列信息文件,使用文本文件存儲,用於保存分區下的列字段信息。
  4.count.txt:計數文件,文本文件存儲,用於記錄當前數據分區目錄下數據的總行數。
  5.primary.idx:以及索引文件,使用二進制格式存儲。用於存放稀疏索引,一張MergeTree表只能聲明一次一級索引
    (通過order by或者primary key)。借助稀疏索引在數據查詢的時候能夠排除主鍵范圍之外的數據文件,從而減少數據掃描范圍,加速查詢速度。
  6.[column].bin:數據文件,使用壓縮格式存儲,默認使用LZ4壓縮格式,用於存儲某一列的數據。由於MergeTree采用列式存儲,每個列字段都擁有獨立的bin數據文件,並以列字段命名。
  7.[column].mrk列字段標記,使用二進制格式存儲。標記文件中保存了bin文件中數據的偏移量信息,標記文件與稀疏文件對齊,又與bin文件一一對應,所以MergeTree通過標記文件建立了primary.idx稀疏索引與bin數據文件的隱射關系。
    首先通過primary.idx找到對應數據的偏移量信息(.mrk),再通過偏移量直接從bin文件中讀取數據。由於.mrk標記文件與.bin文件一一對應,所以MergeTree中的每個列字段都會擁有與其對應的.mrk文件。
                 
  8.[column].mrk2 如使用了自適應大小的索引間隔,則標記文件會以.mrk2命名。工作原理和作用和.mrk標記文件相同。
  9.partition.dat和minmax_[column].idx:
     若使用了分區鍵則會額外生成partition.dat和minmax索引文件,均使用二進制格式存儲。partition.dat用於保存當前分區下
     分區表達式最終生成值,minmax索引文件用於記錄當前分區字段對應原始數據的最小值和最大值。
     在分區索引作用下,進行數據查詢時候能夠快速跳過不必要的數據分區目錄,從而減少最終需要掃描的數據范圍。
  10.skp_idx_[column].idx和skp_idx_[column].mrk:
     若在建表語句中聲明了二級索引則會額外生成相應的二級索引與標記文件,他們同樣用二進制存儲。
     二級索引在clickhouse中又稱之為跳數索引,目前擁有minmax,set,ngrambf_v1和tokenbf_v1四種類型。
     這些索引的目標和一級稀疏索引相同,為了進一步減少所需要掃描的數據范圍,以加速整個查詢過程

2、ReplacingMergeTree:為了數據去重設計的,能夠在合並分區的時候刪除重復的數據,在某種程度上解決了重復數據的問題

參考博客:https://blog.csdn.net/tototuzuoquan/article/details/110913968

  2.1合並分區

  optimize table tableName final;

  2.2  合並查看數據

  select * from tableName FORMAT PrettyCompactMonoBlock;

  2.3 建表語句

    CREATE TABLE org
        (
            `org_code` varchar(8),
            `org_name` varchar(256),
            `createtime` Datetime
        )
        ENGINE = ReplacingMergeTree()  
        PARTITION BY toYYYYMM(createtime) ##按年月進行分區
        PRIMARY KEY org_code  #主鍵 
        ORDER BY (org_code, org_name)  #排序 注意:在去除重復數據的時候是以ORDER by 為基准,而不是primary key。

  2.4 總結

        1.使用ORDER BY 排序鍵作為判斷重復數據的唯一鍵。
            2.只有在合並分區的時候才會觸發刪除重復數據的邏輯。
            3.以數據分區為單位刪除重復數據。當分區合並時候,同一分區內的重復數據會被刪除;不同分區之間的重復數據不會被刪除。
            4.在進行數據去重時候,因為分區的數據已經基於order by進行排序,所以能夠找到相鄰的重復數據。
            5.數據去重策略:
             若沒有version 則保留同一組重復數據的最后一行
             若設置了version版本號,則保留同一組重復數據中的version取值最大的一行

3、SummingMergeTree:只需要查詢匯總值而不太關心明細數據的,且數據的匯總條件是預先明確的則可以直接使用MergeTree存儲數據,然后通過group by 聚合查詢 並利用SUM聚合函數匯總結果

  3.1 場景

    聚合求值

  3.2 建表語句

      CREATE TABLE orders
            (
                `city_id` String,
                `city_name` varchar(64),
                `users` int,
                `orders` int,
                `amount` decimal(22, 2),
                `createtime` datetime
            )
            ENGINE = SummingMergeTree()
            PARTITION BY toYYYYMM(createtime)
            PRIMARY KEY city_id
            ORDER BY (city_id, city_name)

  3.3  SummingMergeTree 支持嵌套類型的字段,在適用嵌套類型字段的時候需要SUM匯總的字段名稱必須以Map后綴結尾

    3.2.1建表語句
                CREATE TABLE orders_sum
                (
                    `city_id` int,
                    `city_name` varchar(32),
                    `statMap` Nested( month int,     orders int,     amount decimal(22, 2)),
                    `createtime` datetime
                )
                ENGINE = SummingMergeTree()
                PARTITION BY toYYYYMM(createtime)
                ORDER BY city_id
       3.2.1 optimize table orders_sum final;

  3.4 SummingMergeTree的處理邏輯

        1.用ORDER BY 排序鍵作為聚合數據的條件key
            2.只有在合並分區的時候才會觸發匯總的邏輯
            3.以數據分區為單位聚合數據。當分區合並的時候同一數據分區內聚合key相同的數據會被合並匯總,而不同分區之間的數據則不會被匯總。
            4.如在定義引擎的時候指定了columns匯總列(非主鍵的數值類型字段)則sum匯總了這些字段;若未指定則聚合所有非主鍵的數值類型字段。
            5.在進行數據匯總時候因為分區內的數據已經基於order by排序所以能找到相鄰且擁有相同聚合key的數據
            6.匯總數據時候統一分區內相同聚合key的多行數據會合並成一行。其中匯總字段會進行SUM計算,對於那些非匯總字段則使用第一行數據的取值。
            7.支持嵌套結構,單列字段名必須要以Map后綴結尾。嵌套類型中默認以第一個字段作為聚合key。除了第一個字段以外,
            任何一Key,id或者Type為后綴結尾的字段,都將和第一個字段一起組合Key.

4、AggregatingMergeTree:在每個數據分區內會按照order by聚合,而使用何種聚合函數以及針對那些列字段計算則通過定義AggregateFunction數據類型實現的

  4.1 場景

    AggregatingMergeTree更為常見的應用場景是結合物化視圖使用,作為物化視圖的表引擎,而這里的物化視圖則作為"其他數據(明細)表上層的一種查詢視圖(聚合)"

  4.2 明細表(MergeTree引擎)

      CREATE TABLE agg
            (
                `city_id` varchar(32),
                `city_name` varchar(64),
                `item` varchar(32),
                `item_value` int
            )
            ENGINE = MergeTree()
            PARTITION BY city_id
            ORDER BY (city_id, city_name)

  4.3 聚合表(AggregatingMergeTree):在明細表上創建視圖

      CREATE MATERIALIZED VIEW agg_mv
            ENGINE = AggregatingMergeTree()
            PARTITION BY city_id
            ORDER BY (city_id, city_name) AS
            SELECT city_id, city_name, uniqState(item) AS item, sumState(item_value) AS value FROM agg GROUP BY city_id, city_name

  4.4 AggregatingMergeTree處理邏輯

            1.使用ORDER BY排序鍵作為聚合數據的條件key
            2.使用AggregateFunction字段類型定義聚合函數的類型以及聚合的字段
            3.只有在合並分區的時候才會觸發聚合計算的邏輯
            4.以數據分區為單位來聚合數據。當分區合並時候,同一數據分區內聚合key相同的數據會被合並計算,而不同分區之間的數據則不會被計算。
            5.在進行數據計算時候,因為分區內的數據已經基於ORDER BY排序,所以能夠找到那些相鄰且擁有相同聚合key的數據。
            6.在聚合數據時候,同一分區內相同聚合key的多行數據會合並成一行。對於那些非主鍵,非AggregateFunction類型字段則會使用第一行的數據取值。
            7.AggregateFunction類型的字段使用二進制存儲,在寫入數據的時候,需要*State函數,在查詢數據的時候,則需要調用相應的*Merge函數。其中*表示定義時使用的聚合函數。
            8.AggregateMergeTree通常作為物化視圖的表引擎,與普通MergeTree搭配使用

5、CollapsingMergeTree是一種以增待刪的思路,支持行級別的表引擎 

  5.1 特征

     通過定義一個sign標記字段,記錄數據行的狀態。sign為1表示當前行有效,sign為-1則表示此行數據需要刪除;
        當CollapsingMergeTree 分區合並的時候,同一數據分區內標記為1和-1的一組數據會抵消刪除。

  5.2 建表語句

      CREATE TABLE collpase
            (
                `id` String,
                `code` String,
                `createtime` datetime,
                `sign` tinyint #注意:sign字段必須為Int8類型或者為tinyint
            )
            ENGINE = CollapsingMergeTree(sign)
            PARTITION BY toYYYYMM(createtime)
            ORDER BY id

  5.3 強制合並數據(關鍵字:final)

  select * from collpase final FORMAT PrettyCompactMonoBlock;

  5.4 CollapsingMergeTree數據折疊規則

     1.若sign=1 和sign=-1的數據多一行則保留最后一行sign=1的數據
     2.若sign=1 和sign=-1的數據少一行則保留第一行sign=-1的數據
     3.若sign=1 和sign=-1的數據行數一樣多且最后一行是sign=1則保留第一行sign=-1和最后一行sign=1的數據。
     4.若sign=1和sign=1的數據行一樣多且最后一行是sign=-1 則什么也不保留
     5.非以上情況則會打印警告信息,但是不會報錯,此時查詢結果不可預知

 


免責聲明!

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



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