10

表 1:包括厨房水槽在内的所有物品。日期格式错误(最后一年,因此您无法对该列进行排序),数字存储为 VARCHAR,“街道”列中的完整地址,名字列中的名字和姓氏,姓氏列中的城市,不完整的地址,行根据多年来发生变化的一组规则,重复记录,不完整记录,垃圾记录...通过将数据从一个字段移动到另一个字段来更新前面的行...您可以命名它...哦,当然不是 TIMESTAMP 或 PRIMARY KEY 列在眼前。

表 2:打开这个婴儿后,任何正常化的希望都破灭了。我们在表一中的每个条目和行的更新都有一行。所以重复像没有明天(价值800MB)和像Phone1 Phone2 Phone3 Phone4 ... Phone15这样的列(它们不被称为电话。我用这个来说明)外键是......好吧猜猜。根据表 1 中的行中的数据类型,有 3 个候选项

表 3:它会变得更糟吗?哦是的。“外键是破折号、点、数字和字母的 VARCHAR 列组合!如果不提供匹配项(通常不提供匹配项),则应使用第二列类似的产品代码。具有名称的列与其中的数据没有相关性,以及强制性的 Phone1 Phone2 Phone3 Phone4...Phone15。有从 Table1 复制的列,而不是 TIMESTAMP 或 PRIMARY KEY 列。

表 4:被描述为正在进行中的工作,随时可能发生变化。它与其他人本质上是相似的。

在接近 1m 行时,这是一个大混乱。幸运的是,这不是我的大麻烦。不幸的是,我必须从中提取每个“客户”的复合记录。

最初,我设计了 Table1 的四步翻译,添加了 PRIMARY KEY 并将所有日期转换为可排序格式。然后再执行几个查询步骤,这些查询返回过滤后的数据,直到我有 Table1 到可以使用它从其他表中提取以形成合成的地​​方。经过数周的工作,我使用一些技巧将其归结为一个步骤。所以现在我可以将我的应用程序指向混乱并拉出一个漂亮干净的复合数据表。幸运的是,我只需要其中一个电话号码就可以了,因此标准化我的桌子不是问题。

然而,这是真正的任务开始的地方,因为每天都有数百名员工以您不想想象的方式添加/更新/删除这个数据库,而且每天晚上我都必须检索新行。

由于可以更改任何表中的现有行,并且由于没有 TIMESTAMP ON UPDATE 列,因此我将不得不求助于日志来了解发生了什么。当然,这假设有一个二进制日志,但实际上没有!

引入这个概念就像铅气球一样下降。我还不如告诉他们,他们的孩子将不得不接受实验性手术。它们并不完全是高科技……万一你没有聚集……

情况有点微妙,因为他们有一些我公司急需的有价值的信息。我被一家大公司的高级管理层(你知道他们是怎么做的)派来“让它发生”。

除了用另一个应用程序解析 bin 日志文件,我想不出任何其他方法来处理夜间更新,以弄清楚他们在白天对该数据库做了什么,然后相应地组合我的表。我真的只需要看看他们的 table1 就可以知道如何处理我的桌子。其他表只提供字段来清除记录。(使用 MASTER SLAVE 将无济于事,因为我会复制一份混乱。)

另一种方法是为其 table1 的每一行创建一个唯一的哈希并构建一个哈希表。然后我会每晚检查整个数据库以查看哈希是否匹配。如果他们不这样做,那么我将读取该记录并检查它是否存在于我的数据库中,如果存在,那么我将在我的数据库中更新它,如果它不存在,那么它是一条新记录,我将插入它。这很难看而且速度不快,但是解析二进制日志文件也不是很漂亮。

我写这篇文章是为了帮助弄清楚这个问题。经常将其告诉其他人有助于澄清问题,从而使解决方案更加明显。在这种情况下,我只是更头疼!

您的想法将不胜感激。

4

4 回答 4

2

我不是 MySQL 人,所以这是从左领域出来的。

但我认为日志文件可能是答案。

谢天谢地,你真的只需要从日志中知道两件事。

你需要记录/rowid,你需要操作。

在大多数数据库中,我假设是 MySQL,每一行都有一个隐式列,比如 rowid 或 recordid 或其他。它是数据库使用的内部行号。这是您的“免费”主键。

接下来,您需要操作。尤其是对行的插入、更新或删除操作。

您按时间顺序整合所有这些信息,然后遍历它。

对于每个插入/更新,您从原始数据库中选择行,然后在目标数据库中插入/更新该行。如果是删除,则删除该行。

您不关心字段值,它们并不重要。做整排。

希望您不必“解析”二进制日志文件,MySQL 已经必须有例程来执行此操作,您只需要找到并弄清楚如何使用它们(甚至可能有一些方便的“转储日志”实用程序可以使用) )。

这使您可以使系统保持非常简单,并且它应该只取决于您白天的实际活动,而不是总数据库大小。最后,您可以稍后通过使其“更智能”来优化它。例如,也许他们插入一行,然后更新它,然后删除它。您会知道您可以在回放中完全忽略该行。

显然,这需要一些神秘的知识才能真正读取日志文件,但其余的应该很简单。我想认为日志文件也带有时间戳,因此您可以知道“从今天开始”处理行,或者您想要的任何日期范围。

于 2008-09-20T04:07:02.240 回答
1

您不能使用访问该数据库的现有代码并使其适应您的需要吗?当然,代码一定很糟糕,但它可能会为你处理数据库结构,不是吗?你可以希望专注于完成你的工作,而不是扮演考古学家。

于 2008-09-19T12:11:34.830 回答
1

日志文件(二进制日志)也是我的第一个想法。如果你知道他们是怎么做的,你会不寒而栗。随着片段的添加和更改,日志中的每一行都有许多条目。它只是巨大的!现在我选择了 Hash 方法。通过一些巧妙的文件内存分页,这是非常快的。

于 2008-11-22T16:10:47.647 回答
0

您也许可以使用 maatkit 的 mk-table-sync 工具来同步暂存数据库(毕竟您的数据库非常小)。这将“复制混乱”

然后,您可以编写一些东西,在同步之后执行各种查询以生成一组更健全的表,然后您可以报告这些表。

我想这可以在没有性能问题的情况下每天完成。

在不同的服务器上完成这一切将避免影响原始数据库。

我能看到的唯一问题是某些表是否没有主键。

于 2008-09-19T12:25:49.773 回答