2012-05-23 32 views
2

我正在基於輸入數據流定期創建數據庫記錄的系統上工作。偶爾會有一些輸入提供證據表明兩個獨立創建的記錄應該合併爲一個。我正在尋找關於如何在數據庫中實現合併的建議。合併數據庫記錄的推薦技術

主表(這只是此時的設計)包含由唯一標識(稱爲主標識,由數據庫指定的主標識,我的系統中的MySQL)以及一些數據字段組成的記錄。還有一些其他表使用主ID將其記錄鏈接到主表中的記錄。

MainTable: 
int mainID 
blob data 
... 

OtherTable: 
int otherID 
int mainID 
blob otherData 
... 

現在,如果每個記錄從未被共享到任何外部過程或系統,它是直接以某種方式混合從一個記錄的數據字段到另一個,並刪除了一個記錄。將其他表中的主要ID字段更新爲我們保留的主要ID值也很簡單(如果單調乏味和/或效率低下)。

當每個記錄的ID在系統外共享時,情況就會變得複雜。在這種情況下,我認爲對那些被刪除的ID進行查詢簡直失敗是不合理的,儘管我可以說服其他人。

我正在考慮的一個想法是引入一個包含兩個關鍵字段的合併表:原始主要ID和當前主要ID。它的目的是將一個主要ID別名到另一個。在創建每個主表記錄時,我們向合併表中添加一條記錄,將新創建的主表記錄的主ID映射到自身。如果發生合併,我們只需簡單地更新合併表中當前的主標識字段,以獲取正在合併的主記錄的原始主標識。然後,對於基於主ID的每個查詢,我們通過合併表映射該ID以找到我們應該真正使用的有效主ID。

MergeTable: 
int mergeID 
int originalMainID 
int currentMainID 

這是一個很好的技術嗎?映射可以在SQL查詢中無縫完成嗎?是否有我應該考慮的標準或更好的技術?

在做這個話題的研究中,我發現了這個驚人的例子。 This question已經接近,但合併方案與我的不同,或者對我而言似乎如此。我對數據庫有一些瞭解,但絕不是專家,所以我可能不知道搜索的正確術語。

回答

2

我喜歡你的設計理念,但考慮在合併表中只存儲替換的記錄,而不是全部。這降低了存儲和提高速度,考慮以下查詢:

SELECT * 
    FROM MainTable 
    WHERE mainID = 1 
UNION ALL 
SELECT MainTable.* 
    FROM MergeTable 
    INNER JOIN MainTable 
    ON MainTable.mainID = MergeTable.currentMainID 
    WHERE MergeTable.originalMainID = 1 
LIMIT 1 

的想法是,在大多數情況下,第一個查詢將成功並返回結果,並因爲限制是符合MySQL會放棄第二個查詢。如果第一個查詢不返回任何結果,那麼它將繼續執行第二個查詢並在合併表上執行連接以查看它是否已合併。

據MySQL中,有關LIMIT:

只要MySQL已經發送所需的行數到客戶端, 除非你正在使用SQL_CALC_FOUND_ROWS它中止查詢。

如果合併記錄是例外,而不是規則,那麼這將節省許多許多聯接。

如果UNION查詢太嚇人,你也可以用兩個查詢來做到這一點。您可以簡單地檢查記錄是否存在,如果不存在,則檢查合併表。

+0

好的答案,馬庫斯。 +1。我希望得到社區的更多回應。你會不會考慮爲什麼我的問題沒有什麼興趣?難度太大或太少(如果是的話,爲什麼?)?謝謝。 –

+0

@RandallCook,我在其中一個特定的系統中一直執行像這樣的查詢。我運行一個查詢,如果我沒有得到任何結果,我將針對不同的表運行另一個查詢。我認爲這不太常見。這裏的問題是碰撞或錯過。有時候一個很長的問題會讓人們失望,有時候這只是一個糟糕的時間。 –

+0

@RandallCook,我忘了提及,你總是可以不接受我的答案,併發布更好的答案賞金。 –