{eval=Array;=+count(Array);}

国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

問答專欄Q & A COLUMN

MySQL分庫分表之后,id主鍵如何處理?

stormgensstormgens 回答0 收藏1
收藏問題

9條回答

張憲坤

張憲坤

回答于2022-06-28 14:38

我從分庫分表存在的問題和怎么做來回答一下這個問題。。

一,分庫分表的ID主鍵不能依賴于數據庫的自增,因為多庫中會重復!

通常使用外接的數據組件獲取全局唯一的ID:比如加強型UUID(根據Ip,時間戳等得到)和使用Redis(RedisAtomicLong)和zookeeper的API獲取,Twitter的雪花算法等等!

二,分庫分表之后的連接查詢比較困難!

問題沒法避免,通常拆分SQL,使用多次查詢,用查到的結果再分別查別的結果!

三,分布式事務的數據一致性很難保證!

可以使用TCC編程模型保證兩處的事務都能正確提交,但是這種方式對代碼的侵入比較重!也可以使用基于消息的數據一致性保證!

四,多數據的排序,分組,統計會比較困難!

1,用多線程,對多個節點分別查詢,然后匯總!

2,也可以提前冗余查詢表,將所有的經常查詢的重點數據提前統一到個庫表里!

分庫分表涉及到的知識點比較多,建議使用專門的分庫分表組件!本人有mycat使用經驗,如果您有相關問題,歡迎前來探討!

評論0 贊同0
  •  加載中...
Cheriselalala

Cheriselalala

回答于2022-06-28 14:38

數據庫在做了分庫分表之后,關于ID主鍵,我認為需要考慮這幾點:


生成算法

當我們的數據庫是單臺的時候,是不用太操心主鍵的生成,但是當數據庫進行了分庫分表之后,那么主鍵的生成就需要注意了,至少不能使用數據庫內部的自增長序列了,通常要引入分布式唯一標識碼的生成算法。

  • 利用數據庫生成:先說最笨的方法,利用數據庫的自增長序列生成,數據庫內唯一,有人會說,剛說完不能用數據庫的自增長序列,這么快就要被打臉了么?其實這個的意思是,先利用(額外)的一臺數據庫,通過其自增長序列得到主鍵,然后作為分庫分表的主鍵;

  • 利用Redis/MongoDB/zookeeper生成:Redis的單線程的,利用incr和increby;MongoDB的ObjectId;ZK通過znode數據版本;都可以生成全局的唯一標識碼;

  • UUID:生成唯一標識碼最常用的算法之一;

  • Snowflake:Twitter開源,基于zk,41位時間戳(毫秒數)+10位機器的ID+12位毫秒內的流水號+1位符號位(永遠是0);

  • UidGenerator:百度開源,基于snowflake算法;

  • Leaf:美團開源,能保證全局唯一性、高可用、趨勢遞增(不太安全,比如泄露公司訂單數量)、單調遞增等。


擴容會比較麻煩

分庫分表通常的方案都用主鍵mod分表的數量,來把數據路由到某一個數據庫分片上。例如分了10張表,那么就是ID%10,得到結果0-9,代表不同的表;但是當數據量進一步增多的時候,單庫的數據量達到了一定的級別之后,那么就需要分更多的表,那么這時候有哪些處理方案呢?

  • 做數據遷移:最簡單暴力,也是最麻煩的一個方案;因為當分表(分庫)數量增多的時候,因為分片規則的變化,每個表的數據都要被重新分配到多個新的表;

  • 如果id是一個增長的全局序列,當前有十張表,那么分表的算法為:id%10,根據0-9路由到10個表中;當表擴到20張的時候,擴容那一刻取max_id,那么未來分庫的算法也就變成了:

if(id<max_id){id%10} else {id%20};
  • 有些分表的算法本身就帶時間戳,可以基于id中的時間戳來實現,比如Snowflake算法(見上文),這個算法是一個64位的Long值,前42位就是一個精確到毫秒的時間戳,那么我們的分庫算法也就可以以某個時間點來判斷:

if(id中的時間<增加分表那一刻的時間){id%10} else {id%20};

我將持續分享Java開發、架構設計、程序員職業發展等方面的見解,希望能得到你的關注。

評論0 贊同0
  •  加載中...
未東興

未東興

回答于2022-06-28 14:38

數據量達到查詢瓶頸的時候,需要做一些拆分或索引優化處理。

對于使用id主鍵來說,分庫分表都要做一些特別的設計,有以下幾個方案。

1、id區間提前規劃好,每個庫分配好整數區間,每個庫中的每個表也要規劃號,數字那么大,總有區間能夠容納下增長的數字。

2、id采用32位全局uuid保證唯一

3、通過雪花算法,得到分布式環境下全局唯一的id

4、采用納秒級時間戳+隨機數+重試機制保證數據唯一。

由于數據庫的索引大部分采用B+數數據結構來存儲,主鍵的線性遞增對數據的插入(B+樹的拆分和合并)和查詢性能有優勢,所以建議采用能保證主鍵遞增的方案。

評論0 贊同0
  •  加載中...
objc94

objc94

回答于2022-06-28 14:38

全局id生成算法 snowklake算法 用long型64位表示 1位表示符號位正整數 41位表示時間戳 10位表示機器碼 12位表示順序位

評論0 贊同0
  •  加載中...
U2FsdGVkX1x

U2FsdGVkX1x

回答于2022-06-28 14:38

為什么要分物理表呢? 分區的底層同樣是物理分表但上層MySQL已做好一切展現給我們的是一個總表,不同的數據放到不同分區,CURD甚至索引完全就是當成一個表來操作,其實展現給用戶的就是一張表,但底層分成了若干個區

評論0 贊同0
  •  加載中...
Cciradih

Cciradih

回答于2022-06-28 14:38

寫個api,專門用來生成唯一id,用他來做主鍵

評論0 贊同0
  •  加載中...
kk_miles

kk_miles

回答于2022-06-28 14:38

苞米豆的mybatis-plus,只需要配置一下就可以,但我沒有實際應用過

評論0 贊同0
  •  加載中...
canger

canger

回答于2022-06-28 14:38

id主鍵不用管。MySQL自己會處理。無非是操作的時候不一樣

評論0 贊同0
  •  加載中...
Kyxy

Kyxy

回答于2022-06-28 14:38

看你怎么分,但無論怎么分都要保留或新建主建來關聯數據,數據關聯不起來,就廢了。

評論0 贊同0
  •  加載中...

相關問題

最新活動

您已邀請0人回答 查看邀請

我的邀請列表

  • 擅長該話題
  • 回答過該話題
  • 我關注的人
向幫助了您的網友說句感謝的話吧!
付費偷看金額在0.1-10元之間
<