日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

如何設計寬表主鍵

Lindorm寬表引擎是一款分布式數據引擎,寬表引擎中的數據均按照主鍵進行分布。在執行查詢時,如果表中存在多列主鍵,系統會從最左邊的主鍵開始匹配。如果主鍵設置不當,則可能導致主鍵無法被有效利用,進而產生熱點問題,影響查詢性能。因此,在數據分區和數據查詢中,主鍵的設計至關重要。本文介紹設計主鍵前需要考慮的一些問題以及設計示例。

問題考慮

主鍵是唯一的嗎?

相同的主鍵在Lindorm中被認為是同一條數據的多個版本,查詢時默認返回最新版本的數據,所以通常主鍵都需要保證唯一,除非用到多版本特性。

最佳設計示例:主鍵可以是一列,也可以是多列的組合。每個主鍵表示一條記錄。

  • [userid]:表示主鍵只有一列,每個用戶只有一條記錄。

  • [userid][orderid]:表示主鍵為兩列的組合,每個用戶有多條記錄。

基于主鍵可以滿足哪種查詢場景?

主鍵的設計限制了數據的查詢方式,一條SELECT查詢語句,Lindorm服務器端會編譯為兩種查詢方式。

  • 根據完整的主鍵查詢(get方式),例如SELECT * FROM table WHERE userid='abc' AND orderid=123

    說明

    get方式需要知道所有的主鍵列,即組成主鍵所有字段的值都是確定的。

  • 根據主鍵的范圍查詢(scan方式),例如SELECT * FROM table WHERE userid='abc' AND 123<orderid<456

    說明

    scan方式需要指定第一列主鍵的范圍,否則Lindorm默認會拒絕低效的全表掃描查詢,具體說明,請參見低效查詢語句及說明

最佳設計示例:在有限的查詢方式下如何實現復雜查詢?以下方法可以幫您實現。

  • 再新建一張表作為索引表。

  • 查詢條件給定非主鍵列范圍,服務端會使用Filter過濾不需要的數據。

  • 使用二級索引。

  • 使用ORDER BY方法實現倒序(將新數據排在前面),例如SELECT * FROM table WHERE userid='abc' AND 123<orderid<456 ORDER BY orderid DESC

    說明

    由于表字段原始順序的倒序性能比正序性能差,如果大部分數據是倒序場景,可以體現在主鍵設計上,主鍵設計為[userid][orderid DESC]

設計主鍵應該考慮哪些因素?

需要考慮主鍵列值的長度和主鍵列的個數。

  • 主鍵列值的長度:主鍵列值的長度建議盡量短小,建議您采用固定長度的類型,例如長整型。對于非固定長度的類型,主鍵列值的長度控制在2 KB之內,有利于減少存儲成本,提升寫性能。

  • 主鍵列的個數:主鍵列越少,寫入性能越高,同時可以降低存儲成本。建議將主鍵列的數量控制在1~3個。

設計主鍵應該避免哪些情況?

云原生多模數據庫 Lindorm是一個分布式數據庫,數據按照主鍵分布。如果存在多列主鍵,則按照數據庫的最左匹配原則分布。為避免產生寫入熱點問題,建議您遵循以下條件:

  • 主鍵的第一列盡量分散,不建議主鍵名使用相同的前綴。

  • 避免使用共同前綴或者自增的數據作為主鍵的第一列或者索引列(例如時間戳列)。

  • 避免使用有明顯前綴的字段或者枚舉(比如order_type)作為主鍵的第一列。

如果有類似的情況無法避免,可以利用Hash算法進行打散。例如:

假設原始主鍵pk是遞增的字符串,可以設定新主鍵pk1 = hash(pk).substring(0,4)+pk,即選取原始主鍵pk經過Hash算法計算后的結果前4位作為前綴,拼接原始主鍵pk,最終形成新的主鍵pk1。

數據足夠分散,會存在堆積的熱點現象嗎?

散列的目的是將數據分散到不同的分區,不至于產生熱點使某一臺服務器終止,其他服務器空閑,充分發揮分布式和并發的優勢。

最佳設計示例:

  • 設計md5散列算法,主鍵設計為[md5(userid).subStr(0,4)][userId][orderid]

  • 設計反轉,主鍵設計為[reverse(userid)][orderid]

  • 設計取模,主鍵設計為[bucket][timestamp][hostname][log-event]; long bucket = timestamp % numBuckets

  • 增加隨機數,主鍵設計為[userId][orderid][random(100)]

主鍵可以再精簡點嗎?

精簡的主鍵列可以減少數據量,提高數據查詢和數據寫入效率。

最佳設計示例:

  • 使用Long或Int代替String,例如'2015122410' => Long(2015122410)

  • 使用編碼代替名稱,例如'淘寶'=> 'tb'

常見設計示例

  • 日志類、時間序列數據。列舉出三個場景設計主鍵。

    • 查詢某臺機器某個指標某段時間內的數據,主鍵設計為[hostname][log-event][timestamp]

    • 查詢某臺機器某個指標最新的幾條數據,主鍵設計為[hostname][log-event][timestamp DESC]

    • 查詢的數據存在只有時間一個維度或某一個維度數據量巨大的情況,主鍵設計為long bucket = timestamp % numBuckets; [bucket][timestamp][hostname][log-event]

  • 交易類數據。列舉出四個場景設計主鍵。

    • 查詢某個賣家某段時間內的交易記錄,主鍵設計為[seller_id][timestamp][order_number]

    • 查詢某個買家某段時間內的交易記錄,主鍵設計為[buyer_id][timestamp][order_number]

    • 根據訂單號查詢,主鍵設計為[order_number]

    • 查詢中同時滿足三張表,一張買家維度表主鍵設計為[buyer_id][timestamp][order_number]。一張賣家維度表主鍵設計為[seller_id][timestamp][order_number]。一張訂單索引表主鍵設計為[order_number]