身份栏重新播种:什么时候需要?

Cry*_*t32 12 mysql auto-increment identity

在大学的最后一节课(我是学生)中,讲师要求我们开发一个数据库(如果重要的话,MySQL 服务器)和使用该数据库作为数据源的小型客户端应用程序。

要求之一是标识列(即每个表中的 PK)必须是连续的,因为这是一个很好的做法(按照讲师的话)。也就是说,当表行被删除时,它的 PK 必须在后续插入中重用。我对 RDBMS、PK 和身份列有一般的了解。据我了解,该标识列只是一种让 DB 在插入行时自动生成 PK 的方法,仅此而已。并且标识列值不得以任何方式与行属性相关(只要它不是自然键)。

这个要求(严格顺序标识列)对我来说是可疑的。我试图问讲师如果身份不是顺序的(由删除引起的差距)有什么问题,但得到了非常抽象的答案,比如“这对用户来说很方便,对维护数据库的数据库管理员很有用”。没有具体的例子。“方便用户”的说法听起来很傻,因为它在业务领域没有任何意义。

因此,我很好奇这些原因是否真实?我只能想到一种需要重新设置身份列的情况——当身份空间耗尽时。但是当标识列类型选择不正确时,这是更多的设计问题,说简单int而不是bigintuniqueidentifier当表包含十亿行。假设,一个标识列是一个聚集索引:标识列中的间隙会影响索引性能吗?也许我不知道在每次删除后自动标识列重新播种的其他现实原因?

提前致谢!

Ric*_*mes 19

也就是说,当表行被删除时,它的 PK 必须在后续插入中重用。

你的讲师来自哪个宇宙??

这是非常低效的。如果您尝试这样做,您的绩效前景将降低 10 倍。

如果出于审计原因需要无缝数字,请明确构建它们,而不是直接从数据库工具中构建。并且永远不要删除行,而是将它们标记为“已删除”。这将增加查询的混乱程度,因为它们将不得不忽略这些行。

在 MySQL 中,InnoDB 要求PRIMARY KEY每个表都存在唯一的。但这就是要求的范围。键甚至可以是字符串。

间隙对用户和 DBA 来说是一种便利而不是一种不便。

我可以想到一种无间隙会很方便的情况——一次分块成 100 行。但是有一个简单的解决方法,使用LIMIT 100,1.

差距对性能的影响为零。这包括非数字索引。和非唯一索引。和复合索引。

当然,您可能会用完 id。我想在使用 MySQL 的近 20 年里,我已经看到它发生了两次。我还不如担心被小行星撞击。我的那些让我在夜间保持清醒的事情清单上的东西很少。

间隙从(至少)发生: INSERT IGNOREIODKUREPLACEDELETEROLLBACK(显式的,或由于崩溃),多主复制(包括加莱拉和组复制)。你真的想为这些想出解决方法吗?!

请随时让我们对讲师所说的任何其他可疑内容进行理智检查。


jmo*_*eno 9

重用标识值,通常应该被劝阻。要么完全在内部使用该值,在这种情况下它的实际价值是无关紧要的,要么也用于外部,在这种情况下,重复使用该值很可能会导致错误识别。

以发票或采购订单编号为例,它们很容易来自标识列并暴露在外部,但您绝不会希望正是因为这个原因而重复使用它们。两者都是指您不想混淆的特定交易。

当公司合并或被收购时,解决这些问题可能是一个很大的麻烦。故意制造这样的问题?不明智。


dan*_*ack 6

PK id 值的重用有问题,一般应该避免。

首先,auto_increment 列的实现不提供无间隙的保证。如果回滚自动增量列上的插入,确实会出现间隙。

其次,间隙 ID 可能指尚未删除的现有数据(由于缺少 FK 约束)。如果它们转换为在系统外传达的成员编号,则会带来潜在的业务身份风险。

第三,bigint unsigned即使插入率非常大,也不会在很长一段时间内用完 ID。

差距的最大痛苦是遇到坚持审计缺陷的审计师。对于 DBA,他们知道存在差距以及原因。