PHP / SQLite - 将表从磁盘复制到内存

时间:2009-07-21 08:43:54

标签: php sqlite

我的硬盘驱动器(file.db)上有一个带有5个表的sqlite3数据库。 我想将其中3个表复制到内存数据库(:memory:)。

使用PHP5的PDO格式有一种简单的方法吗?

6 个答案:

答案 0 :(得分:11)

在您的情况下,不是特定于pdo的解决方案可能会或可能不充分:

  • 创建一个:memory:database
  • Attach现有数据库文件
  • CREATE TABLE ... AS SELECT * FROM ...
  • Detach数据库文件

编辑:示例
首先是存储在mydb.sq3

中的示例数据库
<?php
$pdo = new PDO('sqlite:mydb.sq3');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$pdo->exec('CREATE TABLE foo(x INTEGER PRIMARY KEY ASC, y, z)');

$stmt = $pdo->prepare("INSERT INTO foo (x,y,z) VALUES (:x,:y,:z)");
$stmt->bindParam(':x', $x);
$stmt->bindParam(':y', $y);
$stmt->bindParam(':z', $z);

for($x=0; $x<100; $x++) {
    $y = $x*2;
    $z = $x*2+1;
    $stmt->execute();
}

现在我们有一个:内存:数据库,想要传输表foo

<?php
$pdo = new PDO('sqlite::memory:');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$pdo->exec('ATTACH "mydb.sq3" as filedb');
$pdo->exec('CREATE TABLE bar AS SELECT * FROM filedb.foo');
$pdo->exec('DETACH filedb');

完成。但是让我们来看看sqlite_master表

foreach($pdo->query('SELECT sql FROM sqlite_master') as $row) {
    echo $row['sql'];
}

打印

CREATE TABLE bar(x INT,y,z)

INTEGER PRIMARY KEY ASC 声明丢失。可能就足够了......

答案 1 :(得分:4)

如果这就是你需要做的事情,那么VolkerK的答案是我提供的答案,但我觉得我必须指出你每次运行时都会将这些表的内容读入内存代码(每次加载页面?),因此从磁盘查询数据文件可能更好。

答案 2 :(得分:1)

请注意,总是可以使用某种共享内存机制(例如APC,memcache等)来保持sqlite的内存数据库在连接中保持不变。

答案 3 :(得分:0)

您可以在连接结束时转储数据库,将其保存为apc变量,然后在下次执行开始时从apc再次加载并运行。

答案 4 :(得分:0)

当使用~150Mb sqlite数据库时,使用VolkerK概述的方法大致使我的代码性能翻倍。

将数据库加载到内存中的sqlite db并不需要对现有代码进行任何其他更改。

我的用例是批量处理数据,因此我没有必要处理Wez Furlong强调的问题。

将数据读入内存的速度非常快。整个150Mb在不到两秒的时间内从SSD加载到内存中。这似乎太好了,所以我检查并重新检查数据。

非常感谢VolkerK提供了一个神奇的解决方案!

我还发现,当我为内存表编制索引时,我的查询执行速度提高了三倍

curl_setopt($session, CURLOPT_SSL_VERIFYPEER, 0);

答案 5 :(得分:0)

如果您需要用于测试的小型数据库,则可以将数据库导出到SQL文件,然后在PHP中作为单个查询执行它:

class EphemeralPDO extends \PDO {
  public function __construct() {
    parent::__construct('sqlite::memory:', null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
    $queries = file_get_contents(__DIR__ . '/database.export.sql');
    $this->exec($queries);
  }
}