简体   繁体   English

MySQL:从SQL查询中转储数据库

[英]MySQL: Dump a database from a SQL query

I'm writing a test framework in which I need to capture a MySQL database state (table structure, contents etc.). 我正在编写一个测试框架,需要在其中捕获MySQL数据库状态(表结构,内容等)。

I need this to implement a check that the state was not changed after certain operations. 我需要执行此检查,以确保某些操作后状态没有更改。 (Autoincrement values may be allowed to change, but I think I'll be able to handle this.) (自动增量值可以允许改变,但我想我能处理这个问题。)

The dump should preferably be in a human-readable format (preferably an SQL code, like mysqldump does). 转储最好采用人类可读的格式(最好是SQL代码,如mysqldump一样)。

I wish to limit my test framework to use a MySQL connection only. 我希望将测试框架限制为仅使用MySQL连接。 To capture the state it should not call mysqldump or access filesystem (like copy *.frm files or do SELECT INTO a file, pipes are fine though). 要捕捉它应该叫的mysqldump或访问文件系统的状态(比如复制* .FRM文件还是选择到一个文件中,管道都很好,虽然)。

As this would be test-only code, I'm not concerned by the performance. 由于这将是仅测试的代码,因此我不关心性能。 I do need reliable behavior though. 我确实需要可靠的行为。

What is the best way to implement the functionality I need? 实现我所需功能的最佳方法是什么?

I guess I should base my code on some of the existing open-source backup tools... Which is the best one to look at? 我想我的代码应该基于一些现有的开源备份工具...哪一种是最好的?

Update: I'm not specifying the language I write this in (no, that's not PHP), as I don't think I would be able to reuse code as is — my case is rather special (for practical purposes, lets assume MySQL C API). 更新:我没有指定我用这种语言编写的语言(不,那不是PHP),因为我认为我无法按原样重用代码-我的情况很特殊(出于实际目的,假设MySQL C API)。 Code would be run on Linux. 代码将在Linux上运行。

Given your requirements, I think you are left with (pseudo-code + SQL) 鉴于您的要求,我认为您可以使用(伪代码+ SQL)

tables = mysql_fetch "SHOW TABLES"
foreach table in tables
    create = mysql_fetch "SHOW CREATE TABLE table"
    print create
    rows = mysql_fetch "SELECT * FROM table"
    foreach row in rows
        // or could use VALUES (v1, v2, ...), (v1, v2, ...), .... syntax (maybe preferable for smaller tables)
        insert = "INSERT (fiedl1, field2, field2, etc) VALUES (value1, value2, value3, etc)"
        print insert

Basically, fetch the list of all tables, then walk each table and generate INSERT statements for each row by hand (most apis have a simple way to fetch the list of column names, otherwise you can fall back to calling DESC TABLE ). 基本上,获取所有表的列表,然后遍历每个表并手动为每一行生成INSERT语句(大多数api都有一种简单的方法来获取列名列表,否则可以退回到调用DESC TABLE )。

SHOW CREATE TABLE is done for you, but I'm fairly certain there's nothing analogous to do SHOW INSERT ROWS . SHOW CREATE TABLE已为您完成,但我可以肯定没有类似的东西可以做SHOW INSERT ROWS

And of course, instead of printing the dump you could do whatever you want with it. 当然,除了打印转储,您还可以使用它进行任何操作。

If you don't want to use command line tools, in other words you want to do it completely within say php or whatever language you are using then why don't you iterate over the tables using SQL itself. 如果您不想使用命令行工具,换句话说,您想完全在说php或您使用的任何语言内完成操作,那么为什么不使用SQL本身遍历表。 for example to check the table structure one simple technique would be to capture a snapsot of the table structure with SHOW CREATE TABLE table_name, store the result and then later make the call again and compare the results. 例如,检查表结构,一种简单的技术是使用SHOW CREATE TABLE table_name捕获表结构的快照,存储结果,然后稍后再次调用并比较结果。

Have you looked at the source code for mysqldump? 您是否看过mysqldump的源代码? I am sure most of what you want would be contained within that. 我确信您想要的大部分内容都将包含在其中。

DC DC

Unless you build the export yourself, I don't think there is a simple solution to export and verify the data. 除非您自己构建导出,否则我认为没有简单的解决方案来导出和验证数据。 If you do it table per table, LOAD DATA INFILE and SELECT ... INTO OUTFILE may be helpful. 如果按表对表进行加载 ,则LOAD DATA INFILESELECT ... INTO OUTFILE可能会有所帮助。

I find it easier to rebuild the database for every test. 我发现为每个测试重建数据库更为容易。 At least, I can know the exact state of the data. 至少,我可以知道数据的确切状态。 Of course, it takes more time to run those tests, but it's a good incentive to abstract away the operations and write less tests that depend on the database. 当然,运行这些测试需要花费更多时间,但是这是抽象化操作并编写较少依赖于数据库的测试的良好动机。

An other alternative I use on some projects where the design does not allow such a good division, using InnoDB or some other transactional database engine works well. 在设计不允许如此良好划分的某些项目中,我使用了另一个替代方法,即使用InnoDB或其他事务性数据库引擎效果很好。 As long as you keep track of your transactions, or disable them during the test, you can simply start a transaction in setUp() and rollback in tearDown(). 只要您跟踪事务或在测试过程中将其禁用,就可以简单地在setUp()中启动事务并在tearDown()中回滚。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM