2012-01-24 21 views
1

我正在尋找模式,框架或最佳實踐來處理應用程序級數據同步的一般問題。從不可靠的數據源到SQL表的數據同步

讓我們舉一個只有1個表的例子來使它更容易。

  • 我有一個不可靠的產品目錄數據源。數據有時可能不可用或不完整或不一致。 (問題可能來自手動數據輸入錯誤,ETL故障...)

  • 我在Live系統使用的Mysql表中擁有活動副本。我們說一個網站。

我需要在更新mysql表與同步原始數據源時實施安全機制。以下是安全標準和解決方案,我的建議:

  • 避免刪除記錄時,他們暫時從數據源中消失=>使用「刪除」 boulean /日期欄或存檔/歷史記錄表。

  • 不一致的變化檢查=>配置每列的規則,如:應該永遠不會改變,只能增加,

  • 檢查其完整性的問題=>(標準問題,是沒有意義的討論方法)

  • 回滾上次同步的能力=>從歷史表中恢復?使用版本公司/日期列?

我在找的是最好的實踐和模式/工具來處理這樣的問題。如果不是你沒有指出解決方案,我會感謝任何關鍵字的建議,我會縮小哪些專業領域的探索。

回答

1

從Web分析提供程序導入數據時出現同樣的問題 - 它們遇到與您的目錄相同的問題。這就是我們所做的:

  • 每份進口/同步分配一個唯一的ID(AUTO_INCREMENT的Int64)
  • 每個表都有一個歷史表,它是與原始,但有一個附加列「superseded_id」這獲取導入的import-id,改變了行(刪除是改變),主鍵是(row_id,superseded_id)
  • 每個UPDATE在改變它之前將行復制到歷史表
  • 每個DELETE移動該行到歷史表

這使得回滾很簡單:

  • 找出壞進口
  • REPLACE INTO main_table SELECT <everything but superseded_id> FROM history table WHERE superseded_id=<bad import id>
  • DELETE FROM history_table WHERE superseded_id>=<bad import id>

對於數據庫,在性能是一個問題的IMPORT_ID,我們這樣做的輔助數據庫,然後將查找到的主表複製到生產數據庫到一個新表main_table_$id,其中$ id是最高導入ID,並且具有main_tabl對於SELECT * FROM main_table_$someid來說是一個簡單的視圖。現在通過將視圖重新定義爲SELECT * FROM main_table_$newid,我們可以自動切換桌面。

+0

完全符合這一做法回滾問題上達成一致。 –

+0

在某些記錄中,您是否有任何數據完整性問題? –

+1

這取決於你的意思是「數據的完整性」的東西 - 腐敗行(例如劣棗,負數,...)都在做更新之前過濾掉/插入(在某些情況下,我們將拒絕整個導入)。如果你的意思是違反了一個約束,這經常發生。然後我們拒絕完全導入。 –

-1

我不知道所有這一切的單一解決方案 - 可能是因爲每個項目是如此不同。然而,這裏是我在過去使用兩種技術:

嵌入的版本和有效性的理念融入到你的數據模型

這是一種方式來處理隨時間的變化,而不必訴諸歷史表;它確實使你的查詢複雜化,所以你應該謹慎使用它。

。例如,而不是一個產品表如下

PRODUCTS 
Product_ID primary key 
Price 
Description 
AvailableFlag 

在這種模式下,如果你想刪除一個產品,你執行"delete from product where product_id = ...";修改價格會"update products set price = 1 where product_id = ...."

隨着版本的模型,您有:

PRODUCTS 
product_ID primary key 
valid_from datetime 
valid_until datetime 
deleted_flag 
Price 
Description 
AvailableFlag 

在這種模式下,刪除一個產品需要你update products set valid_until = getdate() where product_id = xxx and valid_until is null,然後插入新行的「deleted_flag =真」。

更改價格的工作方式相同。

這意味着您可以針對「髒」數據運行查詢並將其插入此表中,而不用擔心刪除意外錯過導入的項目。它還可以讓您隨時查看記錄的演變情況,並輕鬆回滾。

使用累積值

如果你有喜歡的東西「的產品庫存編號」一賬樣的機制,它有助於創造交易修改金額,而不是採取電流量您數據饋送。

。例如,而不是你的產品表中的列amount_in_stock,有一個「product_stock_transaction」表:

product_stock_transactions 
product_id FK  transaction_date  transaction_quantity transaction_source 
1     1 Jan 2012    100     product_feed 
1     2 Jan 2012    -3     stock_adjust_feed 
1     3 Jan 2012    10     product_feed 

在1月2日,在股票數量爲97;在1月3日,107

這樣的設計可以讓你保持跟蹤調整以及它們的來源,並且更易於移動多個來源的數據時管理。

這兩種方法都可以創造大量的數據 - 這取決於進口的數量和數據量 - 並可能導致複雜的查詢來獲取相對簡單的數據集。

很難規劃性能問題前面 - 我已經看到了這兩個「歷史」和「分類帳」工作,大量的數據。但是,正如Eugen在下面的評論中所說的,如果您遇到了一個過大的分類帳,可能需要通過彙總當前級別並刪除(或歸檔)舊記錄來清理分類賬表。

+0

我很抱歉,但這種方法只適用於可靠的數據源。 我想說的是完全相反的。當我收到錯誤/損壞的數據時,我想盡量減少主數據庫傳染/腐敗的風險。尤其是分類帳機制會確保1個單一的不正確導入將永遠損壞總金額。 –

+0

抱歉-1這,但我已經看到,在開始工作的罰款太多臺賬類系統,但一個月後,嗆當庫存數量每個請求必要合計1,000,000行 –

+0

是的,有沒有辦法以避免首先將不良數據接收到數據庫中時損壞數據。但是,假設您首先有一些驗證數據的方法,則分類賬允許您追蹤明顯的異常 - 噢,我們在2012年1月1日剔除了整個股票記錄 - 並通過創建額外交易來更正。這至少給你內置的審計和歷史。 –