我有一个列ID和1000个项目,其中一些被删除,如id=90, id=127, id=326
如何进行查询以查找可用的ID,以便我可以将其重新用于其他项目?
它像min(ID)
但我想只找到不在我的数据库中的ID,所以如果我删除ID = 90
的项目,下次我点击ADD ITEM我会插入它为id = 90
答案 0 :(得分:37)
您可以使用此查询获取最低可用ID:
SELECT MIN(t1.ID + 1) AS nextID
FROM tablename t1
LEFT JOIN tablename t2
ON t1.ID + 1 = t2.ID
WHERE t2.ID IS NULL
它的作用是将表连接到自身并检查min+1
ID是否为null
。如果它为null,则该ID可用。假设您有ID
所在的表格:
1
2
5
6
然后,此查询将为您提供3
的结果,这就是您想要的。
答案 1 :(得分:5)
不要重复使用ID。您通常拥有足够的可用ID,因此您不必关心碎片。
例如,如果您重新使用ID,搜索引擎中的链接可能会指向与搜索索引中的任何内容完全无关的内容 - 在这种情况下显示“未找到”错误要好得多。
答案 2 :(得分:3)
尝试重用ID
是违反代理键的概念代理关键是好的,因为它表示记录本身,而不是现实生活中的某些对象。如果记录消失,ID也会消失。
经验丰富的数据库开发人员不怕耗尽数字,因为他们知道需要消耗多少个世纪,比如长整数。
顺便说一句,您可能会遇到锁定或违反多线程环境中的唯一性问题,同时发生的事务试图找到ID序列中的间隙。 DB服务器提供的自动增量id生成器通常在事务范围之外工作,从而生成良好的代理键。进一步阅读:Surrogate keys
答案 3 :(得分:2)
查询为like:
SELECT MIN(tableFoo.uniqueid + 1) AS nextID
FROM tableFoo
LEFT JOIN tableFoo tf1
ON tableFoo.uniqueid + 1 = tf1.uniqueid
WHERE tf1.uniqueid IS NULL
答案 4 :(得分:1)
请注意,如果最低ID是免费的,则shamittomar和Haim Evgi的答案不起作用。要允许重新填充最低ID,请预先检查以确定是否可用:
length/2
如果这返回任何内容,则ID为1不是免费的,您应该使用他们的答案。但如果ID为1是免费的,那就使用它。
答案 5 :(得分:1)
在我个人看来。不是从自动增量中删除行,而是使用布尔列来删除"删除"或"已删除"并且在设置移除的标志时,使用空白对行进行额外的安全性。
UPDATE table SET data=" ", removed = TRUE WHERE id = ##
(##是实际的id btw) 那你可以
SELECT * FROM table WHERE removed = TRUE ORDER BY id ASC
这将使您的数据库表现更好,并为您节省服务器的费用。更不用说确保不会发生令人讨厌的错误。
答案 6 :(得分:0)
鉴于您的数据库足够小,正确的答案是根本不重用您的ID 并确保其自动递增的主键。该表是一千条记录,因此您无需任何费用即可完成此操作。
但是,如果你有一张几百万条记录 /更长的id表,你会发现接受的答案不会在合理的时间内完成。
接受的答案将为您提供最小的这些值,但是,您支付不使用自动增量列的价格,或者如果您有一个,不使用自动将列增加为预期的实际ID(就像我一样,否则我不会在这里)。遗留应用程序的优点是ID不是正在使用的实际主键,并且是由lolgorithm随机生成的,没有任何理由,所以我需要一种方法来替换它,因为upping列范围现在是一个非常昂贵的变化。
在这里,它正在计算整个
在报告这些连接的最小值之前,在整个t1和t2之间连接。从本质上讲,您只关心找到的第一个NULL
t1,无论它是否真的是最小的。
因此,您需要取出MIN
并添加LIMIT
为1。
编辑:由于它不是主键,因此您还需要检查not null,因为主键字段不能为null
SELECT t1.ID + 1 AS nextID
FROM tablename t1
LEFT JOIN tablename t2
ON t1.ID + 1 = t2.ID
WHERE t2.ID IS NULL
AND t1.ID IS NOT NULL
LIMIT 1
这总会给你一个你可以使用的id,它不能保证永远是最小的。