常用注解-@TableId


二、@TableId

1、雪花算法

默認情況下數據庫的id列使用的是基於雪花算法的策略生成

背景

隨着業務規模的不斷擴大,需要選擇合適的方案去應對數據規模的增長,以應對逐漸增長的訪問壓力和數據量。

數據庫的擴展方式主要包括:業務分庫、主從復制,數據庫分表。

數據庫分表

將不同業務數據分散存儲到不同的數據庫服務器,能夠支撐百萬甚至千萬用戶規模的業務,但如果業務繼續發展,同一業務的單表數據也會達到單台數據庫服務器的處理瓶頸。例如,淘寶的幾億用戶數據,如果全部存放在一台數據庫服務器的一張表中,肯定是無法滿足性能要求的,此時就需要對單表數據進行拆分。

單表數據拆分有兩種方式:垂直分表和水平分表。示意圖如下:

垂直分表:

  • 垂直分表適合將表中某些不常用且占了大量空間的列拆分出去。
  • 例如,前面示意圖中的 nickname 和 description 字段,假設我們是一個婚戀網站,用戶在篩選其他用戶的時候,主要是用 age 和 sex 兩個字段進行查詢,而 nickname 和 description 兩個字段主要用於展示,一般不會在業務查詢中用到。description 本身又比較長,因此我們可以將這兩個字段獨立到另外一張表中,這樣在查詢 age 和 sex 時,就能帶來一定的性能提升。

水平分表:

  • 水平分表適合表行數特別大的表,有的公司要求單表行數超過 5000 萬就必須進行分表,這個數字可以作為參考,但並不是絕對標准,關鍵還是要看表的訪問性能。對於一些比較復雜的表,可能超過 1000 萬就要分表了;而對於一些簡單的表,即使存儲數據超過 1 億行,也可以不分表。
  • 但不管怎樣,當看到表的數據量達到千萬級別時,作為架構師就要警覺起來,因為這很可能是架構的性能瓶頸或者隱患。

水平分表相比垂直分表,會引入更多的復雜性,例如數據id:

主鍵自增:

  • 以最常見的用戶 ID 為例,可以按照 1000000 的范圍大小進行分段,1 ~ 999999 放到表 1中,1000000 ~ 1999999 放到表2中,以此類推。
  • 復雜點:分段大小的選取。分段太小會導致切分后子表數量過多,增加維護復雜度;分段太大可能會導致單表依然存在性能問題,一般建議分段大小在 100 萬至 2000 萬之間,具體需要根據業務選取合適的分段大小。
  • 優點:可以隨着數據的增加平滑地擴充新的表。例如,現在的用戶是 100 萬,如果增加到 1000 萬,只需要增加新的表就可以了,原有的數據不需要動。
  • 缺點:分布不均勻。假如按照 1000 萬來進行分表,有可能某個分段實際存儲的數據量只有 1 條,而另外一個分段實際存儲的數據量有 1000 萬條。

Hash :

  • 同樣以用戶 ID 為例,假如我們一開始就規划了 10 個數據庫表,可以簡單地用 user_id % 10 的值來表示數據所屬的數據庫表編號,ID 為 985 的用戶放到編號為 5 的子表中,ID 為 10086 的用戶放到編號為 6 的子表中。
  • 復雜點:初始表數量的確定。表數量太多維護比較麻煩,表數量太少又可能導致單表性能存在問題。
  • 優點:表分布比較均勻。
  • 缺點:擴充新的表很麻煩,所有數據都要重分布。

*雪花算法:*

雪花算法是由Twitter公布的分布式主鍵生成算法,它能夠保證不同表的主鍵的不重復性,以及相同表的主鍵的有序性。

  • 核心思想:

    • 長度共64bit(一個long型)。
    • 首先是一個符號位,1bit標識,由於long基本類型在Java中是帶符號的,最高位是符號位,正數是0,負數是1,所以id一般是正數,最高位是0。
    • 41bit時間截(毫秒級),存儲的是時間截的差值(當前時間截 - 開始時間截),結果約等於69.73年。
    • 10bit作為機器的ID(5個bit是數據中心,5個bit的機器ID,可以部署在1024個節點)。
    • 12bit作為毫秒內的流水號(意味着每個節點在每毫秒可以產生 4096 個 ID)。

  • 優點:整體上按照時間自增排序,並且整個分布式系統內不會產生ID碰撞,並且效率較高。

2、指定主鍵列

  • 測試:將數據庫表中的id列改為 uid,將實體類中的id屬性改成 uid,執行數據插入,則報告如下錯誤

  • 原因:因為MP默認認為id是主鍵列,其他名字的屬性MP無法默認自動填充
  • 解決方案:為主鍵列添加 @TableId 注解

3、value屬性

實體類的屬性名是 id,數據庫的列名是 uid,此時使用 value 屬性將屬性名映射到列名

@TableId(value = "uid")
private String id;

4、type屬性

type屬性用來定義主鍵策略

  • IdType.ASSIGN_ID:使用基於雪花算法的策略生成數據id
@TableId(type = IdType.ASSIGN_ID)
private Long id;

注意:當對象的id被明確賦值時,不會使用雪花算法

  • IdType.AUTO:使用數據庫的自增策略
@TableId(type = IdType.AUTO)
private Long id;

注意:該類型請確保數據庫設置了 ID自增 否則無效

  • 全局配置:要想影響所有實體的配置,可以設置全局主鍵配置
#全局設置主鍵生成策略
mybatis-plus.global-config.db-config.id-type=auto


免責聲明!

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



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