2010-12-22 103 views
11

尋找一些關於Upsert(insert或if exists,then update)過程在數據庫編程中被認爲是不好的做法的見解。我在SQL服務器上工作,如果它有任何相關性。數據庫Upserts - 好還是壞的做法?

在我幾個月前工作過的地方,常駐數據庫大師以新編寫的db編碼標準(大部分我同意)表示,應該避免使用Upserts。

我無法真正看到這樣的邏輯原因,並認爲我的自我合理地意識到良好的編程習慣。我認爲它們對於直接數據管理非常有用,並有助於避免過多的存儲過程數量。

尋找一些見解/討論,這將幫助我得出這個結論。

謝謝。

更新響應於評論:

我指的是特定的上下文是在數據庫中的域實體數據表示的創建或更新。例如,說一個「Person」對象作爲數據庫中「Person」表的表示形式存在。我只需要一個用於創建新人員或更新現有人員的機制。在這裏,我可以選擇創建一個Upsert存儲過程,或者兩個單獨的存儲過程 - 一個用於更新,另一個用於插入。

任何人認爲的優點或缺點?

+0

從Oracle的角度來看,改用MERGE語句。 – DCookie 2010-12-22 15:37:14

+0

MERGE也存在於SQL Server(2005+我相信) – RPM1984 2011-01-12 11:16:29

回答

11

主要的問題是當意圖添加新記錄時覆蓋現有記錄,因爲隨着密鑰被複制而被選中。例如說一個登錄名。您會看到該登錄存在,因此您應該更新時應該反彈登錄名重複的錯誤。

第二個問題是復活刪除的記錄。說進程「A」查詢記錄,進程「B」刪除它,然後處理「A」提交更改。打算刪除的記錄現在回到數據庫中,而不是將例外傳回到它被刪除的「A」。

1

取決於您所談論的內容。數據?那麼,這是由數據處理過程決定的,還是?如果我需要插入或更新,那麼我需要這樣做。如果是關於模式對象,則類似。

+1

確實。很少有方法或實踐本身是不好的,這裏的環境和業務邏輯是非常重要的。 – Piskvor 2010-12-22 10:04:40

7

我喜歡有意編程。

要麼我創造了一些東西,在這種情況下,如果已經存在實體,我會希望插入失敗(重複)。或者,我正在更新我知道的東西,在這種情況下,我希望更新失敗(實際上並未發生)。

隨着upsert/merge這得到了一種模糊。我還是沒有成功?我部分成功了嗎?該行中的一些值是我的(從插入),其中一些是在那裏?

話雖如此,Upserts是有用的(這就是爲什麼他們開始實施),並禁止他們將是愚蠢的。這就像禁止公路一樣,因爲犯罪分子利用他們逃避警察。有無數的情況下,upserts是唯一合理的做事方式。任何在系統間同步數據的人都知道這一點。

0

兩個過程的第一個例子中的異議 - 第二個過程通過添加一個具有相同鍵的新複製過程「復活」刪除的記錄 - 僅在特定情況下有效,無論「upsert」過程是用相同的密鑰寫入記錄還是由兩個單獨的過程寫入插入的記錄,都會發生。

如果必須避免相同的密鑰,則在插入中使用自動遞增的身份密鑰。在不需要避免使用相同密鑰的情況下,必須實施良好的數據庫設計以避免產生「幻影聯結」。例如,在電信世界中,電話號碼經常被重複使用,並且是「唯一」密鑰。它們不能成爲主鍵,因爲2號人可能會「繼承」電話號碼,但可能不會「繼承」1號人的逾期未付帳單或通話記錄等。因此,自動遞增主鍵加服務日期或其他唯一標識符將用於任何連接邏輯中,以防止錯誤的數據鏈接。

相關問題