2013-05-20 76 views
3

我有一個數據庫服務器,充當主SQL Server,包含一個表來保存所有數據。其他數據庫服務器進出(SQL Server的不同實例)。當他們聯機時,他們需要從主表下載數據(在給定的時間段內),然後他們將自己的附加數據生成到同一本地SQL Server數據庫表中,然後希望僅用新數據更新主服務器,使用C#程序,通過定期服務,每隔一段時間。多個額外的服務器可能同時生成數據,雖然它不會那麼多。從一個SQL Server到另一個表的高效更新表,結構

主表將始終在線。額外的非主數據庫表並不總是在線的,並且不應該是主副本,首先它將包含主數據的子集,然後它自己產生附加數據到本地表並更新主表往往與其更新。可能有相當數量的生成和/或下載的行數。所以需要一個高效的算法從額外的數據庫複製到主表。

什麼是最有效的方式在C#中傳輸這個? SqlBulkCopy看起來不像它會起作用,因爲我不能在主服務器中有重複的條目,並且如果由於某些條目已經存在而檢查約束條件,它會失敗。

+1

我不把它放在答案上,因爲它不在C#中。如果你真的關心性能,我認爲最有效的方法是通過數據庫鏡像。 – Renan

+0

一種可能性是做部分事務複製(http://stackoverflow.com/questions/495680/sql-server-transactional-replication-partial-data-only)。或者只是創建一個應用程序,完全爲你維護這個任務。 – mipe34

+0

我編輯了你的標題。請參閱:「[應該在其標題中包含」標籤「](http://meta.stackexchange.com/questions/19190/)」,其中的共識是「不,他們不應該」。 –

回答

0

以下是如何我會做到這一點:

  1. 其接收具有相同的結構作爲主表中的用戶定義的表的變量主表數據庫上創建的存儲過程。

應該做這樣的事情 -

INSERT INTO yourtable (SELECT * FROM tablevar) 

,或者你可以使用MERGE語句插入,或更新功能。

  1. 在代碼中,(一個窗口服務)負載的所有(或一部分)從secondery表中的數據並將其發送到存儲過程作爲表的變量。

  2. 您可以以1000的批量執行此操作,並且每次批量更新時都應將其標記在源表/源更新程序代碼中。

+0

您無法將公用表表達式作爲變量存儲在存儲過程中。你的意思是用戶定義的表變量? –

+0

是的,對不起。我正在更新我的答案。 –

1

你可以在DB或C#中做到這一點。在所有情況下,您都必須執行類似Using FULL JOINs to Compare Datasets的操作。你已經知道了。

最重要的是在交易中做到這一點。如果您有100k行,則將其分割爲每個事務1000行。或者嘗試確定每筆交易的行數最適合您。使用Dapper。這真的很快。

如果您擁有C#中的所有數據,請使用TVP將它傳遞給DB存儲過程。在存儲過程中使用MERGEUPDATE/DELETE/INSERT數據。

最後。在C#中使用Dictionary<Tkey, TValue>或與O(1)不同的訪問時間。

0

SQLBulkCopy是從C#程序中將數據插入表中的最快方法。我用它來在數據庫之間複製數據,迄今爲止沒有任何東西能夠在速度上勝出。這是一個很好的通用示例:Generic bulk copy

當您下載數據到本地數據庫服務器,我會用一個IsProcessed標誌在主服務器和主表的主鍵的跟蹤表。然後,您應該可以再次對主服務器進行刪除和更新。

0

你可以使用鏈接服務器嗎?如果是的話,它會使從主服務器到主服務器的數據複製變得更容易。

在將數據複製回主服務器時,我會在每個INSERT語句之前使用IF EXISTS來額外確保沒有重複項並將所有插入語句封裝到事務中,以便在發生錯誤時回退事務。

我也同意其他人對1000條左右的記錄進行分批處理,以便在出現問題時可以限制損壞。

相關問題