【问题标题】:Find lowest ID that does not exist [duplicate]查找不存在的最低 ID [重复]
【发布时间】:2013-10-02 14:51:35
【问题描述】:

我有一个表,其中每一行都有一个 id,每次我插入一个新行时,它都会使用最高的 id 并加 1。但是,我希望新行取回原来的行数删除。如何找到不存在的最低 id?谢谢

【问题讨论】:

  • 不要这样做。自增主键不应该乱用。
  • 确实是重复的。将删除
  • 这是个坏主意。首先,您可以让您的 mysql 引擎负责创建唯一标识符(id),不建议您自己执行此操作。第二个 id 必须是唯一的,甚至删除的行也必须有自己的 id。例如,当您有一个名为 william 的 id 为 3 的用户,您删除该用户并插入一个名为 jan 的新用户。 William 愿意查看他的数据并在他的 id 3 上搜索他突然发现有关 jan 的信息。你不要这样做,让 mysql 用自动增量来完成任务
  • 关于这样做的进一步说明。使用 auto_increment 字段,MySQL 将确保它们在生成它们时是唯一的。如果您尝试重用一个已被释放的语句,则有可能有 2 个语句同时检索相同的 id,并且都尝试使用它。

标签: mysql sql


【解决方案1】:

可以在同一张表上使用LEFT JOIN,看看下一个id是否存在。
我不认为这个解决方案对于很多行来说真的很好,但它确实有效:

SELECT (t.id + 1)
FROM `table` as t
LEFT JOIN `table` s ON s.id = (t.id + 1)
WHERE s.id IS NULL
ORDER BY t.id
LIMIT 1

【讨论】:

  • 没有 ORDER BY 的 LIMIT 几乎毫无意义。只是说;-)
  • 感谢您的指点,我刚刚编辑了我的答案。
【解决方案2】:

不要重复使用以前使用过的 id 值。

示例场景:

  • 假设您的网站有辱骂用户发送挑衅性电子邮件。电子邮件引用用户的主键编号。您删除了违规用户的帐户,但电子邮件仍然存在。您将已删除的 id 重新分配给一个新的好用户,但他不断收到有关他过去不负责的滥用电子邮件的投诉。

自动增量值应该是唯一的,但它们不需要是连续的

32 位有符号整数最大可达到 231-1,或 2147483647。64 位有符号整数最大可达到 263-1,或 9223372036854775807。您不可能用完所有整数。

MySQL不取最高值加1。它分配序列中的下一个值。由于插入失败、删除行或回滚事务,您可能会丢失值。这很正常。如果您尝试解决它,您的应用程序将变得缓慢而复杂。您应该按照设计使用自动增量功能,并接受不可避免的差距。

例外:如果重启 MySQL 服务,InnoDB 的自增值会重置为 MAX(id)+1。

【讨论】:

  • 人们太迷恋身份证号码了。大多数时候,它们不应该直接暴露给用户。如有必要,添加一个可展示的“序列号”,纯粹是装饰性的,可以根据需要进行调整,而不会破坏数据完整性或回收旧数字。
  • @tadman,是的,在我的书 SQL Antipatterns 中,我将自动增量值的回收称为“伪键 Neat-Freak”。
【解决方案3】:

您可以使用 AUTO_INCREMENT 来获取唯一递增的 ID,但它们通常不会被重复使用。重用旧值有什么好处?

参考:http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html

【讨论】:

    【解决方案4】:

    试试这个:

    select id+1
    from users
    where (id+1) not in (select id from users) limit 1
    

    SQLFiddle:http://www.sqlfiddle.com/#!8/3e5a0/5

    请注意,我同意其他人的观点,他们表示您应该决定这是否是一个好的设计。如果您可以选择不重复使用数字,我强烈建议您这样做.. .

    【讨论】:

      猜你喜欢
      • 2012-02-06
      • 2017-03-06
      • 1970-01-01
      • 2013-07-11
      • 1970-01-01
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多