1

我是一家为我的 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 更新呢?

谢谢!

4

2 回答 2

6

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

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

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

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

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

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

或类似的东西(对不起,未经测试)

于 2009-11-11T16:51:10.817 回答
0

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

于 2009-11-11T16:54:21.983 回答