2015-07-11 92 views
2

我在寫一個將用戶插入MYSQL表的函數。最初我寫了這樣一個功能,它首先會用SELECT聲明檢查具有相同用戶名的現有用戶。但是,我的表指定用戶名列是唯一的,所以我意識到在檢查用戶是否存在後,數據庫會再次檢查。通過嘗試插入來測試MYSQL中的重複記錄

只是嘗試插入該行並查看是否有錯誤或者是否明確地檢查了SELECT語句會更好嗎?

回答

1

不知道很多關於你的環境,編程語言,負載,性能等我要說堅持什麼讓你感覺良好!

這兩種情況都沒有錯;)

想想並編寫常見的場景。我的意思是,你是說這是爲新的註冊用戶。那麼,你認爲用戶會多頻繁地嘗試重新註冊?對!我會在這種情況下嘗試插入第一種情況。

您是否認爲您的插入失敗率很高,那麼首先進行選擇檢查是很好的。

+0

如果我預期失敗率很高,難道我不想避免額外支票來擺脫開銷嗎? – bytesized

+1

在這種情況下(比db引擎中的錯誤處理成本更高),對高速插入失敗進行選擇檢查的代價將更容易。所有都可以測量,你可以設置一個負載並運行這兩種方案來查看你的數據庫引擎行爲。如上所述,如果您正在尋找性能增益的常見場景代碼 – MrSimpleMind

+0

有趣。我沒有意識到在數據庫引擎中的錯誤處理會有很大的開銷(我猜這是有道理的)。但是,最終,我打算所有的驗證都通過客戶端完成(在這種情況下通過AJAX)。因此,我預計失敗率很低,所以我認爲我會先插入,然後再提問。 – bytesized

0

如果這是基於Web的應用程序,我會通過Ajax請求執行檢查以獲得更好的最終用戶體驗。

+0

我打算這樣做,但問題是關於在後端創建用戶功能 – bytesized

+0

如果您已驗證您的dB,用戶名不存在允許用戶提交表單。否則,請不要提交表單,以便每個用戶名只提供一次dB檢查。我不認爲有必要採取另一項安全措施。 –

0

您正在尋找INSERT IGNORE。在重複主鍵插入時,它將生成警告而不是錯誤,並且您不需要運行SELECT來檢查重複項。

https://dev.mysql.com/doc/refman/5.5/en/insert.html

+0

閱讀了一下你鏈接到的文檔後,這聽起來就像我想要的相反。這不妨礙我想用來檢測重複的用戶名的確切錯誤嗎?看起來這樣會導致服務器顯示「全部完成,您的用戶名現在存在」,實際上什麼都沒有完成。 – bytesized

1

這取決於你如何做檢查。

當你在insert之前做select時,你有一個競爭條件。另一個用戶/線程可以在,selectinsert之間插入重複記錄。這就是爲什麼你想要在insert做檢查。

通常,在insert中進行檢查就足夠了。如果您想避免該錯誤,請使用on duplicate key update。這比insert ignore更可取,因爲on duplicate key update只能處理有關密鑰重複的錯誤。 Insert ignore忽略所有錯誤。

我會說,除非你有某些特殊的原因,否則不要打擾手邊的檢查。原因如下:

  • 想要最小化表被鎖定的時間,因此您希望避免提出問題,例如「發生重複時表鎖定多長時間?」。
  • auto_increment列中的故意漏洞會打擾您(實際上,我不確定這是MySQL的問題)。
  • 您插入多行,並希望能夠檢測多個重複報告給用戶。