【问题标题】:MySql autoincrement column increases by 10 problemMySql自增列增加10的问题
【发布时间】:2009-11-11 16:46:25
【问题描述】:

我是一家为我的 MySql 数据库提供服务的托管公司的用户。由于它们的复制问题,自动增量值增加了 10,这似乎是一个常见问题。

我的问题是如何(安全地)模拟自动增量功能以使列具有连续的 ID?

我的想法是实现一些序列机制来解决我的问题,但我不知道这是否是最佳选择。我在网上找到了这样的代码片段:

DELIMITER ;;

DROP TABLE IF EXISTS `sequence`;;
CREATE TABLE `sequence` (
  `name` CHAR(16) NOT NULL,
  `value` BIGINT UNSIGNED NOT NULL,
  PRIMARY KEY  (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;;

DROP FUNCTION IF EXISTS `nextval`;
CREATE FUNCTION `nextval`(thename CHAR(16) CHARSET latin1)
RETURNS BIGINT UNSIGNED
MODIFIES SQL DATA
SQL SECURITY DEFINER
BEGIN
  INSERT INTO `sequence` 
    SET `name`=thename, 
        `value`=(@val:=@@auto_increment_offset)+@@auto_increment_increment
   ON DUPLICATE KEY 
    UPDATE `value`=(@val:=`value`)+@@auto_increment_increment;
  RETURN @val;
END ;;

DELIMITER ;

这似乎完全正确。我的第二个问题是这个解决方案是否是并发安全的?当然 INSERT 语句是,但是 ON DUPLICATE KEY 更新呢?

谢谢!

【问题讨论】:

  • 什么是“常见问题”?我以前从未听说过。
  • 一点更正:当然,在代码中,@@auto_increment_increment 将被一些常数替换——在我的例子中——替换为 1。这个解决方案是针对更一般的问题(如何实现序列) .

标签: mysql concurrency auto-increment sequences


【解决方案1】:

为什么你首先需要拥有它?

即使使用auto_increment_increment == 1,也不能保证表中的自动增量字段将具有连续值(如果行被删除,嗯?)。

使用自动增量,您只需由 db 引擎保证,该字段将是唯一的,没有别的,真的。

编辑:我想重申一下:在我看来,假设自动增量列的并发值之类的东西不是一个好主意,因为它会以后再咬你。

EDIT2:无论如何,这可以通过“插入”触发器“解决”

create trigger "sequence_b_ins" before insert on `sequence`
for each row
begin
    NEW.id = select max(id)+1 from `sequence`;
end

或类似的东西(抱歉,未经测试)

【讨论】:

  • 是的,你是对的。我不依赖于这个自动增量列的连续性,但是对于我的客户来说,让这个数字“几乎总是”连续是很有用的。
  • 嗯,在我的书中,“几乎总是”的意思基本上是“从不”。这并不总是正确的,但对于这种特殊情况,在我看来(当然)是正确的。
  • 感谢您的回复,考虑到您的话,我将重新考虑我的问题。
  • 对不起,如果我听起来太苛刻了,但我被自己的假设深深地咬了(尤其是在处理数据库时)。根据我的经验,如果可以保证某些事情(如“保证自动递增列中值的唯一性”),那么您可以围绕该保证构建逻辑。如果不能保证,那么最好的办法是完全忽略它,就好像它根本不存在(例如自增列中的值的连续性),而不是稍后在它转动时编写丑陋的hack你的假设在某种程度上是错误的。
  • 我对此深信不疑:“使用自动增量,您只需由 db 引擎保证,该字段将是唯一的,没有别的,真的。”。我在任何文件中都找不到提到 MySQL 可以同时控制生成自动增量键?你能告诉我为什么、在哪里或读过什么让你如此确定吗?
【解决方案2】:

另一种选择是使用存储过程进行插入,并让它从您的表中选择最大 id 或使用当前 id 保留另一个表并在使用 id 时更新。

【讨论】:

  • 对,这是我问题的第二部分。如果附加的代码是并发安全的,你能给我一个提示吗?这对我来说是个问题。
猜你喜欢
  • 1970-01-01
  • 2016-02-05
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多