2016-02-26 32 views
0

這是我的表id字段爲無符號的TINYINT PRIMARY KEY與NOT NULL和AUTO_INCREMENT。是可以更新到空值的自動增量主鍵值爲MySQL表

+----+ 
| id | 
+----+ 
| 1 | 
| 4 | 
|254 | 
|255 | 
+----+ 

我的應用程序是一個嵌入式應用程序,所以我使用tinyint這樣的小型數據類型。我的id值總數不會高達255.但如果中間值被刪除了多少次,那麼插入新的id值遲早肯定會達到255。

我有一些問題,

是否可以設置自動遞增特性使得它會插入新的ID在不存在更大的價值(這裏是2)?

如果不是請建議某種方式來處理這個問題,除了使用更高的數據類型的id和更新刪除一個id後更高的id值(如,如果我刪除id = 2更新所有id值大於2 id -1,以便所有值在插入新值時保持順序)。

+2

我不會質疑是否有必要保持TINYINT你的情況,但我想指出的是,自動遞增不支持「重置」功能的示例,而且你所做的任何事情都會根據你的需求定製。你可能想要檢查[this](http://stackoverflow.com/questions/2214141/auto-increment-after-delete-in-mysql)SO q-and-a。 – Sevle

+1

如果你想做這樣的事情,那麼你肯定不想自動遞增功能。也就是說,我可以想到爲什麼你會想要做這樣的事情,沒有任何理由,它幾乎可以肯定地指出你對關係數據理解的缺陷。 – Strawberry

+0

@Strawberry我該如何使用有限的ID? –

回答

1

附加您的字段進行插入。這將用最低的自由ID

INSERT INTO ai (id) (
    SELECT a.id+1 FROM ai a 
    LEFT JOIN ai b ON a.id+1 = b.id 
    WHERE b.id IS NULL LIMIT 1 
) 

或獲得也1

SELECT a.id+1 FROM (
     SELECT 0 AS id UNION SELECT id FROM ai 
     ) AS a 
    LEFT JOIN ai b ON a.id+1 = b.id 
    WHERE b.id IS NULL 
    ORDER by a.id ASC 
    LIMIT 1; 
+0

嗨Bernd Buffen偉大的工作。但是,我應該禁用那麼自動增量? –

+0

沒有那不必要。最好有一個自動增量,所以你可以使用兩者。 Tha autoincrement總是設置爲max + 1。所以如果表中只有3行(id 1,2,3),並且插入id 100 auto_increment被設置爲101。但他們從未設置爲較低的價值 –

+0

我已將其添加到我的回答中 –

0

我想不出你爲什麼選擇這個任意限制的約束。也就是說,如果要做到這一點,那麼我會構建一個包含所有可能的整數(1-255)的表格和一個指示該值當前是否正在使用的標誌。所以DELETE變成UPDATE x SET flag = 0 WHERE id = n。然後查詢找到最低的0標誌變得微不足道。

+0

感謝您的回覆。這真是個好主意。由於我是新手,我已經說過我正在開發嵌入式應用程序。我還有另外一個問題,那就是添加另一列而不是像Bernd Buffen所建議的那樣工作? –

+0

我不明白這個解決方案,所以我不能發表評論。 – Strawberry

+0

如果此主鍵鏈接到其他表的外鍵,該怎麼辦?在這種情況下,設置標誌= 0不會刪除此父表中的行。但我可能想從子表中刪除行(我不能使用刪除級聯功能,所以我必須從所有這些子表中刪除這些行) –

0

@

邊緣戈德堡 - 如果你要重新排序的entrys和使用AUTO_INCREMENT使用。然後,lst_insertid也可以工作 - : - 在刪除一個行之後 UPDATE abc,(SELECT @nr:= 0)AS INIT SET a:= @nr:=(@ nr + 1); ALTER TABLE abc AUTO_INCREMENT = 1;

- 插入新的 INSERT INTO ABC(一)VALUES(1234); SELECT LAST_INSERT_ID();

+0

它不工作 –

+0

我有添加的回答,抱歉,但我不能在評論格式化 –

0

這裏是集AUTO_INCREMENT

MariaDB []> select * from abc; 
+-------+------+ 
| a  | b | 
+-------+------+ 
| 00001 | 2 | 
| 00002 | 3 | 
| 00004 | 5 | 
| 00005 | 6 | 
| 00007 | 8 | 
| 00008 | 9 | 
| 00009 | 10 | 
| 00010 | 11 | 
| 00012 | 13 | 
| 00013 | 14 | 
| 00014 | 15 | 
| 00015 | 16 | 
| 00016 | 17 | 
| 00017 | 18 | 
| 00018 | 19 | 
| 00033 | 34 | 
| 00077 | 78 | 
| 00555 | 556 | 
+-------+------+ 
18 rows in set (0.00 sec) 

MariaDB []> -- After DELETE a ROW 
MariaDB []> UPDATE abc , (SELECT @nr:=0) AS INIT SET a := @nr := (@nr+1); 
Query OK, 16 rows affected (0.03 sec) 
Rows matched: 18 Changed: 16 Warnings: 0 

MariaDB []> ALTER TABLE abc AUTO_INCREMENT=1; 
Query OK, 0 rows affected (0.00 sec) 
Records: 0 Duplicates: 0 Warnings: 0 

MariaDB []> select * from abc; 
+-------+------+ 
| a  | b | 
+-------+------+ 
| 00001 | 2 | 
| 00002 | 3 | 
| 00003 | 4 | 
| 00004 | 5 | 
| 00005 | 6 | 
| 00006 | 7 | 
| 00007 | 8 | 
| 00008 | 9 | 
| 00009 | 10 | 
| 00010 | 11 | 
| 00011 | 12 | 
| 00012 | 13 | 
| 00013 | 14 | 
| 00014 | 15 | 
| 00015 | 16 | 
| 00016 | 17 | 
| 00017 | 18 | 
| 00018 | 19 | 
+-------+------+ 
18 rows in set (0.00 sec) 

MariaDB []> INSERT INTO abc (a) VALUES(NULL); 
Query OK, 1 row affected (0.01 sec) 

MariaDB []> SELECT LAST_INSERT_ID(); 
+------------------+ 
| LAST_INSERT_ID() | 
+------------------+ 
|    19 | 
+------------------+ 
1 row in set (0.00 sec) 

MariaDB []> select * from abc; 
+-------+------+ 
| a  | b | 
+-------+------+ 
| 00001 | 2 | 
| 00002 | 3 | 
| 00003 | 4 | 
| 00004 | 5 | 
| 00005 | 6 | 
| 00006 | 7 | 
| 00007 | 8 | 
| 00008 | 9 | 
| 00009 | 10 | 
| 00010 | 11 | 
| 00011 | 12 | 
| 00012 | 13 | 
| 00013 | 14 | 
| 00014 | 15 | 
| 00015 | 16 | 
| 00016 | 17 | 
| 00017 | 18 | 
| 00018 | 19 | 
| 00019 | 20 | 
+-------+------+ 
19 rows in set (0.01 sec) 

MariaDB []> 
+0

嗨你的幫助再次感謝,但我在我的問題已經特別提到,我要尋找不是使用ID更高的數據類型和刪除ID(如你在這裏建議)之後更新更高的ID值的其他解決方案。 –

相關問題