2012-03-27 45 views
1

我有這個表:使用MySQL具有良好的原子唯一索引不提高錯誤

User 
    id INT PK 
    login VARCHAR UNIQUE 

我想知道的最佳方式來處理UNIQUE索引插入(例如:新用戶創建)

1)我可以簡單地插入,當一個「重複的條目提出了」我捕獲異常並處理它在應用

=>我不知道這是最好的解決方案,這樣做

2)I可以SELECT ... WHERE登錄= ...然後插入時沒有找到記錄,或者如果選擇發現一些

=>這不是原子,插入件可以選擇之間發生,INSERT

顯示錯誤

3)我就可以開始交易,SELECT FOR UPDATE,INSERT然後提交時,沒有發現任何記錄或ROLLBACK,如果用戶已經存在

=>這是行不通的,因爲MySQL不顯示錯誤鎖定沒有現有的線...所以它肯定會導致死鎖

那麼處理這個問題的最佳方法是什麼簡單的研究案例?

回答

0

你可以做一個

INSERT IGNORE ... 

MySQL manual INSERT

或者

REPLACE ... 

MySQL manual REPLACE

你也可以接受一些問題的答案。這將鼓勵更多的人來幫助你。

+0

我想我也可以使用ON DUPLICATE KEY,但是我真的很好奇,是否有解決方案來查找現有密鑰而不是嘗試插入並查看正在發生的事情。 – nemenems 2012-03-27 15:43:09

+0

@nemenems你爲什麼要這麼做?這只是您的服務器必須處理的額外查詢。另外在重複關鍵的事情。如果行已經存在,它基本上是一個UPDATE。所以只有當行中的其他列發生了變化時才這樣做。否則,讓自己多餘的操作你的服務器必須處理。別忘了,你也擺脫了原子問題。 – fancyPants 2012-03-27 21:10:32

+0

理解,但REPLACE或者只比ON DUPLICATE KEY差,因爲它將在兩行中重寫。我認爲抓住錯誤,而INSERTING似乎是唯一可以接受的解決方案 – nemenems 2012-03-28 13:56:17

0

我看到它的方式,你有兩個選擇:

1)使用Lock TablesSELECT然後Insert。鎖定桌子將確保您不會因競爭狀態而結束。 2)如果您擔心桌面鎖,您可以執行列出的第一個選項:INSERT或更好,INSERT IGNORE。如果您使用INSERT IGNORE,則重複鍵異常將作爲警告返回。

就我個人而言,我會嘗試表鎖,看看它是否工作。你的SELECT聲明應該快速運行,因爲它有一個唯一的密鑰,所以我不會擔心鎖會減慢你的速度。

+0

鎖定桌子肯定不是最好的解決方案,因爲桌子鎖真的很重。我的例子是一個研究案例。想象一下寫密集型數據庫的問題 – nemenems 2012-03-27 15:42:00