我刚刚接到任务,要恢复/重建一个极其庞大且复杂的网站,该网站没有备份且完全丢失。我有所有 PHP 文件的完整(希望如此)副本,但是我完全不知道数据库结构是什么样的(除了它肯定至少有 50 个左右的表......非常复杂)。所有数据都已丢失,最初的开发人员大约一年前在激烈的争执中被解雇(有人告诉我)。我作为一名 PHP 开发人员已经有一段时间了,并且很乐意尝试对所有内容进行分类并让应用程序/站点恢复运行……但是缺少数据库将是一场巨大的斗争。那么...有什么方法可以模拟 MySQL 与某些软件的连接,这些软件将捕获所有传入的查询并尝试使用请求的字段和表名来重建结构?
在我看来,如果我开始点击应用程序,它会传递一个查询
SELECT
name,phonefromcontact_tableWHEREcontact_id='1'
...应该有一种方法来捕获该信息并假设有一个名为“contact_table”的表至少有 4 个具有这些名称的字段...如果我可以重复这样做,每次都添加一些示例数据到发现的字段,然后转到另一个页面,最终我应该得到大部分数据库结构的粗略副本(至少是所有面向公众的部分)。这比手动读取所有代码并提取每个引用、读取所有连接和子查询并手动对其进行排序要容易得多。
有人试过这个吗?从 PHP 代码逆向工程数据库结构的任何其他想法?
最佳答案
mysql> SET GLOBAL general_log=1;
启用此配置后,MySQL 服务器会将每个查询写入日志文件(默认情况下为 datadir/hostname.log),即使是那些因为表和列不存在而出错的查询还没有。
http://dev.mysql.com/doc/refman/5.6/en/query-log.html说:
The general query log can be very useful when you suspect an error in a client and want to know exactly what the client sent to mysqld.
当您在应用程序中四处点击时,它应该会生成 SQL 查询,您可以打开一个终端窗口,在一般查询日志上运行 tail -f。当您看到由该引用表或尚不存在的列运行的查询时,请创建这些表和列。然后在应用中重复点击。
许多事情可能会使这项任务变得更加困难:
如果查询使用 SELECT *,您无法推断出列的名称,甚至无法推断出有多少列。您必须检查应用程序代码以查看在返回查询结果后使用了哪些列名。
如果 INSERT 语句省略列名列表,您将无法知道有哪些列或有多少列。另一方面,如果 INSERT 语句确实指定了列名列表,您将无法知道是否有更多列旨在采用其默认值。
列的数据类型不会从它们的名称、字符串长度、字符集或默认值中明显看出。
约束、索引、主键、外键在查询中不明显。
有些表可能存在(例如,查找表),即使您在应用程序中找到的查询从未提及它们的名称。
说到查找表,许多数据库都在表中存储了一组初始值,例如所有可能的用户类型等。如果不了解此类查找表的数据,应用将很难或不可能运行。
可能有触发器和存储过程。应用程序中的 CALL 语句可能会引用过程,但您无法猜测触发器或存储过程中的代码是什么。
这个项目必然非常费力、耗时,并且涉及很多猜测。雇主与开发商有很大的不和这一事实可能是一个警告信号。小心设定期望值,让雇主明白要做到这一点需要做很多工作。
PS:我假设您使用的是最新版本的 MySQL,例如 5.1 或更高版本。如果您使用 MySQL 5.0 或更早版本,您应该将 log=1 添加到您的/etc/my.cnf 并重新启动 mysqld。
关于php - 模拟MySQL连接分析查询重建表结构(逆向工程表),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18027235/
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类
给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
您将如何构建一个简单的Sinatra应用程序?我正在制作,我希望该应用具有以下功能:“应用程序”更像是一个包含所有信息的管理仪表板。然后另一个应用程序将通过REST访问信息。我还没有创建仪表板,只是从数据库中获取东西session和身份验证(尚未实现)您可以上传图片,其他应用可以显示这些图片我已经使用RSpec创建了一个测试文件通过Prawn生成报告目前的设置是这样的:app.rbtest_app.rb因为我实际上只有应用程序和测试文件。到目前为止,我已经将Datamapper用于ORM,将SQLite用于数据库。这是我的第一个Ruby/Sinatra项目,所以欢迎任何和所有建议-我应
我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时