MySQL自增主键用完报什么错?有什么建议?
0 实验准备
我们首先通过代码输出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 试验一
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可以正确插入数据表:
2147483645 a 2147483646 b 2147483647 c
d不能正确插入数据表:
Duplicate entry 2147483647 for key PRIMARY
2 试验二
主键ID改为无符号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 试验三
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可以正确插入数据表:
9223372036854775805 a 9223372036854775806 b 9223372036854775807 c
d不能正确插入数据表:
Duplicate entry 9223372036854775807 for key PRIMARY
4 试验四
主键ID改为无符号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 试验总结
5.1 数值范围总结
Int有符号范围:[-2147483648,2147483647] Int无符号范围:[0,4294967295] Long有符号范围:[-9223372036854775808,9223372036854775807] Long无符号范围:[0,18446744073709551615]
5.2 选择合适主键类型
如果希望单表可以存储尽可能多的数据,选择主键类型时Long优先于Int,无符号优先于有符号。
5.3 选择合适时机分库分表
阿里巴巴开发手册建议:单表行数超过500万行或者单表容量超过2GB才推荐进行分库分表,如果预计三年后数据量根本达不到这个级别,请不要在创建表时就分库分表。
在业务初期可能并不用分库分表,但是随着业务发展,当单表记录数超过一定数量时就可以考虑分库分表,而不是等到自增主键用完时再分库分表,因为即使以有符号Int主键值上限分析,单表21亿数据也太多了。
分库分表原理与实际应用请参看笔者的两篇文章:
上一篇:
IDEA上Java项目控制台中文乱码