大多数自动增量方案的工作方式是数据库记住为每个此类字段分配的最后一个数字,并且插入的下一条记录总是+1。所以它只需要记住 1 个数字:分配的最后一个数字。
假设您插入了 5 条记录。他们得到 1、2、3、4、5。现在删除 2 和 4。数据库如何知道在接下来的两次插入中重复使用 2 和 4?
我想,它可以在每次插入时扫描表中的所有记录,寻找序列中的第一个孔。但是每次插入都需要读取表中的每条记录。如果表有数百万条记录会怎样?插入可能需要几分之一毫秒到几分钟。
它可以保存一张已删除记录的表格。据推测,它每次插入时都会将第一个数字从表中拉出。但是,现在每个插入都是:检查表。有记录吗?如果是这样,取那个号码,删除记录。如果没有,请取下一个可用的号码。该表必须同步,以便如果多个用户正在添加记录,我们不会两次给出相同的数字。如果有很多删除,它可能会变得非常大。即使每次执行插入时只是额外读取一次,我们现在也执行两次操作而不是一次:性能将减半。
好的,我们可以处理迄今为止分配的最高数字被删除的特殊情况,然后从我们迄今为止分配的最高数字中减去 1。可行,但是否值得为那个特殊情况制定特殊规则?您多久删除一次插入的最后一条记录?如果删除基本上是随机发生的,那么该记录将被删除的可能性很小。
总是分配一个新号码有明显的优势:
一:简单。这种行为是直截了当且易于预测的。没有特殊情况。
二:速度。如前所述,替代方案需要额外的工作。也许不是很多,但如果我们只需要为每个插入处理一个额外的记录,我们的性能就会降低一半。
三:我们可以使用分配的编号来告诉我们添加记录的顺序。高数记录总是比低数记录更新。在进行临时查询和跟踪问题时,我经常发现这很方便。
四:我们避免潜在的错误连接。假设您向表 A 添加一条记录,并为其分配编号 12。然后您向表 B 添加一条记录,其中包含对表 A 的引用,因此我们插入该编号 12。假设对于各种您不将其声明为外键的原因。然后你从表 A 中删除记录 12。所以现在你在表 B 中有这个悬空引用。这很糟糕。但是想象一个新的记录被添加到 A 并且它得到一个循环的数字 12。现在我们在 B 中有一条记录指向 A 中的错误记录。悬空指针是不好的,但错误的指针更糟糕。客户因他人的指控而被收取费用,或因犯罪而被错误逮捕的人等。
更复杂的系统会有什么好处?我看到的唯一好处是,我们将减少用尽可能数字的可能性。但是如果序列号是一个 4 字节的整数,那么就有 20 亿个可能的值。有多少表在其生命周期内获得 20 亿次插入?当然,如果表有 50 亿条记录,那么无论您是否尝试重用数字,您都会遇到问题。我想如果您有一些非常大容量的队列,其中不断添加新记录而丢弃旧记录,这可能是一个问题。或者,如果您经常删除记录并重新插入它们,而不是在原地进行更新。但坦率地说,我从事这项业务已有 30 年了,我从来没有遇到过问题,因为数据库中的自动序列用完了数字。我不怀疑它发生在某个地方的某个人身上,但这不是一个常见的问题。我不认为它很常见到足以破坏一个干净、简单的系统。