获得下一个未使用的id的最有效方法

时间:2010-08-25 18:06:53

标签: sql scalability execution-time

(与Finding the lowest unused unique id in a listGetting unused unique values on a SQL table相关)

假设我有一个包含id列和其他一些表的表(它们在这里没有任何区别):

+-----+-----+
| id  |other|
+-----+-----+

id具有数值增加值。我的目标是获得最低的未使用ID并创建该行。因此,当我第一次运行它将返回0并且该行的行将被创建。几次执行后,它将如下所示:

+-----+-----+
| id  |other|
+-----+-----+
|  0  | ... |
|  1  | ... |
|  2  | ... |
|  3  | ... |
|  4  | ... |
+-----+-----+

通常有些行可能会被删除。我们假设删除了id为13的行。表格不会是这样的:

+-----+-----+
| id  |other|
+-----+-----+
|  0  | ... |
|  2  | ... |
|  4  | ... |
+-----+-----+

如果我现在再次运行查询,它想要返回id 1并且应该创建此行:

| id  |other|
+-----+-----+
|  0  | ... |
|  1  | ... |
|  2  | ... |
|  4  | ... |
+-----+-----+

下次查询运行时,应返回id 356等。

运行这类查询的最有效方法是什么,因为我需要在一秒钟内经常执行它们(可以假设id是表的唯一目的)?是否可以通过一个查询获取下一个未使用的行?或者通过引入另一个跟踪未使用ID的表来更容易和更快?

如果速度明显加快,也可以重新使用表格中的任何一个洞,只要所有数字在某个时间重复使用。

奖金问题:我计划将SQLite用于这种存储信息,因为除了存储这些id之外我不需要数据库。是否有其他免费(如语音)服务器可以更快地完成

的工作?

4 个答案:

答案 0 :(得分:2)

我想我会在删除时创建一个触发器,并将old.id插入一个单独的表中。 然后,您可以从该表中选择min(id)以获得最低ID。

免责声明:我不知道您使用的是什么数据库引擎,所以我不知道您是否可以使用触发器。

答案 1 :(得分:2)

数据库不关心值是否是连续的,只是它们是唯一的。让你的id值顺序的愿望纯粹是装饰性的,如果你将这个价值暴露给用户 - 它不应该是你的主键,也不应该基于价值有任何参照完整性,因为客户可以如果需要,可以更改格式。

处理id值生成的最快和最安全的方法是依靠本机功能,它为您提供唯一的整数值(IE:SQLite的自动增量)。使用触发器只会增加开销,使用MAX(id)+1非常危险......

摘要

理想情况下,使用本机唯一整数生成器(SQLite / MySQL auto_increment,Oracle / PostgreSQL序列,SQL Server IDENTITY)作为主键。如果您想要一个始终是连续的值,请添加一个额外的列来存储该顺序值&必要时保持它。 MySQL / SQLite / SQL Server唯一整数生成只允许每列一个 - 序列更灵活。

答案 2 :(得分:2)

Dennis Haarbrink所说的那样;删除时触发,插入时触发另一个:

删除触发器将获取已删除的ID并将其插入到id池表中(只有一列id

插入前的触发器将检查是否提供了id值,否则它只是查询id池表(例如:SELECT MIN(id)FROM id_pool_table)并分配它(ig从id_pool_table中删除它)

答案 3 :(得分:1)

通常,您可以让数据库处理分配ID。是否有一个特殊的原因你需要id的顺序而不是唯一?相反,你可以给它们加上时间戳,并在显示它们时对它们进行编号吗?或者为顺序ID创建一个单独的列,并重新编号?

或者,您无法删除行本身,而是使用列中的标记将它们标记为已删除,然后通过查找编号最小的“已删除”行重新使用标记行的ID,并重新使用那个id。