2012-03-23 137 views
1

我想從MySQL表中提取增量更新。問題表中有一個自動遞增的ID字段,以及每次更改(INSERT/UPDATE)時更新爲當前時間戳的updated_at字段。記錄不會從這張表中刪除。從MySQL表中提取增量更新

我想從腳本的最後一次運行以來,從此表中提取所有新創建和更新的記錄。我知道最後一次運行的最高updated_at值。因此,提取記錄的主要查詢將如下所示:

SELECT * FROM table WHERE updated_at >= :last_seen_updated_at 

實現此目的的最佳方法是什麼?我必須100%確定將提取所有新的和更新的記錄。一些問題和顧慮:其中一些

  • 多個記錄可以在同一秒內被更新,其中一些可能已經被列入前提取來看,並非如此。 (例如:提取器運行在第二秒的前半部分,而記錄可能會在第二秒的後半部分更新。
  • 我應該使用一個大的SELECT查詢還是應該使用多個查詢來提取批量的X記錄?請注意,要提取的數據量可能很大,如果我使用批處理,則記錄可能會在不同查詢之間更新。
  • 最好不要提取重複記錄,但這不是一個大問題。有意義的最後一次露面更新之前開始的時間X量,「以防萬一」?(如updated_at >= :last_seen_updated_at - INTERVAL 1 MINUTE
  • 我應該?重複讀運行什麼隔離模式下,這些疑問?SERIALIZABLE?
  • MySQL的d atabase是一個複製的slave,它有時會滯後master DB。這會對包含或不包含的行產生任何影響嗎?

回答

1

這不是一個完整的答案,但它是一種避免重複的可靠方法。首先,當你運行更新腳本時,不要在當前秒運行它。在超過5秒的時間內運行它。那樣的話,你知道如果你有一個給定秒的記錄,那麼你就有第二個記錄。完成之後,您應該能夠使用updated_at > :last_seen_updated_at並避免更新週期之間的重複。

此時,您應該可以隨意抽取批量或一個大型查詢。至少如你所描述的那樣,你將要提取的數據在很大程度上是靜態的 - 當你走的時候,可能會有其他條目被添加到表中,但是它們都將在任何你的任意最近截斷的第二個是,所以不會成爲你的查詢的一部分。

對於從/主問題,這可能有點擔心,但只要主人先更新舊記錄,它仍然很容易解決。在設置更新截止日期時,請在本地記錄中查找最近的時間間隔並減去一秒鐘。

仍然存在您關注的時間段中添加或更新的條目在解壓時可能會再次更新的問題。嚴格防止這種情況的唯一方法是在解壓縮時斷開與服務器的連接並緩存更改,但在完成相對少量的添加和修改後,可以通過返回並再次運行腳本來顯着降低事件發生率這是在您提取較大的羣組時發生的。你可以多次重複這一點,因爲你覺得偏執狂保證。或者,您可以計算預提取,提取和計算提取的數量的行數。如果有任何區別,您可以再次運行該過程,直到您獲得前後的相同編號。