mysql 如果自动递增值达到其限制,该怎么办?

rqmkfv5c  于 2023-02-28  发布在  Mysql
关注(0)|答案(3)|浏览(208)

我正在做一个小的研究,有一天可能会发生的问题。假设你有一个InnoDB MySQL表,有一个id和一个name字段。id字段有BIGINT(20),是AUTO_INCREMENT加上它的主键。
如果这个表已满,意味着我们已经达到了ID的限制,并且无法再生成自动递增的编号,您该怎么办?

euoag5mw

euoag5mw1#

让我们假设一个表结构如下:

CREATE TABLE `tbl` (
    `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (`id`)
);

INSERT查询,如:

INSERT INTO tbl(id) VALUES (NULL);

在真实的代码中,表中还有其他列,它们也出现在INSERT查询中,但我们可以放心地忽略它们,因为它们对这个特定问题没有任何价值。
当列id的值达到其最大值时,无法使用上面的查询在表中插入更多行。下一个INSERT将失败,并显示错误:
SQL错误(167):列“id”的值超出范围。
如果id列的值中有间隙,则仍然可以插入使用表中不存在的值的行,但必须在INSERT查询中指定id的值。
无论如何,如果AUTO_INCREMENT列的类型是BIGINT,则不必担心。
假设代码每秒插入100万条记录(这被高估了,但不能说是不可能的),那么id列有足够的值供下一个half of million years使用,或者如果该列不是UNSIGNED,则只有292,277年的值。
我在一个实时的Web服务器上目睹了这种行为,该服务器使用INT(11)(而不是UNSIGNED)作为记录网站访问信息的表的AUTO_INCREMENT ed PK。经过几年的平稳运行,当访问量达到2^312十亿左右)时,它在半夜失败了。
将列类型从INT更改为BIGINT并不是处理20亿条记录表的解决方案(要花很长时间才能完成,而且当系统运行时,时间永远不够)。解决方案是创建一个结构相同的新表,但PK列为BIGINTAUTO_INCREMENT列为初始值,然后切换表:

CREATE TABLE `tbl_new` (
    `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (`id`)
) AUTO_INCREMENT=2200000000;

RENAME TABLE `tbl` TO `tbl_old`, `tbl_new` TO `tbl`;
ezykj2lf

ezykj2lf2#

tinyint: 1 byte, -128 to +127 / 0 to 255 (unsigned)
smallint: 2 bytes, -32,768 to +32,767 / 0 to 65,535 (unsigned)
mediumint: 3 bytes, -8,388,608 to 8,388,607 / 0 to 16,777,215 (unsigned)
int/integer: 4 bytes, -2,147,483,648 to +2,147,483,647 / 0 to 4,294,967,295 (unsigned)
bigint: 8 bytes, -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 / 0 to 18,446,744,073,709,551,615 (unsigned)

你认为这个数字很小吗?也许你还没达到这个数字就已经死了

jucafojl

jucafojl3#

  • 使用id varchar(255),然后在插入每条记录之前手动生成(例如,将HH:mm:ss.SSS中的日期与表名连接)。*

相关问题