高基數(shù)列是指數(shù)據(jù)基本不重復或者均為唯一值的列。典型的高基數(shù)列有ID標識,電子郵件地址或者用戶名等。一個具有高基數(shù)的數(shù)據(jù)表列的例子是具有一個名為USER_ID的列的USERS表。
這一列包含1-n的唯一值。每次在USERS表中創(chuàng)建一個新用戶時,將在USER_ID列中創(chuàng)建一個新數(shù)字,以唯一地標識它們。由于USER_ID列中保存的值是唯一的,因此該列的基數(shù)類型被稱為高基數(shù)。
如果你的工作中用到了數(shù)據(jù)庫,特別是要處理時序數(shù)據(jù),那么可能你就會面對處理高基數(shù)數(shù)據(jù)的挑戰(zhàn)。
特別是工業(yè)物聯(lián)網(wǎng)(如制造業(yè)、石油和天然氣、公用事業(yè)等)以及一些監(jiān)控和事件數(shù)據(jù)工作負載中,時間序列高基數(shù)的處理是一個常見問題。高基數(shù)也是開發(fā)人員經(jīng)常討論的一個話題,圍繞它經(jīng)常會有很多問題。
這里要澄清一個常見的混淆點:高基數(shù)在時序數(shù)據(jù)世界中之所以成為如此大的問題,是因為一些流行的時序數(shù)據(jù)庫的局限性。如果選擇了正確的數(shù)據(jù)庫,高基數(shù)數(shù)據(jù)其實是一個已經(jīng)解決了的問題。
讓我們回過頭來首先來定義什么是高基數(shù)。
什么是高基數(shù)?
廣義上講,基數(shù)是指一個集合中的值的數(shù)量。有時,集合的基數(shù)很小(低基數(shù)),有時可能很大(高基數(shù))。例如,上圖中有很多(美味的)M&M,但該數(shù)據(jù)集的基數(shù)非常?。?):
在數(shù)據(jù)庫世界中,基數(shù)是指數(shù)據(jù)庫的特定列或字段中包含的唯一值的數(shù)量。
然而,對于時序數(shù)據(jù)來說,事情可能變得有些復雜了。時序數(shù)據(jù)往往與描述該數(shù)據(jù)的元數(shù)據(jù)(有時稱為“標簽”)配對。
通常,主時序數(shù)據(jù)或元數(shù)據(jù)會被索引以提高查詢性能,這樣就可以快速找到匹配所有指定標簽的值。時序數(shù)據(jù)集的基數(shù)最典型是定義方式為每個索引列的基數(shù)的交叉乘積。
如果有6種顏色的m&m巧克力豆以及5種類型的m&m巧克力豆(普通的、花生的、杏仁的、椒鹽脆餅的和脆的),那么我們的基數(shù)現(xiàn)在是6x5 = 30種m&m巧克力豆。有了正確的索引,我們就能高效地找到所有藍色的、酥脆的m&m巧克力豆(這是客觀上最好的)。
如果你有多個索引列,每個列都有大量的唯一值,那么叉乘的基數(shù)可能會變得非常大。這是軟件開發(fā)人員在談論具有“高基數(shù)”的時序數(shù)據(jù)集時,“高基數(shù)”的通常含義。
讓我們來看一個例子。
高基數(shù)示例:工業(yè)物聯(lián)網(wǎng)
想象一個物聯(lián)網(wǎng)場景,在某個采石場,有大型、沉重的設備在進行采礦、破碎巖石和分類巖石這三種作業(yè)。
假設有10000件設備,每件設備有100個傳感器,運行10個不同的固件版本,分布在100個地點:這個數(shù)據(jù)集的最大基數(shù)變成了10億[10,000 x 100 x 10 x 100]。現(xiàn)在,假設設備也可以移動,我們想要存儲精確的GPS位置(lat、long)(緯度,經(jīng)度),并將其用作查詢的索引元數(shù)據(jù)。因為(lat, long)是一個連續(xù)的字段(而不是像equipment_id這樣的離散字段),通過對位置進行索引,這個數(shù)據(jù)集的最大基數(shù)現(xiàn)在是無限大的(無界)。
為時序設計的關系型數(shù)據(jù)庫如何處理高基數(shù)
不同的數(shù)據(jù)庫采用不同的方法來處理高基數(shù)。根本上說,在使用高基數(shù)數(shù)據(jù)集時,數(shù)據(jù)庫的性能表現(xiàn)如何可以追溯到它從一開始是如何設計的。
如果你正在處理大量的時序數(shù)據(jù)并使用關系數(shù)據(jù)庫,那么用于索引數(shù)據(jù)的一種經(jīng)過驗證的數(shù)據(jù)結構是b樹。依賴b樹數(shù)據(jù)結構來索引數(shù)據(jù)對于高基數(shù)數(shù)據(jù)集有幾個好處:
- 你可以清晰地理解數(shù)據(jù)庫的執(zhí)行方式。只要你希望查詢的數(shù)據(jù)集的索引和數(shù)據(jù)適合內存(這是可以調優(yōu)的),基數(shù)就不是問題。
- 你可以控制索引哪些列,包括在多個列上創(chuàng)建聯(lián)合索引的能力。你還可以隨時添加或刪除索引,如果你的查詢工作負載發(fā)生了變化。
- 你可以在離散和連續(xù)字段上創(chuàng)建索引,特別是因為b樹可以很好地使用以下操作符進行比較:<,<=,=,>=,>,BETWEEN, IN, IS NULL, IS NOT NULL。我們的示例查詢(“SELECT * from sensor_data WHERE mem_free = 0”和“SELECT * from sensor_data WHERE temperature > 90”)將運行在對數(shù)或O(log n)的時間復雜度內。
雖然時序數(shù)據(jù)庫使用其他方法來實現(xiàn)高基數(shù),但使用b樹結構已被證明是可靠的。如果你遇到有關高基數(shù)的數(shù)據(jù)問題,可以留言一起討論。
參考鏈接:https://dzone.com/articles/what-is-high-cardinality
譯者介紹
盧鑫旺,51CTO社區(qū)編輯,半路出家的九零后程序員。做過前端頁面,寫過業(yè)務接口,搞過爬蟲,研究過JS,有幸接觸Golang,參與微服務架構轉型。目前主寫Java,負責公司可定制化低代碼平臺的數(shù)據(jù)引擎層設計開發(fā)工作。