假设我有一个简单的3列表。
CREATE TABLE `test1` (
id INT,
name VARCHAR(40),
age INT,
PRIMARY KEY (id)
);
如果我然后插入让表示5个值到表中将有5个记录。每条记录的id
范围为1 - 5.如果我要删除4条记录,请留下id
为1的记录,然后再插入4条记录,如何来吧,它不是从id=2
开始,而是继续,所以它从6开始?
答案 0 :(得分:2)
为什么呢?因为它是最容易实现的。它可以通过单个" next值"来实现。每次插入新行时计数器并递增它。
自动重置下一个值将非常昂贵。由于可以按任何顺序删除行,因此服务器必须在每次插入或删除时查看整个表以确定下一个值。
答案 1 :(得分:2)
这是一个解释为什么它不能在DELETE上减少AI的场景:
Ashley启动一个事务并删除id=2
到id=5
的行。但阿什利并没有立即承诺。
Bill开始自己的事务并插入一个新行。由于id
值2到5已被删除,因此它们可以用于抓取。比尔的行获得id=2
。
Ashley回滚第一笔交易。因此,id=2
到id=5
的行会返回
但Bill的交易已经插入了id=2
的新行!
另一种方法是根据每个事务可以看到的内容进行增量,并忽略未提交的更改:
Ashley删除id=2
到id=5
的行。不要提交。
Bill开始自己的事务并插入一个新行。由于id
值2到5仍然存在于Bill的数据视图中,因此不要使用这些值。分配id=6
。
Ashley承诺第一笔交易。因此id=2
到id=5
的行已经消失,而Bill的行有id=6
行,导致了一个神秘的差距!
避免这种情况的唯一方法是将所有事务序列化。换句话说,比尔的INSERT将不得不等到Ashley的交易得到解决。我们希望避免这种情况,并允许并发插入。
出于这个原因,AI机制必须在事务范围之外运行。并发交易可以"见"即使有未提交的事务正在进行中,表的最新AI值也是如此。防止重复使用值的唯一方法是始终递增,而不是递减。
这确实会导致"差距"时。这是正常的和预期的。 AI键不需要连续,它们只需要是唯一的。
答案 2 :(得分:1)
这对你有好处;想象一下你把这些id存储在其他地方;您仍然可以识别已删除的记录,并跟踪您拥有的记录以及您不再记录的记录。
无论如何,您始终可以将主键设置为INT或CHAR,然后创建一个函数来创建自己的ID。
答案 3 :(得分:0)
每个表都有自己的AUTO_INCREMENT
计数器,当需要自动生成新ID时,会查询该计数器。由于以下几个原因,该值不一定与表的当前内容相对应:
两个同时INSERT
个查询不应自动生成相同的ID。如果最大值基于表的实际内容,则两个查询都会看到MAX(id) + 1
的相同值 - 特别是如果两个插入都在事务中完成 - 并且其中一个查询由于重复而最终失败键。
MySQL允许您设置 AUTO_INCREMENT
值,该值定义要自动生成的下一个值。如果DBMS只是在满意的情况下将值重置为MAX(id) + 1
,那就不会太用了。