【问题标题】:Mysql auto_increment proceed with lowest valueMysql auto_increment 以最低值进行
【发布时间】:2011-06-05 08:23:18
【问题描述】:

我的问题是:我有一个带有 auto_increment 列的表。当我插入一些值时,一切正常。 插入第一行:ID 1 插入第二行:ID 2

现在我想在 ID 10 处插入一行。

我的问题是,在此之后只有在 ID 10 之后插入的行(这是正常行为)。

但我希望数据库在创建之前先填充 ID 3-9。

有什么建议吗?

编辑:

澄清一下:这是我想为自己构建的 URL 缩短器。 我将 id 转换为一个单词(a-zA-z0-9) 以进行搜索,并将其保存在数据库中,我将其转换为一个数字,即表的 ID。

现在的问题是: 我缩短了第一个链接(没有名称)-> ID 为 1 并且自动名称为 1 转换为 a-zA-Z0-9 这是一个

接下来也是一样——>ID是2,名字是b,是2转换的。

接下来有趣的是,有人想将链接命名为test -> ID 是4597691,这是转换后的test

现在,如果有人添加另一个没有名称的链接 -> ID 为 4597692 which 将是 tesu,因为数字已转换。

我希望新行将自动插入到最后一个空白处(此处为 3)

【问题讨论】:

  • 你为什么想要那个? id 3-9 丢失有什么问题?
  • 我真的很想知道你为什么会遇到这样的情况。这最终可能会成为一个非常烦人的问题,它与您存储的实际数据无关(考虑到这些 ID 只是内部的)。另外,看看 UUID 是否是您正在寻找的替代品
  • 我正在尝试制作自己的链接缩短器。我将 id 转换为 url 名称并返回。如果我用名字 JohnDoeJohnDoe 建立一个短链接,那么下一个想要随机名字的人将会有 JohnDoeJohnDof,那可能太长了。
  • @gluca,这将使您的插入变慢,通过对丢失键的无用测试来减慢您的数据库,没有任何好处。需要发生的事情是 id 是唯一的。如果您重用以前使用的 id,您还将面临各种参考问题。当 MySQL 删除一个数字时,顺序编号会中断。这是一个非常糟糕的主意。
  • @gluca:我看不到12310JohnDoeJohnDoe之间的联系……

标签: mysql sql auto-increment


【解决方案1】:

您可以为 URL ID 设置另一个整数列。

您的流程可能如下所示:

  • 如果为链接生成了默认名称,那么您只需插入一个新行,用自动增量值填充 URL ID 列,然后将结果转换为相应的名称。

  • 如果为 URL 指定了自定义名称,则在插入一行后,URL ID 列将填充从将所选名称转换为整数获得的数字。

等等。在查找整数 ID 时,您将使用 URL ID 列,而不是表自动增量列。

如果我遗漏了什么,请告诉我。

【讨论】:

  • 这听起来不错,而且我认为它比每次都搜索空闲间隙具有更高的性能,我可能会实现这一点。谢谢。
【解决方案2】:

您可以进行 6 次虚拟插入,然后根据需要删除/更新它们。按照设计,自动递增的概念旨在限制应用程序或用户对数字的控制,以确保输入到表中的每条记录都具有唯一值。

【讨论】:

  • 我认为如果我继续使用 1.2.3 然后像 1000 这样的东西会不太好。但一个好主意
  • 建议不好,只是因为请求不好。 +1 表明自动生成的 ID 是为了提供唯一性而不是没有间隙
【解决方案3】:
ALTER TABLE MY_TABLE AUTO_INCREMENT = 3;

【讨论】:

  • 谢谢,但如果我将值插入我的数据库(这是通过 php 页面),我希望它们自动设置在第三行。我想我每次设置一行并添加1并保存它时都无法获取id,以供以后使用(我认为这不是很漂亮)。
【解决方案4】:

您必须找到第一个未使用的 id,将其存储为用户变量,用作插入的 id。

SELECT @id := t1.id +1 
FROM sometable t1 LEFT JOIN sometable t2 
ON t2.id = t1.id +1 WHERE t2.id IS NULL LIMIT 1;

INSERT INTO sometable(id, col1, col2, ... ) VALUES(@id, 'aaa', 'bbb', ... );

如果您仍然有差距,则必须为每个插入运行两个查询,由您决定是否值得这样做。

【讨论】:

  • 听起来不错,但是 select table.id from table where id is null limit 1 返回一个空结果
  • @gluca,那不是 piotrm 的回答中的查询,你在说什么?
  • @Johan 好的,那么查询是什么?你得到 t1.id ,其中 t2.id 为空并且只得到一个结果。我只对其进行了修改,使其适用于我没有多说的一张桌子。你能说一下你的sql是如何工作的(不明白第三行的开头)吗?
  • @gluca:这个答案中正好有 1 个表:sometable
  • @ypercube:啊,现在我明白了,但是为什么会有LEFT JOIN 的想法(这让我猜对了)。这是为了合并两张表,不是吗?
【解决方案5】:

不是 100% 确定您要达到的目标,但这样的事情可能会奏效:

drop table if exists foo;
create table foo
(
id int unsigned not null auto_increment primary key,
row_id tinyint unsigned unique not null default 0
)
engine=innodb;

insert into foo (row_id) values (1),(2),(10),(3),(7),(5);

select * from foo order by row_id;

+----+--------+
| id | row_id |
+----+--------+
|  1 |      1 |
|  2 |      2 |
|  4 |      3 |
|  6 |      5 |
|  5 |      7 |
|  3 |     10 |
+----+--------+
6 rows in set (0.00 sec)

【讨论】:

  • 谢谢你,但我的意思是,(关于你的例子)如果我现在插入:插入 foo (id,row_id) 值 (10,11) 然后插入:插入 foo (row_id)值 (12) 那么 row_id 为 12 的行的 id 应该是 7 而不是 11。希望我已经正确解释了
猜你喜欢
  • 1970-01-01
  • 2021-05-07
  • 2020-03-21
  • 1970-01-01
  • 1970-01-01
  • 2021-03-14
  • 2016-07-26
  • 1970-01-01
  • 2021-01-15
相关资源
最近更新 更多