如何将MySQL表转储到文件然后读取它并使用它代替数据库本身?

时间:2015-04-18 09:47:18

标签: php mysql json

因为我使用的提供商有一个非常不可靠的MySQL服务器,这个服务器每周下降1次: - 影响我制作的其中一个网站,我想以下列方式防止其出现:

  • 将MySQL表转储到文件中以防与SQL连接 服务器失败,
  • 然后读取文件而不是服务器,直到服务器返回。

这将避免从用户体验的角度出现中断。 事实上事情并不像看起来那么容易,我请求你的帮助。

我所做的是将数据保存为JSON文件格式。 但是这会产生问题,因为数据库中的许多数据都“明确”包含转义复杂的URL,带有长参数行,这在JSON的解码过程中会产生一些问题。 在CSV和TSV上也没有正确的工作。 CSV由Commas或Semilcolon分隔,并且这些内容存在于从DB中获取的原始内容中。 TSV格式留下不可删除的双引号,无需避免将它们删除到记录的字段中

然后我尝试序列化从DB读取的每个记录,存储它并检索它序列化它。 但结果有点灾难性,因为所有记录都存储在文件中。 当我检索它们时,只返回一个。然后有一些东西阻碍了程序的运行(请在下面的代码中)

require_once('variables.php');
require_once("database.php");
$file = "database.dmp";

$myfile = fopen($file, "w") or die("Unable to open file!");

$sql = mysql_query("SELECT * FROM song ORDER BY ID ASC");
    // output data of each row
    while ($row = mysql_fetch_assoc($sql)) {
    // store the record into the file
    fwrite($myfile, serialize($row));
    }
fclose($myfile);
mysql_close();


// Retrieving section
$myfile = fopen($file, "r") or die("Unable to open file!");

// Till the file is not ended, continue to check it
    while ( !feof($myfile) ) {
        $record = fgets($myfile); // get the record
        $row = unserialize($record); // unserialize it
        print_r($row); // show if the variable has something on it
     }
fclose($myfile);

我也试过uuencode和base64_encode,但是他们的选择更糟。

有没有办法实现我的目标?

非常感谢您的帮助

3 个答案:

答案 0 :(得分:2)

如果您的数据层很好地解耦,您可以考虑使用SQLite作为后备存储。

只需添加一个抽象,使用相同的代码访问存储,并在主存储目标不可用的情况下更改存储目标。

- - - - - - - - EDIT 您还可以尝试考虑一些缓存(json / html文件?!)策略,以便在mysql中断的情况下返回过时的数据。

-----编辑2 ----- 如果不是太费力,请考虑使用PDO,我确定你永远不会回头相信我这会帮助你轻松地构建数据库调用在存储之间切换时。

  

请仅以下面的例子为例,有更好的方法   设计这个架构部分代码的方法。

只是一个小而基本的代码来向您展示我的意思:

class StoragePersister
{
    private $driver = 'mysql';

    public function setDriver($driver)
    {
        $this->driver = $driver;
    }

    public function persist($data) 
    { 
        switch ($this->driver)
        {
            case 'mysql':
                $this->persistToMysql($data);
            case 'sqlite':
                $this->persistToSqlite($data);
        }
    }

    public function persistToMysql($data)
    {
        //query to mysql
    }

    public function persistSqlite($data)
    {
        //query to Sqlite
    }

}

$storage = new StoragePersister;
$storage->setDriver('sqlite'); //eventually to switch to sqlite
$storage->persist($somedata); // this will use the strategy to call the function based on the storage driver you've selected.

-----编辑3 ----- 请看一下" strategy"设计模式部分,我想它可以帮助更好地理解我的意思。

答案 1 :(得分:0)

SELECT...之后,您需要创建一个正确的结构来插入数据,然后您可以序列化或者想要什么。 例如:  你有一行,你可以这样做 - $sqls[] = "INSERT INTO歌曲(field1,field2,.. fieldN) VALUES(field1_value, field2_value, ... fieldN_value);"; 比你可以序列化这个$sqls,写入文件,当你需要它时,你可以阅读,反序列化和查询。

答案 2 :(得分:0)

您是否考虑过将查询缓存到像APC这样的缓存中?此外,您可能希望使用mysqlipdo而不是mysql(在最新版本的PHP中不推荐使用Mysql)。

要回答你的问题,这是一种做法。

  • var_export会将变量导出为有效的PHP代码
  • require会将数组的内容放入$ data变量中(因为return语句)

以下是代码:

$sql = mysql_query("SELECT * FROM song ORDER BY ID ASC");
$content = array();

// output data of each row
while ($row = mysql_fetch_assoc($sql)) {
    // store the record into the file
    $content[$row['ID']] = $row;
}
mysql_close();

$data = '<?php return ' . var_export($content, true) . ';';
file_put_contents($file, $data);

// Retrieving section
$rows = require $file;