2013-03-01 53 views
0

我有一些麻煩提出了一個有效的解決方案來解決這個問題。也許我會讓它變得比需要更復雜。我有這樣一個表:mysql重新排列具有唯一約束的行

thing_id | user_id | order 
    1   1  0 
    2   1  1 
    3   1  2 

用戶可以與他們周圍事物的混亂,他們改變的東西1〜3的事情可能發生,事情3事情。在我的情況下,是不是用戶明確地改變了訂單。相反,他們正在修改他們的東西庫,他們可能會改變第1槽中的東西成爲第3槽中的東西,反之亦然。因此,如果用戶執行此操作,表應該是這樣的:

thing_id | user_id | order 
    3   1  0 
    2   1  1 
    1   1  2 

什麼複雜這是(thing_id,USER_ID)具有獨特的約束,這樣連續的更新,完全不是那麼回事。如果我嘗試UPDATE tbl SET thing_id=3 WHERE thing_id=1,則唯一約束被打破。

訂單欄純粹用於展示,以便製作按字母順序排列的清單。所以我想我可以使用PHP來檢查訂單並且像這樣弄清楚這些事情,但是這會引入與真正重要的東西無關的代碼。我想找到一個純粹/主要是SQL的解決方案。

同樣,如果我要在表中插入一個新行,我希望訂單值爲3.是否有一種有效的方法可以在SQL中執行此操作,而不必先執行SELECT MAX(order) WHERE user_id=1

+0

關於最後一個問題,您可以使用'SELECT MAX(ORDER)'作爲INSERT的一部分,作爲子查詢,至少不需要進行兩次調用,並且如果不使用事務,可能會添加爭用條件。 – ficuscr 2013-03-01 17:18:20

+0

好酷。我正在使用codeigniter框架,所以我可能不得不與這一點作鬥爭,所以它不認爲它是SQL注入哈哈。因此,查詢將簡單地爲'INSERT INTO tbl VALUES(4,1,(SELECT MAX(order)FROM tbl WHERE user_id = 1)',對吧? – 2013-03-01 17:20:43

+0

是的,事實上使用[transactions](http://dev.mysql .com/doc/refman/5.0/en/commit.html)可能會解決您的主要問題...閱讀此:http://stackoverflow.com/questions/5014700/in-mysql-can-i-defer-referential-完整性檢查直到提交...實際上不是交易,但推遲參照完整性 – ficuscr 2013-03-01 17:20:56

回答

0

我的評論似乎已經獲得了一些吸引力,所以我將其作爲答案張貼...爲了避免您的問題,請添加一個沒有約束的新列,並將其用於用戶所需的更新。

0

爲什麼不更新訂單而不是thingid?

UPDATE tbl 
    SET order = 2 
    WHERE thing_id=1; 

每一行代表一個「事物 - 用戶」對。 數據是您要使用的順序。你不想改變實體(「事物 - 用戶」)。你想改變數據。

順便說一句,您將不得不做一些額外的工作,以保持訂單中的唯一值。

如果你切換這個,並把唯一的約束放在user_id, order上,那麼更新thing_id是有意義的。