2009-06-16 63 views
1

這更像是一個正確性問題。假設我的數據庫中有一個包含主鍵列的表。在我的DAO代碼中,我有一個名爲insertRow(string key)的函數,如果表中不存在該鍵並且用鍵插入一個新行,它將返回true。否則,如果該行已經存在,則返回false。 insertRow首先檢查鍵的存在或者繼續執行插入操作並捕獲重複的鍵錯誤,是否更好/更糟糕?或者是在一個單一的選擇語句上存儲過於簡單的優化,甚至會擔心擔心?測試數據庫中重複密鑰的最佳方法

所以在須藤代碼:

boolean insertRow(String key){ 
    //potentially a select + insert 
    if(select count(*) from mytable where key = "somekey" == 0){ 
     insert into mytable values("somekey") 
     return true; 
    } 
    return false; 
} 

boolean insertRow(String key){ 
    try{ 
     //always just 1 insert 
     insert into mytable values("somekey") 
     return true; 
    } catch (DuplicateKeyException ex){} 
    return false; 
    } 
+0

如果有企業應用架構Martin Fowler的書模式我敢肯定,他給出了這樣一些很好的指導在他的「標識字段」的格局。當然,在沒有某種鎖定的情況下檢查最後一把鑰匙會很危險。 – RichardOD 2009-06-16 15:32:43

+0

看起來您可以在Google書籍上查看 - http://books.google.co.uk/books?id=FyWZt5DdvFkC&pg=PT243&lpg=PT243&dq=%22identity+field%22+Fowler+implementation&source=bl&ots=eEAuZzZtdA&sig=f3jc- rc3CsY2ZRQ9HzgkiMVzZdc&HL = EN&EI = nrs3SvvsJZTQjAfOm_GhDQ&SA = X&OI = book_result和CT =導致與resnum = 4#PPT243,M1 – RichardOD 2009-06-16 15:35:30

回答

3

嘗試插入,然後捕獲的錯誤。

否則,你可以仍然有兩個積極的SPID之間的併發問題(可以同時說,該系統在兩個網站的用戶),在這種情況下,你無論如何都要趕錯誤:

​​

您可以通過使用顯式事務或設置事務隔離級別來緩解這種情況,但除非您確信只有一個應用程序線程始終在數據庫上運行,否則它更容易使用第二種技術。

2

第二個,因爲第一個選項擊中分貝的兩倍,而第二個只有一次。

0

簡單的答案是你需要自己測試一下。我的直覺是,做一個小選擇來檢查存在性能會更好,但是你需要在量上驗證自己,看看哪個性能更好。

通常,我不喜歡將我的錯誤檢查完全留給異常引擎,無論我在做什麼。換句話說,如果我能檢查我所做的是否有效,而不是僅僅拋出異常,那通常就是我所做的。

我建議,但是,使用EXISTS查詢,而不是count(*)

if(exists (select 1 from mytable where key = "somekey")) 
    return false 
else 
    insert the row 

之所以這麼說(從一個抽象的,發動機中立的角度),我敢肯定,MySQL有一些關鍵字只有在主鍵不存在的情況下才可用於將行插入表中。這可能是你最好的選擇,假設你可以使用特定於MySQL的關鍵字。

另一種選擇是將邏輯完全放置在SQL語句中。

0

在mysql中另外兩個選項是使用

insert ignore into.... 

insert into .... on duplicate key update field=value 

包括on duplicate key update field=field

參見:http://dev.mysql.com/doc/refman/5.0/en/insert.html

編輯: 您可以測試affected_rows對於是否不是插入哈d效果與否。

+0

類似的語句也存在於Oracle和SQL Server 2008:合併。 – 2009-06-16 15:34:03

6

插入行,捕獲重複鍵錯誤。我個人的選擇

我認爲這可能會表現更好,這取決於拋出異常的成本與打兩次db的成本。

只有通過測試這兩種方案wilil你肯定知道

3

在我看來,這是使用異常(因爲重複是例外),一個優秀的情況下,除非你指望在那裏,大部分時間,已經是一排(即,你正在做「插入,但更新如果存在」的邏輯。)

如果代碼的目的是更新,那麼您應該使用select或INSERT ... ON DUPLICATE KEY UPDATE子句(如果您的數據庫引擎支持)。或者,爲您處理此邏輯的存儲過程。

0

現在,我已經找到Martin Fowler的書在網上,一個體面的方式來做到這一點是有key table - 參閱第222獲取更多信息。

相關問題