2008-09-19 68 views
10

表1: 一切都包括廚房水槽。日期格式錯誤(年份最後,因此無法在該列上排序),以VARCHAR形式存儲的數字,「街道」列中的完整地址,名字列中的名字和姓氏,姓氏列中的城市,地址不完整,行根據多年來發生變化的一些規則,將數據從一個字段移動到另一個字段,更新前面的行,重複記錄,不完整的記錄,垃圾記錄......你的名字......哦,當然不是TIMESTAMP或PRIMARY KEY欄目在眼前。最終的MySQL遺留數據庫噩夢

表2: 正常化的任何希望都在打開嬰兒時出現在窗外。 對於表1中的每個條目和行更新,我們都有一行。所以像明天沒有(800MB的價值)和像Phone1 Phone2 Phone3 Phone4這些列的複製品... Phone15(他們不叫電話,我用這個插圖)foriegn的關鍵是......好好猜測。根據表1中的行的數據類型,有三種候選者:

表3: 它可能會變得更糟。哦,是的。 「外鍵是虛線,點,數字和字母的VARCHAR列組合!如果沒有提供匹配(通常不會),那麼類似產品代碼的第二列應該是。與他們內部的數據無關,並且強制性的Phone1 Phone2 Phone3 Phone4 ... Phone15。從表1重複列,而不是TIMESTAMP或PRIMARY KEY列在望。

表4:被描述爲工作在任何時刻都有可能發生變化,這與其他人相比是相似的。

在接近1米的行上,這是一個大混亂。幸運的是,這不是我的大混亂。不幸的是,我不得不把它從一個複合記錄每個「客戶」。

最初,我設計了Table1的四步翻譯,添加了PRIMARY KEY並將所有日期轉換爲可排序格式。然後再執行幾步查詢來返回已過濾的數據,直到我有了Table1才能使用它從其他表中拉出來形成組合。經過幾個星期的工作,我用一些技巧將這個過程變成了一步。所以現在我可以將我的應用程序指向混亂,並提出一個很好的合成數據清理表。幸運的是,我只需要其中一個電話號碼用於我的目的,因此我的表正常化不是問題。

但是,這是真正的任務開始的地方,因爲每天有數百名員工以您不想要的方式添加/更新/刪除此數據庫,並且每天晚上我都必須檢索新的行。

由於任何表中的現有行都可以更改,並且由於沒有TIMESTAMP ON UPDATE列,所以我將不得不使用日誌來了解發生了什麼。當然,這假定有一個二進制日誌,但沒有!

引入這個概念就像鉛氣球一樣。我可能告訴他們,他們的孩子將不得不接受實驗手術。他們並不是高科技......如果你沒有收集到......

這種情況有點微妙,因爲他們有我的公司非常需要的一些有價值的信息。我被一家大公司的高級管理人員(你知道他們是怎麼做的)發送了「實現它」。

我想不出任何其他方式來處理夜間更新,而不是用另一個應用程序解析bin日誌文件,以找出他們在白天對數據庫做了什麼,然後相應地組合我的表。我真的只需要看看他們的桌子1就可以知道該怎麼辦我的桌子了。其他表格只提供一些字段來清除記錄。 (使用MASTER SLAVE不會有幫助,因爲我將有一個副本的混亂。)

另一種方法是爲其table1的每一行創建一個唯一的散列並構建一個散列表。然後,我每天晚上都會查看整個數據庫,看看哈希是否匹配。如果他們不這樣做,我會閱讀該記錄,並檢查它是否存在於我的數據庫中,如果存在,那麼我會在數據庫中更新它,如果它不是它的新記錄,我會插入它。這是醜陋的,並不快,但解析二進制日誌文件也不是很好。

我已經寫了這個,以幫助弄清楚問題。經常告訴別人有助於澄清問題,使解決方案更加明顯。在這種情況下,我只是頭痛得厲害!

您的想法將不勝感激。

回答

1

日誌文件(二進制日誌)是我的第一個想法。如果你知道他們做了什麼,你會不寒而慄。對於每一行,日誌中會有很多條目添加和更改。它只是巨大的! 現在我決定了哈希方法。隨着一些聰明的文件內存分頁,這是相當快的。

1

難道你不能使用現有的代碼訪問這個數據庫,並適應您的需求嗎?當然,代碼必須是可怕的,但它可能可能爲你處理數據庫結構,不是嗎?你可以專心於完成你的工作,而不是當時考古學家。

0

您可能可以使用maatkit的mk-table-sync工具來同步臨時數據庫(畢竟,您的數據庫只有非常小的數據庫)。這將「複製混亂」

然後,您可以編寫一些內容,在同步之後,執行各種查詢以生成一組更清晰的表格,然後您可以報告。

我想這可以在沒有性能問題的情況下每天完成。

這樣做可以避免影響原始數據庫。

我可以看到的唯一問題是如果某些表沒有主鍵。

+0

*我可以看到的唯一問題是,如果有些表沒有主鍵。* - 他們不會... 今天他們告訴我他們很少「更新/刪除記錄」。 ..無論這意味着什麼。在與另一位數據庫開發人員交談時,似乎最好的(唯一)方法是正確執行此操作,即對每一行進行散列並將散列存儲在表中。然後,每天晚上重新閱讀整個數據庫,爲每一行做一個散列,然後做一個簡單的比較。我只是無法看到它的方式。試圖破譯二進制日誌文件只會充滿危險。 – 2008-09-20 01:55:22

2

我不是MySQL的人,所以這是從左場出來。

但我認爲日誌文件可能是答案。謝謝你,你真的只需要知道日誌中的兩件事情。

您需要record/rowid,並且您需要該操作。

在大多數數據庫中,我假定MySQL,每行都有一個隱式列,比如rowid或recordid,或者其他。這是數據庫使用的內部行號。這是您的「免費」主鍵。

接下來,您需要操作。值得注意的是它是否是對行的插入,更新或刪除操作。

按時間順序合併所有這些信息,然後遍歷它。

對於每個插入/更新,您從原始數據庫中選擇行,然後在目標數據庫中插入/更新該行。如果是刪除,則刪除該行。

你不關心字段值,它們並不重要。做整行。

你希望不應該「解析」二進制日誌文件,MySQL已經必須有例程來做到這一點,你只需要找到並找出如何使用它們(甚至可能有一些方便的「轉儲日誌」你可以使用的工具)。

這可以讓您保持系統非常簡單,它應該僅取決於您在一天中的實際活動,而不是總數據庫大小。最後,你可以通過使它變得「更聰明」來優化它。例如,也許他們插入一行,然後更新它,然後刪除它。你會知道你可以完全忽略你的重播中的那一行。

顯然這需要一些奧術知識才能真正閱讀日誌文件,但其餘的應該是直截了當的。我想認爲日誌文件也是時間戳的,所以你可以知道在「從今天開始」的行上工作,或者你想要的任何日期範圍。