我需要制作一个我从未使用过的庞大数据库的通用模式。 问题是我不知道如何/在哪里可以开始这样做,因为不考虑大小,我不知道每个表是什么。我可以猜到一些,但是其中有一些通用名称字段对我来说没有任何意义。
你有什么建议吗?我能做什么? 没有关于数据库的文档,创建者也无法帮助我,因为他们现在在另一家公司。
非常感谢您的进步。
答案 0 :(得分:2)
这并不容易。
首先收集现有的任何文档,备注等。此外,彻底了解所存储的数据类型和应用程序也是非常有帮助的。记录您的发现,并构建应该之前构建的文档。
如果您的数据库包含声明的外键,您可以从那里开始,至少可以降低表之间的关系。请记住,这可能是不完整的。正如@John Watson指出的那样,如果宣布关系,那么有一些工具可以帮助你。
检查存储的功能和程序,包括触发器。虽然这些在MySQL数据库中有点不常见。特别是触发器通常会产生线索(“表X的每次更新都会向表Y插入一个新行” - >“表Y可能是日志或审计表”)。
有些表格显然是显而易见的,如果您知道与它们相关的内容,您可以开始弄清楚那些相关的表格。
希望您可以访问应用程序代码,您可以通过grep和阅读来查找线索。访问可以反复销毁的测试环境也是有用的(“如果我在应用程序中更改此内容会发生什么,数据库会发生什么变化?”;“如果我加扰这些值会发生什么?”等等)。您可以转储表并在其上使用diff
,前提是您按主键或唯一键转储它们。
执行SELECT DISTINCT foo FROM table
之类的查询可以帮助您了解列中的不同内容。
如果可以从大多数空的数据库开始(例如,最小化以使应用程序运行),您可以观察在向应用程序添加数据时的更改。当它很小时,转储数据库要快得多。同样用于区分它,同样用于读取输出。在一个小型数据库中,有些东西更容易理解,但有些东西更难理解。如果您拥有庞大的数据集并且列始终为3,那么您可以更加自信。
您可以从应用程序中观察SQL流量,以了解他们为每个功能访问的表和列,以及它们如何加入它们。观察SQL流量可以通过特定于应用程序的方式(例如,DBI跟踪)或特定于服务器的方式(打开常规查询日志)或使用Wireshark或tcpdump等数据包跟踪来完成。哪个是合适的取决于你正在工作的环境。例如,如果你必须在生产系统上这样做,你可能想要Wireshark。如果你在开发/测试中这样做,MySQL查询日志的缺点是所有的应用程序可能很好地混合在一起,如果有多个人在点击应用程序,它会让人感到困惑。特定于应用程序的日志可能不会受此影响,但当然应用程序可能没有这个。
请记住数据的各种存储方式。例如,所有这三个都可能意味着1980年5月1日:
数据库中可能存在非规范化的东西,其中一些可能被错误地归一化。例如,您可能想知道“为什么这个用户在一个表中有一个名字Bob,在另一个表中有一个名字Joe?”答案是“数据损坏”。
可能存在未使用的列。可能存在未使用的整个表。尽管如此,他们仍然可能拥有应用程序旧版本(或其他不再使用的应用程序)的数据,从MySQL控制台运行的查询等等。
应用程序中可能存在任何在应用程序中不可见但已被使用的内容。如果不知道应用程序中实现的算法,它们的目的可能完全不明显。例如,app中的搜索功能可以存储关于要搜索的文档及其连接的各种预先计算的信息。更糟糕的是,这些表只能通过批处理作业进行更新,因此更改文档不会触及它们(使您错误地认为它们与文档无关)。然后,你第二天早上来,桌子神秘地非常不同。但是,在搜索案例中,运行搜索时的查询日志会告诉您。
答案 1 :(得分:2)
尝试使用免费的mySQL workbench(特定于mySQL)
我有这种逆向工程数据库,最终得到了很好的实体关系图!
我已经使用SQL 20年了,这个产品真的很棒(它是免费的,来自mysql人们自己)。
它可能偶尔出现问题,崩溃等等,至少它在Ubuntu10上做过但是它们已经相对稀少而且远远超出了它们的优势!它也是积极开发的,所以bug实际上是在持续修复的。
答案 2 :(得分:1)
假设没有人打扰在表定义中声明外键,并且数据库属于正在使用的应用程序,在获取当前模式之后,我的下一步将是启用所有查询的日志记录(希望数据不使用像[x] hibernate这样的简单ORM来识别连接和数据语义。
This perl script可能会有所帮助。