Mysql 自动递增主计数,在计数时留下间隙
我有一张带有自动递增主键的表。这个表是用来存储数百万条记录的,我现在不需要删除任何内容。问题是,当插入新行时,由于某些错误,自动增量键会在自动增量ID中留下一些间隙。。例如,在5之后,下一个id是8,留下6和7的间隙。结果是当我数行时,结果是28000,但最大id是58000。原因可能是什么?我没有删除任何内容。我怎样才能解决这个问题Mysql 自动递增主计数,在计数时留下间隙,mysql,primary-key,Mysql,Primary Key,我有一张带有自动递增主键的表。这个表是用来存储数百万条记录的,我现在不需要删除任何内容。问题是,当插入新行时,由于某些错误,自动增量键会在自动增量ID中留下一些间隙。。例如,在5之后,下一个id是8,留下6和7的间隙。结果是当我数行时,结果是28000,但最大id是58000。原因可能是什么?我没有删除任何内容。我怎样才能解决这个问题 另外,我在插入记录时使用insert ignore,这样当我尝试在“唯一”列中插入重复条目时,它就不会出错。这是出于设计,而且总是会发生的 为什么? 让我们看两个
另外,我在插入记录时使用insert ignore,这样当我尝试在“唯一”列中插入重复条目时,它就不会出错。这是出于设计,而且总是会发生的 为什么? 让我们看两个正在进行插入的重叠事务
- 事务1执行插入,获取值(比如42),做更多的工作
- 事务2执行插入,获取值43,执行更多工作
- 事务1失败。向后滚动。42未使用
- 事务2以43完成
另请参见(SQL Server,但适用相同的原则)这是MySQL存储引擎InnoDB中的一个问题 这真的不是问题,因为当您检查“”上的文档时,它基本上说InnoDB使用一个特殊的表在启动时自动递增 它使用的查询类似于
SELECT MAX(ai_col) FROM t FOR UPDATE;
这在不影响数据的情况下提高了并发性
要避免使用MyISAM而不是InnoDB作为存储引擎,您可以创建一个触发器来处理自动增量,如下所示:
CREATE DEFINER=`root`@`localhost` TRIGGER `mytable_before_insert` BEFORE INSERT ON `mytable` FOR EACH ROW
BEGIN
SET NEW.id = (SELECT IFNULL(MAX(id), 0) + 1 FROM mytable);;
END
也许(我还没有测试过)解决方案是将innodb\u autoinc\u lock\u模式设置为0
。
根据这一点,可能会使事情变得慢一些(如果您在一个查询中执行多行插入),但应该消除间隙。您可以尝试插入,如:
insert ignore into table select (select max(id)+1 from table), "value1", "value2" ;
这将尝试- 插入最后未使用id的新数据(非自动增量)
- 如果在唯一字段中找到重复条目,请忽略它
- 否则通常插入新数据
(但如果发现重复条目,此方法不支持更新字段)