簡體   English   中英

如何在 auto_increment 列中找到“洞”?

[英]how find "holes" in auto_increment column?

例如,當我刪除 id 3 時,我有這個:

id | name
 1 |
 2 |    
 4 |
 5 |
 ...

現在,我想搜索丟失的 id,因為我想再次填充 id:

INSERT INTO xx (id,...) VALUES (3,...)

有沒有辦法在 auto_increment 索引中搜索“洞”?

謝謝!

你可以找到像這樣的差距的最高值:

select t1.id - 1 as missing_id
from mytable t1
left join mytable t2 on t2.id = t1.id - 1
where t2.id is null

AUTO_INCREMENT的目的是為您的行生成簡單唯一且無意義的標識符。 一旦您計划重新使用這些ID,它們就不再是唯一的(至少不會及時),所以我覺得您沒有使用正確的工具來完成工作。 如果您決定擺脫AUTO_INCREMENT ,則可以使用相同的算法完成所有插入操作。

至於SQL代碼,此查詢將匹配現有行與具有下一個ID的行:

SELECT a.foo_id, b.foo_id
FROM foo a
LEFT JOIN foo b ON a.foo_id=b.foo_id-1

例如:

 1 NULL
 4 NULL
10 NULL
12 NULL
17 NULL
19   20
20 NULL
24   25
25   26
26   27
27 NULL

因此,過濾掉行並獲得第一個差距很容易:

SELECT MIN(a.foo_id)+1 AS next_id
FROM foo a
LEFT JOIN foo b ON a.foo_id=b.foo_id-1
WHERE b.foo_id IS NULL

以此為出發點,因為它仍需要一些調整:

  • 您需要考慮最低可用數量是最低可能數量的情況。
  • 您需要鎖定表以處理並發插入。
  • 在我的電腦里,它和大桌子一樣慢。

我認為你能做到這一點的唯一方法就是循環:任何其他解決方案都不會顯示大於1的間隙:

insert into XX values (1)
insert into XX values (2)
insert into XX values (4)
insert into XX values (5)
insert into XX values (10)

declare @min int
declare @max int

select @min=MIN(ID) from xx
select @max=MAX(ID) from xx

while @min<@max begin
    if not exists(select 1 from XX where id = @min+1) BEGIN
        print 'GAP: '+ cast(@min +1 as varchar(10))
    END

    set @min=@min+1
end

結果:

GAP: 3
GAP: 6
GAP: 7
GAP: 8
GAP: 9

首先,我同意你不應該嘗試填補漏洞的評論。 您將無法使用單個SQL語句找到所有漏洞。 你必須循環遍歷從1開始的所有可能的數字,直到找到一個洞。 您可以編寫一個sql函數來為您執行此操作,然后可以在函數中使用它。 因此,如果您編寫了一個名為find_first_hole的函數,則可以在插入中調用它,如:

INSERT INTO xx (id, ...) VALUES (find_first_hole(), ...)

這是一個空白和島嶼問題,請參閱此處此處的我(以及其他)回復。 在大多數情況下,使用遞歸CTE可以最優雅地解決間隙和島嶼問題,這在mysql中是不可用的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM