我正在研究一天可能发生的问题。 假设你有一个带有id和name字段的InnoDB MySQL表。 id字段有BIGINT(20)并且是AUTO_INCREMENT加上它的主键。
如果此表已满,您会怎么做,这意味着我们已达到id的限制,并且不再生成自动增量编号。
答案 0 :(得分:5)
我们假设一个表格结构如下:
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
列的值存在间隙,那么您仍然可以插入使用表中不存在的值的行,但您必须在{{1}中指定id
的值查询。
无论如何,如果INSERT
列的类型为AUTO_INCREMENT
,您无需担心。
假设代码每秒插入一百万条记录(这是高度高估的,不能说不可能),BIGINT
列的值足够用于下一个half of million years }。如果列不是id
,则只需292,277
年。
我目睹了使用UNSIGNED
(而不是INT(11)
)作为UNSIGNED
ed PK的实时网络服务器上的行为,该表记录了有关网络访问的信息现场。经过几年的顺利运行,当访问次数达到AUTO_INCREMENT
(2^31
十亿次等等)时,它在半夜失败了。
将列类型从2
更改为INT
不是20亿条记录表的解决方案(完成时间需要很长时间,当系统处于活动状态时,永远不会有足够的时间)。解决方案是创建一个具有相同结构的新表,但PK列为BIGINT
,BIGINT
列为初始值,然后切换表:
AUTO_INCREMENT
答案 1 :(得分:2)
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)
您认为这个数字是一个小数字吗? 也许在你达到这个数字之前你会死的