当前位置: 首页 > 面试题库 >

Mysql upsert和自动增量导致差距

周麒
2023-03-14
问题内容

我有一个带有自动递增主键的MySql表,并且似乎所有各种upsert方法(INSERT IGNORE和ON DUPLICATE KEY
UPDATE)都具有自动递增字段递增甚至递增的功能。如果行已更新但未插入。这意味着将间隙引入表中,我发现这是不希望的。

因此,问题是:是否有任何方法可以在具有自动递增字段的表中向上插入记录, 而无需
自动递增该字段,如果实际上仅由向上插入来更新该行。在我看来,这是upsert的行为方式,但似乎并非如此。


问题答案:

此“问题”仅存在于中InnoDB

它是设计使然,旨在提高并发性:另一个线程可以使用,AUTO_INCREMENT而不必等待UPSERT操作结果。

文档

服务器启动后,对于第一次插入表t,将InnoDB执行以下语句的等效项:

SELECT MAX(ai_col) FROM t FOR UPDATE;

InnoDB 初始化但不增加值并将其存储以供以后的插入使用

访问自动增量计数器时,请InnoDB使用特殊的表级AUTO- INC锁,该锁保留在当前SQL语句的末尾,而不是事务的末尾。引入了特殊的锁定释放策略,以提高插入到包含AUTO_INCREMENT列的表中的并发性。但是,两个事务不能AUTO- INC同时在同一个表上拥有锁,如果AUTO-INC长时间持有该锁,则会对性能产生影响。对于这样的语句,例如INSERT INTO t1 ... SELECT ... FROM t2将一个表的所有行插入到另一个表,可能就是这种情况。

MyISAM不会表现出这种行为,因为它的AUTO_INCREMENT算法实现方式不同(由于其支持并发的能力有限DML)。



 类似资料:
  • 问题内容: 使用Postgres,我试图用SQL自动编号主键。但是,这给了我一个错误。 错误: 知道为什么吗? 问题答案: Postgres 10或更高版本 列(请参见下文)保持不变。但是考虑一个 专栏。Postgres10实现了此标准SQL功能。 手册中的基本语法和信息。 __用列 创建 表 将 列 添加 到现有表 表可能填充也可能不填充行。 同时使它成为PK(表还不能拥有PK): 有关的: 如

  • 这就是我所拥有的 当程序运行时,会出现一个添加新类别的屏幕,用户必须写入类别的名称和描述,但ID应该是自动的,并且应该在每次用户输入新类别时增加ID。我这样做并没有达到预期效果,它只增加了一次,但由于初始值保持在5,所以它总是6。

  • 问题内容: 我有一个带有自动递增主键的表。该表旨在存储数百万条记录,我现在不需要删除任何内容。问题是,当插入新行时,由于某些错误,自动增量键在自动增量ID中保留了一些间隙。例如,在5之后,下一个ID为8,而间隙为6和7 。结果是当我计算行数时,结果为28000,但最大id为58000。我没有删除任何内容。以及如何解决此问题。 PS我在插入记录时使用插入忽略,以便当我尝试在唯一列中插入重复项时不会出

  • 我有一个Ruby网络应用程序在赫洛库上运行,有一个Postgres数据库。我注意到自动递增的ID在Postgres数据库被Heroku“维护”时有一个间隙。 差距是一次性的,然后ID再次增加1。像这样: Heroku的维护发生在两个记录(和)之间,于创建。 我看到了一个解释,即失败的事务将导致下一次成功提交时跳过一个ID,但我在应用程序日志中看不到任何指示当时正在创建任何记录的内容。

  • 问题内容: 我有一个MySQL数据库,我试图找到一种仅导出其结构而没有自动递增值的方法。几乎可以完成这项工作,但是会保留auto_increment值。有没有不用PHPMyAdmin就能做到的方法(我知道它可以做到)? 问题答案: 你可以这样做 : 正如其他人所提到的,如果你想以正常工作,添加(用于 摹 这样叶形更换)参数: (如果您已经安装了GUI工具这仅适用:) 将是无用的,有时候会打破命令。

  • 问题内容: 我正在尝试在mysql数据库中创建一列,该列自动递增1但从0-Z开始然后滚动。 例如000、001、002,…,009、00A,00B,…,00Z,010,…,0ZZ,…,100。 我想让数据库通过自动递增字段创建列。 我的想法是: 为从0到36的每个字符创建一列,然后将行N(其中N是最低有效数字)自动递增1。然后在每列上添加触发器,以在第N列达到36时向N-1列添加1 。 创建一个包