MySQL數(shù)據(jù)庫(kù)刪除數(shù)據(jù)后自增ID不連續(xù)的問(wèn)題及解決
MySQL數(shù)據(jù)庫(kù)刪除數(shù)據(jù)后自增ID不連續(xù)
1.表中已經(jīng)出現(xiàn)不連貫的數(shù)據(jù)ID時(shí)
執(zhí)行以下語(yǔ)句進(jìn)行修改
SET @auto_id = 0; UPDATE 表名 SET 自增字段名 = (@auto_id := @auto_id + 1); ALTER TABLE 表名 AUTO_INCREMENT = 1;
如果需要清空表的數(shù)據(jù)的話,最好使用TRUNCATE TABLE 表名來(lái)刪除,這樣新增的數(shù)據(jù)自增ID會(huì)從1開(kāi)始,如果使用DELETE來(lái)刪除,新增的數(shù)據(jù)會(huì)沿著之前的ID進(jìn)行自增。
如果使用的數(shù)據(jù)庫(kù)管理軟件是Navicat,那可以選中表右鍵選擇截?cái)啾?,其效果和TRUNCATE的效果是一樣的。
2.在刪除時(shí)解決
//刪除信息 public void delete(int id) { try { PreparedStatement ps = con.prepareStatement("delete from books where id = ?"); ps.setInt(1, id); ps.executeUpdate(); PreparedStatement pr = con.prepareStatement("alter table books auto_increment = ?;"); pr.setInt(1, id - 1); pr.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(e); } }
MySQL自增字段不連續(xù)的原因分析
造成自增字段不連續(xù)的原因
1)唯一鍵沖突導(dǎo)致自增字段值不連續(xù)
示例1:創(chuàng)建數(shù)據(jù)表tb_student3,插入導(dǎo)致唯一鍵沖突的記錄后,在插入數(shù)據(jù)
mysql> CREATE TABLE tb_student3( -> id INT PRIMARY KEY AUTO_INCREMENT, -> name VARCHAR(20) UNIQUE KEY, -> age INT DEFAULT NULL); Query OK, 0 rows affected (0.02 sec) mysql> INSERT INTO tb_student3 VALUES(1,'1','1'); Query OK, 1 row affected (0.01 sec) mysql> INSERT INTO tb_student3 VALUES(NULL,'1','1'); ERROR 1062 (23000): Duplicate entry '1' for key 'name' ERROR 1062 (23000): Duplicate entry '1' for key 'name' mysql> INSERT INTO tb_student3 VALUES(NULL,'2','1'); Query OK, 1 row affected (0.01 sec) mysql> SELECT * FROM tb_student3; +----+------+------+ | id | name | age | +----+------+------+ | 1 | 1 | 1 | | 3 | 2 | 1 | +----+------+------+ 2 rows in set (0.00 sec)
由于name字段有唯一鍵約束,當(dāng)插入相同內(nèi)容的字段時(shí),會(huì)報(bào) Duplicate key error(唯一鍵沖突)。
在這之后,在插入新數(shù)據(jù)時(shí), ,自增 id 就是 3,這樣就出現(xiàn)了自增字段值不連續(xù)的情況。
2)刪除字段導(dǎo)致自增字段值不連續(xù)
示例2:創(chuàng)建數(shù)據(jù)表tb_student4,刪除新增的數(shù)據(jù)后,再次新增數(shù)據(jù)
#創(chuàng)建新表 mysql> CREATE TABLE IF NOT EXISTS tb_student4( -> id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, -> name VARCHAR(10) NOT NULL); Query OK, 0 rows affected (0.02 sec) #新增字段 mysql> INSERT INTO tb_student4(name) VALUES('JAVA'),('PYTHON'); Query OK, 2 rows affected (0.01 sec) Records: 2 Duplicates: 0 Warnings: 0 #查看表內(nèi)容 mysql> SELECT * FROM tb_student4; +----+--------+ | id | name | +----+--------+ | 1 | JAVA | | 2 | PYTHON | +----+--------+ 2 rows in set (0.00 sec) #刪除字段 name='PYTHON' mysql> DELETE FROM tb_student4 WHERE name='PYTHON'; Query OK, 1 row affected (0.01 sec) #查看表內(nèi)容 mysql> SELECT * FROM tb_student4; +----+------+ | id | name | +----+------+ | 1 | JAVA | +----+------+ 1 row in set (0.00 sec) #插入表數(shù)據(jù) mysql> INSERT INTO tb_student4(name) VALUES('MYSQL'),('HTML'); Query OK, 2 rows affected (0.01 sec) Records: 2 Duplicates: 0 Warnings: 0 #查看表內(nèi)容 mysql> SELECT * FROM tb_student4; +----+-------+ | id | name | +----+-------+ | 1 | JAVA | | 3 | MYSQL | | 4 | HTML | +----+-------+ 3 rows in set (0.00 sec)
可以看出,刪除字段后,自增字段不會(huì)補(bǔ)齊而是按照既定數(shù)值繼續(xù)向下排列,會(huì)導(dǎo)致自增數(shù)字不連續(xù)。
3)其他
還有一些情況會(huì)造成自增不連續(xù),比如事務(wù)回滾導(dǎo)致的自增鍵不連續(xù)、自增鎖優(yōu)化帶來(lái)的不連續(xù)等。
解決方法
執(zhí)行以下語(yǔ)句就可以解決
SET @i=0; UPDATE `tablename` SET `id`=(@i:=@i+1); ALTER TABLE `tablename` AUTO_INCREMENT=0
我們執(zhí)行上面由于唯一鍵沖突導(dǎo)致自增不連續(xù)的數(shù)據(jù)表,會(huì)發(fā)現(xiàn)id字段的自增連續(xù)了。
mysql> SET @i=0; Query OK, 0 rows affected (0.00 sec) mysql> UPDATE `tb_student3` SET `id`=(@i:=@i+1); Query OK, 1 row affected (0.02 sec) Rows matched: 2 Changed: 1 Warnings: 0 mysql> ALTER TABLE `tb_student3` AUTO_INCREMENT=0 -> ; Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0mysql> select * from tb_student3; +----+------+------+ | id | name | age | +----+------+------+ | 1 | 1 | 1 | | 2 | 2 | 1 | +----+------+------+ 2 rows in set (0.00 sec)
附:
如果想要清空表的話可以使用TRUNCATE table 'good'語(yǔ)句來(lái)操作,比delete效率高,并且會(huì)將自增歸零
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
MySQL循環(huán)插入千萬(wàn)級(jí)數(shù)據(jù)
這篇文章主要介紹了MySQL如何實(shí)現(xiàn)循環(huán)插入千萬(wàn)級(jí)數(shù)據(jù),幫助大家更好的理解和使用MySQL數(shù)據(jù)庫(kù),感興趣的朋友可以了解下2020-09-09MySQL 統(tǒng)計(jì)查詢(xún)實(shí)現(xiàn)代碼
MySQL 統(tǒng)計(jì)查詢(xún)其實(shí)就是通過(guò)SELECT COUNT() FROM 語(yǔ)法用于從數(shù)據(jù)表中統(tǒng)計(jì)數(shù)據(jù)行數(shù)2014-05-05MySQL實(shí)現(xiàn)JDBC詳細(xì)步驟
JDBC?是?Java?訪問(wèn)數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)規(guī)范,真正怎么操作數(shù)據(jù)庫(kù)還需要具體的實(shí)現(xiàn)類(lèi),也就是數(shù)據(jù)庫(kù)驅(qū)動(dòng),本文給大家介紹MySQL實(shí)現(xiàn)JDBC詳細(xì)講解,感興趣的朋友一起看看吧2022-02-02MySQL生成千萬(wàn)測(cè)試數(shù)據(jù)以及遇到的問(wèn)題
前兩天發(fā)現(xiàn)同事要做一個(gè)對(duì)大表進(jìn)行范圍查詢(xún)的功能,所以需要生成千萬(wàn)數(shù)據(jù)進(jìn)行性能測(cè)試,下面這篇文章主要給大家介紹了關(guān)于MySQL生成千萬(wàn)測(cè)試數(shù)據(jù)以及遇到的問(wèn)題的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08MySQL 格式化時(shí)間的實(shí)現(xiàn)示例
MySQL提供了多種日期和時(shí)間類(lèi)型,在處理時(shí)間時(shí)需要根據(jù)不同類(lèi)型選擇不同的格式化方法,常用的日期類(lèi)型有DATE、YEAR、TIME;常用的日期時(shí)間類(lèi)型有DATETIME和TIMESTAMP,本文就來(lái)介紹一下MySQL 格式化時(shí)間,感興趣的可以了解一下2023-10-10mysqladmin、mysqlshow、mysqlcheck的工具使用
我們一般使用mysql客戶(hù)端工具來(lái)進(jìn)行日常的數(shù)據(jù)庫(kù)操作,本文主要介紹了mysqladmin、mysqlshow、mysqlcheck的工具使用,具有一定的參考價(jià)值,感興趣的可以了解一下2024-07-07MySQL timestamp與時(shí)區(qū)問(wèn)題的解決
本文主要介紹了MySQL timestamp與時(shí)區(qū)問(wèn)題的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06