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

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

問答專欄Q & A COLUMN

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

stormgensstormgens 回答0 收藏1
收藏問題

9條回答

張憲坤

張憲坤

回答于2022-06-28 14:38

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

一,分庫分表的ID主鍵不能依賴于數(shù)據(jù)庫的自增,因?yàn)槎鄮熘袝?huì)重復(fù)!

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

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

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

三,分布式事務(wù)的數(shù)據(jù)一致性很難保證!

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

四,多數(shù)據(jù)的排序,分組,統(tǒng)計(jì)會(huì)比較困難!

1,用多線程,對多個(gè)節(jié)點(diǎn)分別查詢,然后匯總!

2,也可以提前冗余查詢表,將所有的經(jīng)常查詢的重點(diǎn)數(shù)據(jù)提前統(tǒng)一到個(gè)庫表里!

分庫分表涉及到的知識點(diǎn)比較多,建議使用專門的分庫分表組件!本人有mycat使用經(jīng)驗(yàn),如果您有相關(guān)問題,歡迎前來探討!

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

Cheriselalala

回答于2022-06-28 14:38

數(shù)據(jù)庫在做了分庫分表之后,關(guān)于ID主鍵,我認(rèn)為需要考慮這幾點(diǎn):


生成算法

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

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

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

  • UUID:生成唯一標(biāo)識碼最常用的算法之一;

  • Snowflake:Twitter開源,基于zk,41位時(shí)間戳(毫秒數(shù))+10位機(jī)器的ID+12位毫秒內(nèi)的流水號+1位符號位(永遠(yuǎn)是0);

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

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


擴(kuò)容會(huì)比較麻煩

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

  • 做數(shù)據(jù)遷移:最簡單暴力,也是最麻煩的一個(gè)方案;因?yàn)楫?dāng)分表(分庫)數(shù)量增多的時(shí)候,因?yàn)榉制?guī)則的變化,每個(gè)表的數(shù)據(jù)都要被重新分配到多個(gè)新的表;

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

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

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

我將持續(xù)分享Java開發(fā)、架構(gòu)設(shè)計(jì)、程序員職業(yè)發(fā)展等方面的見解,希望能得到你的關(guān)注。

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

未東興

回答于2022-06-28 14:38

數(shù)據(jù)量達(dá)到查詢瓶頸的時(shí)候,需要做一些拆分或索引優(yōu)化處理。

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

1、id區(qū)間提前規(guī)劃好,每個(gè)庫分配好整數(shù)區(qū)間,每個(gè)庫中的每個(gè)表也要規(guī)劃號,數(shù)字那么大,總有區(qū)間能夠容納下增長的數(shù)字。

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

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

4、采用納秒級時(shí)間戳+隨機(jī)數(shù)+重試機(jī)制保證數(shù)據(jù)唯一。

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

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

objc94

回答于2022-06-28 14:38

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

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

U2FsdGVkX1x

回答于2022-06-28 14:38

為什么要分物理表呢? 分區(qū)的底層同樣是物理分表但上層MySQL已做好一切展現(xiàn)給我們的是一個(gè)總表,不同的數(shù)據(jù)放到不同分區(qū),CURD甚至索引完全就是當(dāng)成一個(gè)表來操作,其實(shí)展現(xiàn)給用戶的就是一張表,但底層分成了若干個(gè)區(qū)

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

Cciradih

回答于2022-06-28 14:38

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

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

kk_miles

回答于2022-06-28 14:38

苞米豆的mybatis-plus,只需要配置一下就可以,但我沒有實(shí)際應(yīng)用過

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

canger

回答于2022-06-28 14:38

id主鍵不用管。MySQL自己會(huì)處理。無非是操作的時(shí)候不一樣

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

Kyxy

回答于2022-06-28 14:38

看你怎么分,但無論怎么分都要保留或新建主建來關(guān)聯(lián)數(shù)據(jù),數(shù)據(jù)關(guān)聯(lián)不起來,就廢了。

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

最新活動(dòng)

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

我的邀請列表

  • 擅長該話題
  • 回答過該話題
  • 我關(guān)注的人
向幫助了您的網(wǎng)友說句感謝的話吧!
付費(fèi)偷看金額在0.1-10元之間
<