2014-06-16 64 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