2012-12-12 52 views
1

我只是想知道,如果存在的根據本內容的MySQL表的自動增量自動復位爲最低值的優雅的方式。自動設置的MySQL自動增量到最小值

例如:

MYTABLE:

1 content of row 1 
2 content of row 2 
3 content of row 3 
4 content of row 4 
5 content of row 5 

現在的自動增量將在6

但在此之前我插入了新的內容,我刪除的行3,4和5的內容看起來像這樣:

1 content of row 1 
2 content of row 2 

自動增量仍然是6.

這就是問題所在。

我想autoincrement爲3,因爲它是根據插入的ID的最低可能值。

的將阻止非常大的數字,如果自動增量將增長「無限」,走出的12位長整型的範圍。

感謝您的任何建議!

+1

我下面提供的答案,但我要評論說,在大多數情況下,automincrement場的實際值是沒有意義的,所以努力保障和持續訂單從1到任何最高值是沒有必要的。您也可以隨意使用允許值高達'18446744073709551615'的BIGINT數據類型。我猜測這應該足以滿足大多數用例。因此,您對無限擴展的擔憂不應成爲您設計應用程序的工作原因。 –

+1

等什麼?我的id = 3的文檔已經完全改變了?誰做到了,發生了什麼事?混亂! '''(即:如果你可以避免它,請不要回收ID) – Wrikken

+0

@Wrikken的好評 - 這是爲什麼在大多數使用自動增量主鍵的表中,你永遠不應該刪除。如果您需要「刪除」或取消激活某個項目,您通常可以通過添加值爲0或1的TINYINT「已刪除」列來輕鬆完成此操作,以指示項目是否應被視爲可供使用。 –

回答

9

這取決於你的存儲引擎,

對於MyISAM和InnoDB的MySQL的5.6+,您可以設置AUTO_INCREMENT值表說1。該值將自動增加到最大電流值+1。這樣做。

ALTER TABLE table_name AUTO_INCREMENT = 1; 

對於InnoDB對MySQL的< 5.6,這是不行的,你將需要手動執行此操作是這樣的:

SELECT MAX(autoincrement_field) + 1 FROM table_name INTO @maxautoinc; 
ALTER TABLE table_name AUTO_INCREMENT = @maxautoinc; 

注意在最後一種情況下,這兩個查詢將需要運行具有相同的數據庫連接。

+0

這將工作,但爲什麼我應該這樣做?因爲數據庫表看起來更好,如果有人看看這些ID? –

+0

@ChristianKuetbach我同意你的看法。通常,當使用自動增量字段時,他們確實不在乎實際的自動增量值是什麼,只是保證它們是唯一的,並基於插入順序升序。 –

+0

@MikeBrant使用自動生成的值...我甚至不相信他們的順序應該重要。如果您需要歷史記錄,那麼使用時間戳就是我所教的內容。 – Wrikken

0

重置自動遞增ID。

http://community.spiceworks.com/scripts/show/3042-reset-auto-increment-ids

更新所有自動增量列在數據庫中根據數據庫中的當前值的最小可能值。我們需要在清理完數據庫後執行此操作。

使用存儲過程中的一個準備好的聲明:

drop PROCEDURE if exists reset_autoincrement; 
DELIMITER // 
CREATE PROCEDURE reset_autoincrement (IN schemaName varchar(255)) 
BEGIN 
    DECLARE done INT DEFAULT FALSE; 
    DECLARE o_name VARCHAR(255); 
    DECLARE o_table VARCHAR(255); 
    DECLARE cur1 CURSOR FOR SELECT COLUMN_NAME, TABLE_NAME FROM information_schema.`COLUMNS` WHERE extra LIKE '%auto_increment%' and table_schema=schemaName; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; 
    OPEN cur1; 
    read_loop: LOOP 
    FETCH cur1 INTO o_name, o_table; 

    IF done THEN 
     LEAVE read_loop; 
    END IF; 

    set @qry1 = concat('SELECT MAX(`',o_name,'`) + 1 as autoincrement FROM `',o_table,'` INTO @ai'); 
    PREPARE stmt1 FROM @qry1; 
    EXECUTE stmt1; 

    IF @ai IS NOT NULL THEN 
     SELECT o_name, o_table; 
    select @qry1; 
    select @ai; 
    set @qry2 = concat('ALTER TABLE `',o_table,'` AUTO_INCREMENT = ', @ai); 
    select @qry2; 
    PREPARE stmt2 FROM @qry2; 
    EXECUTE stmt2; 
    END IF; 

    END LOOP; 

    CLOSE cur1; 
END // 
DELIMITER ; 


call reset_autoincrement('my_schema_name');