MySQL自增主鍵用完報(bào)什么錯(cuò)?有什么建議?
JAVA前線?
歡迎大家關(guān)注公眾號(hào)「JAVA前線」查看更多精彩分享,主要內(nèi)容包括源碼分析、實(shí)際應(yīng)用、架構(gòu)思維、職場(chǎng)分享、產(chǎn)品思考等等,同時(shí)也非常歡迎大家加我微信「java_front」一起交流學(xué)習(xí)
0 實(shí)驗(yàn)準(zhǔn)備
我們首先通過(guò)代碼輸出Integer和Long最大值:
public?class?IDTest?{
????public?static?void?main(String[]?args)?{
????????System.out.println("JAVA?Integer.MAX_VALUE?=?"?+?Integer.MAX_VALUE);
????????System.out.println("JAVA?Long.MAX_VALUE?=?"?+?Long.MAX_VALUE);
????}
}
//?JAVA?Integer.MAX_VALUE?=?2147483647
//?JAVA?Long.MAX_VALUE?=?9223372036854775807
1 試驗(yàn)一
CREATE?TABLE?`id_test_1`?(
??`id`?int(11)?NOT?NULL?AUTO_INCREMENT?COMMENT?'主鍵',
??`value`?varchar(20)?DEFAULT?NULL?COMMENT?'值',
??PRIMARY?KEY?(`id`)
)?ENGINE=InnoDB?AUTO_INCREMENT=2147483645?DEFAULT?CHARSET=utf8;
insert?into?id_test_1(value)?values?("a");
insert?into?id_test_1(value)?values?("b");
insert?into?id_test_1(value)?values?("c");
insert?into?id_test_1(value)?values?("d");
abc可以正確插入數(shù)據(jù)表,但是插入d時(shí)報(bào)錯(cuò):
Duplicate entry '2147483647' for key 'PRIMARY'2 試驗(yàn)二
主鍵ID改為無(wú)符號(hào)int類型之后,abcd全部可以正確插入:
CREATE?TABLE?`id_test_2`?(
??`id`?int(11)?UNSIGNED??NOT?NULL?AUTO_INCREMENT?COMMENT?'主鍵',
??`value`?varchar(20)?DEFAULT?NULL?COMMENT?'值',
??PRIMARY?KEY?(`id`)
)?ENGINE=InnoDB?AUTO_INCREMENT=2147483645?DEFAULT?CHARSET=utf8;
insert?into?id_test_2(value)?values?("a");
insert?into?id_test_2(value)?values?("b");
insert?into?id_test_2(value)?values?("c");
insert?into?id_test_2(value)?values?("d");
3 試驗(yàn)三
CREATE?TABLE?`id_test_3`?(
??`id`?bigint(20)?NOT?NULL?AUTO_INCREMENT?COMMENT?'主鍵',
??`value`?varchar(20)?DEFAULT?NULL?COMMENT?'值',
??PRIMARY?KEY?(`id`)
)?ENGINE=InnoDB?AUTO_INCREMENT=9223372036854775805?DEFAULT?CHARSET=utf8;
insert?into?id_test_3(value)?values?("a");
insert?into?id_test_3(value)?values?("b");
insert?into?id_test_3(value)?values?("c");
insert?into?id_test_3(value)?values?("d");
abc可以正確插入數(shù)據(jù)表,但是插入d時(shí)報(bào)錯(cuò):
Duplicate entry '9223372036854775807' for key 'PRIMARY'4 試驗(yàn)四
主鍵ID改為無(wú)符號(hào)Long類型之后,abcd全部可以正確插入:
CREATE?TABLE?`id_test_4`?(
??`id`?bigint(20)?UNSIGNED?NOT?NULL?AUTO_INCREMENT?COMMENT?'主鍵',
??`value`?varchar(20)?DEFAULT?NULL?COMMENT?'值',
??PRIMARY?KEY?(`id`)
)?ENGINE=InnoDB?AUTO_INCREMENT=9223372036854775805?DEFAULT?CHARSET=utf8;
insert?into?id_test_4(value)?values?("a");
insert?into?id_test_4(value)?values?("b");
insert?into?id_test_4(value)?values?("c");
insert?into?id_test_4(value)?values?("d");
5 試驗(yàn)總結(jié)
5.1 數(shù)值范圍總結(jié)
Int有符號(hào)范圍:[-2147483648,2147483647]
Int無(wú)符號(hào)范圍:[0,4294967295]
Long有符號(hào)范圍:[-9223372036854775808,9223372036854775807]
Long無(wú)符號(hào)范圍:[0,18446744073709551615]5.2 選擇合適主鍵類型
如果希望單表可以存儲(chǔ)盡可能多的數(shù)據(jù),那么選擇主鍵類型時(shí)Long優(yōu)先于Int,無(wú)符號(hào)類型優(yōu)先于有符號(hào)類型。
5.3 選擇合適分庫(kù)分表時(shí)機(jī)
阿里巴巴開發(fā)手冊(cè)建議:?jiǎn)伪硇袛?shù)超過(guò)500萬(wàn)行或者單表容量超過(guò)2GB才推薦進(jìn)行分庫(kù)分表,如果預(yù)計(jì)三年后數(shù)據(jù)量根本達(dá)不到這個(gè)級(jí)別,請(qǐng)不要在創(chuàng)建表時(shí)就分庫(kù)分表。
在業(yè)務(wù)初期可能并不用分庫(kù)分表,但是隨著業(yè)務(wù)發(fā)展,當(dāng)單表記錄數(shù)超過(guò)一定數(shù)量時(shí)就可以考慮分庫(kù)分表,而不是等到自增主鍵用完時(shí)再分庫(kù)分表,因?yàn)榧词挂杂蟹?hào)Int主鍵值上限分析,單表21億數(shù)據(jù)也太多了。
關(guān)于分庫(kù)分表原理以及如何進(jìn)行分庫(kù)分表實(shí)戰(zhàn),請(qǐng)參看筆者的兩篇文章:
JAVA前線?
歡迎大家關(guān)注公眾號(hào)「JAVA前線」查看更多精彩分享,主要內(nèi)容包括源碼分析、實(shí)際應(yīng)用、架構(gòu)思維、職場(chǎng)分享、產(chǎn)品思考等等,同時(shí)也非常歡迎大家加我微信「java_front」一起交流學(xué)習(xí)
