MySQL自增字段的自增值超過字段宣告的範圍怎麼辦

2021-10-09 09:25:22 字數 2403 閱讀 3697

面試遇到乙個問題,設定自增主鍵的資料型別為int(10),範圍設定的比較小,如果自增超過這個範圍會怎麼樣?當時一臉懵逼,確實沒考慮過這個情況。

思路與猜測

首先是知道,字段型別宣告為int(10),後面的長度10只是zerofill的長度,不影響資料的儲存,也就是自增超過的範圍應該是int型別欄位的最大值。

型別儲存占用位元組

最小值最大值

無符號int40

4294967295(2^32-1)

有符號int

4-2147483648(-2^31)

2147483647(2^31-1)

對於無符號的自增主鍵,也就是超過2^32-1=4294967295。由於不知道會發生什麼,有幾種猜測:

重新從0開始?

直接返回錯誤碼?

驗證與結果

新建乙個表用於測試自增;為了驗證問題,把自增值設定到了最大值-2,用於測試。

create

table

`auto_inc `

(`id`

int(1)

unsigned

notnull

auto_increment

,`name`

varchar(64

)character

set utf8mb4 collate utf8mb4_general_ci not

null

primary

key(

`id`

)using

btree

)engine

=innodb

auto_increment

=4294967294

character

set= utf8mb4 collate

= utf8mb4_general_ci row_format = dynamic;

先插入一條資料,能夠插入成功,自增值上公升1;

mysql>

insert

into auto_inc(name)

values(''

);query ok,

1row affected (

0.04 sec)

mysql>

select

*from auto_inc;

+------------+------+

| id | name |

+------------+------+

|4294967294||

+------------+------+

1row

inset

(0.03 sec)

然後繼續插入兩條資料;發現第二條插入資料報錯了,主鍵衝突,而此時表裡最大的id是4294967295

mysql>

insert

into auto_inc(name)

values(''

);query ok,

1row affected (

0.04 sec)

mysql>

insert

into auto_inc(name)

values(''

);1062

-duplicate entry '4294967295'

forkey

'primary'

mysql>

select

*from auto_inc;

+------------+------+

| id | name |

+------------+------+

|4294967294||

|4294967295||

+------------+------+

2rows

inset

(0.04 sec)

所以可以得出結論:自增主鍵超過資料型別的最大值後,會繼續使用最大值作為下一次的遞增值,如果最大值記錄在表中已經存在,會報主鍵衝突錯誤;

這個問題用smallint和tinyint做自增鍵也可以復現,而且不需要設定自增值。

沒有意義。面試的時候可以考你一下。

如果是smallint或tinyint型別的自增主鍵溢位,那只能說表設計的不合理,用範圍這麼小的型別做主鍵欄位;

如果是int型別的自增主鍵溢位,int範圍都21億了,再加上主鍵一般無符號,42億的取值範圍不夠用?即便插入報錯之類的導致主鍵不連續,那30多億有效主鍵總有吧,mysql乙個表30億資料,想啥呢老哥,還不考慮分庫分表?

至於bigint……

可能mysql的開發人員也覺得這樣的情況應該由開發者決定怎麼處理,所以就在溢位後仍使用最大值?

todo

mysql 自增字段原理 MySQL自增字段暴增

找了點資料 從網上看到一篇文章,mysql在檢測到表中有損壞的記錄時,會自動修復,為了保證資料的完整性,mysql會以空格 0x20 寫進磁碟來完成修復。根據欄位的型別,自增字段的長度不同,所允許的最大值也不同。見下 int 10 unsigned型別最大值十進位制為4294967295,十六進製制...

Mysql自增字段

1.關鍵字 auto increment 2.自增用法 例 create table animals id mediumint not null auto increment,name char 30 not null,primary key id 3.關於自增 q 怎麼獲得當前的自增的最大值?q ...

mysql自增字段重排

由於刪除了某些記錄行,所以自增字段不連續了。重排或歸零的方法 方法1 truncate table 你的表名 這樣不但重新定位自增的字段,而且會將表裡的資料全部刪除,慎用!方法2 delete from 你的表名 dbcc checkident 你的表名,reseed,0 重新定位自增的字段,讓它從...