2009-11-11 103 views
1

我是某个主机公司的用户,它服务于我的MySql数据库。由于其复制问题,自动增量值增加10,这似乎是一个常见问题。MySql自动增量列增加10个问题

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

我的想法是实现一些顺序机制来解决我的问题,但我不知道它是否是一个最佳选择。我在网上发现了这样的代码snipset:

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:[email protected]@auto_increment_offset)[email protected]@auto_increment_increment 
    ON DUPLICATE KEY 
    UPDATE `value`=(@val:=`value`)[email protected]@auto_increment_increment; 
    RETURN @val; 
END ;; 

DELIMITER ; 

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

谢谢!

+0

什么是“常见问题”?我从来没有听说过这个。 – longneck 2009-11-11 17:08:24

+0

纠正:当然,在代码中,@@ auto_increment_increment将被一些常量(在我的情况下)替换为1.此解决方案用于更一般的问题(如何实现序列)。 – vnx 2009-11-11 17:18:28

回答

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 

还是什么沿着这些线路(对不起,未测试)

+0

是的,你说得对。我不依赖于这个自动增量列的连贯性,但是对于我的客户来说,让这个数字“几乎总是”连续是有用的。 – vnx 2009-11-11 16:54:56

+1

那么,在我的书中,“几乎总是”的意思,基本上是“从不”。这并非总是如此,但对于这种特殊情况,我认为(当然)是这样。 – shylent 2009-11-11 16:57:49

+0

感谢您的回复,我会考虑您的话,重新考虑我的问题。 – vnx 2009-11-11 17:25:51

0

另一种选择是使用“解决”存储过程执行插入操作,并使其从您的表中选择最大ID或使用正在使用的当前ID保留另一个表,并使用id进行更新。

+0

对,这是我的问题的第二部分。如果附加的代码是并发安全的,你能给我一个提示吗?这对我来说是一个问题。 – vnx 2009-11-11 16:56:34