2014-06-16 35 views
2

在MySQL中使用INSERT语句,很容易为主键输入AUTO_INCREMENT值。 UPDATE声明有这样的功能吗?自动递增更新查询ID或序列号

我想象什么是表像这样:

users 
userid username password email ... unique_updated_id 

用户每次更新的东西在users表中,unique_updated_id将包含MAX(unique_updated_id)+1。这将用于与数据库同步的系统中。它会记住它收到的最后一个unique_updated_id,并在从服务器获取更新时将其返回。

因此,当用户更改他们在数据库中的信息时,他们的unique_updated_id将更新为SELECT MAX(unique_updated_id)+1 FROM users。这将告诉同步过程只有在指定的unique_updated_id之后更新的信息才会被发送。

但是,我担心的是,由于一个可能的竞争条件下,我可能无法与

UPDATE users SET email='[email protected]',unique_updated_id=(SELECT MAX(unique_updated_id)+1 FROM users) WHERE userid=1;

达到预期的行为如何确保unique_updated_id将永远是独一无二的,将有连续编号的所有UPDATEINSERT查询?

我试图在PHP中实现这一点,所以执行由分号分隔的查询似乎不是解决方案,以确保两个查询可以连续执行而不需要在其间执行其他查询。

+0

好表可以有一个以上的主键。为什么你不能攻击auto_increment unique_updated_id –

+0

难道这只是在冲突的情况下返回错误?假设3个查询同时运行:QUERY1设置UUI = 10,QUERY2设置UUI = 10,QUERY3设置UUI = 10。当QUERY2和QUERY3执行时,这不会仅仅返回错误吗? –

+0

那么,服务器上的请求会排队,因此它会按收到的顺序处理它们并相应地更新它们。这就是为什么自己做这件事更可靠。尽管有更多SQL经验的人可以提供更好的洞察力。 –

回答

0

我不知道这样的方法是否存在,但可以通过创建另一个表来存储更新的元组来解决您的问题。并且当同步过程运行时让它删除同步的行。

+0

竞赛状况问题如何? –

+0

我是nat专家,但是,我不认为来自两张桌子的交易会引起竞争状况。在更新元组之后,您将更新后的元组的主键添加到了另一个表中。因此,有两个操作,可能会比较慢,但我不会看到竞争条件如何发生。 –

1

这是我会怎么使用MySQL Triggers做到这一点:

CREATE TABLE IF NOT EXISTS `test` (
    `testid` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `test` text NOT NULL, 
    `tuple` int(10) unsigned NOT NULL, 
    PRIMARY KEY (`testid`), 
    UNIQUE KEY `tuple` (`tuple`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ; 

INSERT INTO `test` (`testid`, `test`, `tuple`) VALUES 
(2, 'whateversadfa jdsfj', 5), 
(3, 'whaatasdfljsdflkj', 4); 

DROP TRIGGER IF EXISTS `PLUSONEA`; 
DELIMITER // 
CREATE TRIGGER `PLUSONEA` BEFORE INSERT ON `test` 
FOR EACH ROW SET NEW.tuple=(SELECT MAX(tuple)+1 FROM test) 
// 
DELIMITER ; 

DROP TRIGGER IF EXISTS `PLUSONEB`; 
DELIMITER // 
CREATE TRIGGER `PLUSONEB` BEFORE UPDATE ON `test` 
FOR EACH ROW SET NEW.tuple=(SELECT MAX(tuple)+1 FROM test) 
// 
DELIMITER ; 

要进行测试,这样做:

UPDATE test SET test='hello' WHERE testid=2; # this would update tuple of testid=2 to 6 
INSERT INTO test (test) VALUES ('hi'); # this would update tuple of testid=4 to 7 
UPDATE test SET test='world' WHERE testid=3; # this would update tuple of testid=3 to 8 
UPDATE test SET test='abc' WHERE testid=4; # this would update tuple of testid=4 to 9