MySql自增列增加10问题
我是一家为我的 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更新呢?
谢谢!
I am a user of a some host company which serves my MySql database. Due to their replication problem, the autoincrement values increses by 10, which seems to be a common problem.
My question is how can I simulate (safely) autoincrement feature so that the column have an consecutive ID?
My idea was to implement some sequence mechanism to solve my problem, but I do not know if it is a best option. I had found such a code snipset over the web:
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 ;
which seems quite all correct. My second question is if this solution is concurrent-safe? Of course INSERT statement is, but what about ON DUPLICATE KEY update?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为什么你首先需要拥有它?
即使使用 auto_increment_increment == 1,也不能保证表中的自动增量字段将具有连续的值(如果行被删除怎么办,嗯?)。
使用自动增量,数据库引擎可以简单地保证该字段是唯一的,没有别的,真的。
编辑:我想重申:在我看来,假设自动增量列的并发值之类的事情不是是一个好主意,因为它会稍后会咬你。
来“解决” (抱歉,未测试)
EDIT2:无论如何,这可以通过“插入时”触发器或类似的东西
Why do you need to have it in the first place?
Even with
auto_increment_increment
== 1 you are not guaranteed, that the autoincrement field in the table will have consecutive values (what if the rows are deleted, hmm?).With autoincrement you are simply guaranteed by the db engine, that the field will be unique, nothing else, really.
EDIT: I want to reiterate: In my opinion, it is not a good idea to assume things like concurrent values of an autoincrement column, because it is going to bite you later.
EDIT2: Anyway, this can be "solved" by an "on insert" trigger
Or something along these lines (sorry, not tested)
另一种选择是使用存储过程进行插入,并让它从表中选择最大 id,或者保留另一个表,其中当前 id 正在使用,并在使用 id 时进行更新。
Another option would be to use a stored proc to do the insert and have it either select max id from your table or keep another table with the current id being used and update as id's are used.