2010-07-19 142 views
5

好了,故事是這樣的:當檢測數據已經改變

- 我有大量的文件(相當大,各地25GB)是在一個特定的格式,需要在數據存儲需要進口

- 這些文件連續數據,有時新的,有時同樣的數據

更新 - 我試圖找出我如何可以檢測,如果事情在改變特定線路的算法文件,以便最小化更新數據庫的時間。

- 它現在的工作方式是每次丟棄數據庫中的所有數據,然後重新導入它,但由於我需要時間戳來記錄項目發生更改,因此這種方法不再適用。

- 文件包含字符串和數字(​​標題,訂單,價格等)

我能想到的唯一的解決方案是:

- 從數據庫中的每一行計算哈希,它與文件中該行的散列進行比較,如果它們不同,則更新數據庫

- 保留2個文件副本,前一個和當前文件,並對其進行差異化(這可能比更新數據庫更快)並基於那些更新數據庫。

由於數據量非常巨大,所以我現在有些選擇了。從長遠來看,我將擺脫文件和數據將直接推入數據庫,但問題仍然存在。

任何意見,將不勝感激。

回答

1

而不是從數據庫按需計算每行的散列,爲什麼不存儲散列值呢?

然後,您可以只計算有問題的文件的哈希值,並將其與數據庫存儲的哈希值進行比較。

更新

另一個選項,來到我的腦海是存儲在數據庫中的最後修改日期/時間信息,然後與之比較的有問題的文件。如果信息不能有意或無意改變,這應該起作用。

+0

如果您要求計算整個文件的散列值,而不是整個數據庫的散列值,這對我無能爲力。但是如果你打算在數據庫中存儲每行的散列,是的,這是我想到的解決方案之一。我只是想知道這是否比通過比較元素和元素來判斷數據是否已經改變更快。 – hyperboreean 2010-07-19 07:37:04

+0

+1用於暗示存儲上次修改日期和時間 – 2010-07-19 07:47:22

+0

我沒有該文件中的任何時間戳。 – hyperboreean 2010-07-19 07:55:17

1

那麼無論你使用什麼樣的最壞情況,都會是O(n),這在n〜25GB的數據上並不那麼漂亮。

除非您可以修改寫入文件的進程。

由於您並未全部更新所有25GB,因此這是您節省週期的最大潛力。

1.不要寫隨機
你爲什麼不作出這樣的寫入數據只追加的過程?通過這種方式,您將獲得更多數據,但是您將擁有完整的歷史記錄,並且可以跟蹤已處理的數據(您已經放入數據存儲區的數據)。

2。如果您必須隨機寫入,請保留更改列表
或者,如果您確實必須執行隨機寫入,則可以保留更新行的列表。這個列表可以在#1中進行處理,並且您可以跟蹤您處理的更改。如果您想節省一些空間,您可以保留數據更改的塊列表(其中塊是您定義的單位)。

此外,您可以保留更改塊/線的校驗和/散列。然而,這可能不是很有趣 - 計算並不便宜,直接比較可能會更便宜(如果在寫入期間有空閒的CPU週期,它可能會爲您節省一些讀取時間,YMMV)。

說明(S)

  • 無論#1和#2是唯一有趣的,如果你能做出調整,以將數據寫入到磁盤
  • 過程中如果不能修改的過程寫入25GB數據,然後我看不出校驗和/哈希如何提供幫助 - 無論如何您都必須讀取所有數據才能計算哈希值(因爲您不知道發生了什麼變化),因此您可以在讀取和想出更新/添加的行列表(或直接更新/添加)
  • 使用diff算法可能不太理想,diff算法不僅會查找已更改的行,還會檢查給定特定格式選項的兩個文本文件之間的最小編輯距離。 (在diff中,這可以用-H或--minimal來控制,以更慢或更快的速度工作,即搜索確切的最小解或者使用啓發式算法,如果iirc該算法變爲O(n log n);這並不壞,但隨後爲O(n),如果通過線做直接比較線這是提供給你)
3

問題的定義仍然比較慢所理解

比方說,你的文件中包含

ID,Name,Age 
1,Jim,20 
2,Tim,30 
3,Kim,40 

正如你說行,可以添加/更新,因此文件將成爲

ID,Name,Age 
1,Jim,20 -- to be discarded 
2,Tim,35 -- to be updated 
3,Kim,40 -- to be discarded 
4,Zim,30 -- to be inserted 

現在的要求是通過插入/只更新來更新數據庫在兩個sql查詢中的兩個以上記錄或包含兩個sql語句的一個批處理查詢。

我想提出以下假設這裏

  • 不能修改現有流程來創建文件。
  • 您正在使用一些批處理[從文件讀取 - 在存儲器中處理 - 在DB中寫入] 以上載數據庫中的數據。

在內存映射中存儲Record [Name,Age]的哈希值與ID,其中ID是密鑰,值是哈希[如果需要可擴展性,請使用hazelcast]。

您的批處理框架加載數據[再次假設將一行文件當作一條記錄],需要根據內存中的標識檢查計算出的散列值。首次創建也可以使用批處理完成閱讀文件的框架。

If (ID present) 
--- compare hash 
---found same then discard it 
—found different create an update sql 
In case ID not present in in-memory hash,create an insert sql and insert the hashvalue 

您可能會使用spring-batch和hazelcast進行並行處理,塊處理和內存數據分區。

http://www.hazelcast.com/

http://static.springframework.org/spring-batch/

希望這有助於。

0

實際上這是一種需要備份軟件解決的問題,爲什麼不使用他們的一些標準解決方案? 最好的方法是鉤住WriteFile調用,以便每次更新都會收到回調。這對二進制記錄非常有效。

我無法理解的東西:這些文件實際上是不僅僅是附加的文本文件,而是更新的文件?這是非常無效的(連同保留兩份文件的想法,因爲它會使文件緩存工作更糟糕)。