首页 > Berkeley DB, 赵汝聪 > 使用DBSQL作为PHP PDO数据库引擎

使用DBSQL作为PHP PDO数据库引擎

2010年4月22日 赵汝聪

PHP Data Object(PDO)是PHP访问数据库的一个扩展库,也是目前PHP程序访问数据库的标准.PDO定义了一组访问数据库的抽象方法. 不论何种类型的数据库, 我们只用同样的接口访问就可以了.采用PDO接口的PHP程序具有独立性和开放性:与具体的数据库系统无关,与具体的操作系统无关.

本文介绍了如何在Linux环境下应用Berkeley DB SQL(DBSQL)作为PHP PDO数据库引擎.考虑到会有许多SQLite用户迁移到DBSQL以获得更高的并发性和性能,本文创建了一个SQLite3数据库并展示了如何将已有SQLite3数据库迁移到DBSQL上来.

1. 安装PDO SQLite

本文假定您已经有了一个可工作的Apache+PHP 5.x环境.此外,如果你没有一个可工作的PDO SQLite, 那么需要安装一个.以Ubuntu机器为例,我们只需要使用aptitude安装php5-sqlite即可.其它环境请Google/Baidu一下适用的安装步骤.

安装完成后,应该检查一下/usr/lib/php5/20060613+lfs目录下(该目录可能根据环境有所不同,以下一律以本机环境/usr/lib/php5/20060613+lfs为例)是否有pdo.so和pdo_sqlite.so文件:

debian:/usr/lib/php5/20060613+lfs# ls
pdo.so  pdo_sqlite.so

2. 数据库迁移

(是为了模拟SQLite3用户的迁移场景,本步骤准备了一个SQLite3数据库,并将其迁移到DBSQL数据上来)
创建SQLite3数据库/tmp/test.db,将以下文本保存为/tmp/create.sql:

CREATE TABLE Friends
([id] integer,
 [LastName] text,
 [FirstName] text,
 [Phone] text,
 CONSTRAINT [Index1] PRIMARY KEY ([id]));
INSERT INTO Friends (id, LastName, FirstName, Phone)
VALUES (1, 'Zhang', 'San', '1234-0000');
INSERT INTO Friends (id, LastName, FirstName, Phone)
VALUES (2, 'Li', 'Si', '1234-0001');
INSERT INTO Friends (id, LastName, FirstName, Phone)
VALUES (3, 'Wang', 'Wu', '1234-0002');

使用sqlite3 shell创建一个test.db:

/tmp$ cat create.sql | sqlite3 test.db

到现在为止,我们已经模拟了现实场景:我们有一个可工作的PDO(SQLite)和数据库文件.接下来我们将它迁移到DBSQL上来:
a) 按照http://www.bdbchina.com/2010/04/在unixlinux平台上应用berkeley-db-11gr2-sql/,编译得到库libdb_sql-5.0.so(路径:$HOME/db-5.0.21/build_unix/.libs/libdb_sql-5.0.so)
b) 按照以下步骤dump SQLite3数据库到test.dump文件:

/tmp$ sqlite3 test.db
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .output test.dump
sqlite> .dump
sqlite> .quit

c) 使用DBSQL shell加载dump文件.加载完成后在/tmp目录下生成新的test.db及test.db-journal:

/tmp$ mv test.db test.db.bak
/tmp$ $HOME/db-5.0.21/build_unix/dbsql test.db
Berkeley DB 11g Release 2, library version 11.2.5.0.21: (March 30, 2010)
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
dbsql> .read test.dump
dbsql> .quit
/tmp$ ls
create.sql  test.db  test.db-journal  test.dump  test.db.bak

3. 安装PDO DBSQL

本步骤需要root权限.具体做法如下:
a)复制libdb_sql-5.0.so到php lib目录下并改名为libdb_sql-50.so:

    cp /build_unix/.libs/libdb_sql-5.0.so /usr/lib/php5/20060613+lfs/libdb_sql-50.so

b)使用vi编辑usr/lib/php5/20060613+lfs/pdo_sqlite.so(这是一个二进制文件),并将文件中的libsqlite3.so.0替换为libdb_sql-50.so(只有一处替换).这使得pdo_sqlite.so连接到DBSQL,而不是SQLite3.
c)把usr/lib/php5/20060613+lfs/增加到HTTP Server的LD_LIBRARY_PATH环境变量中.否则Web Server无法找到libdb_sql-50.so. 不同的HTTP Server的具体做法不同.以Apache2为例,编辑/etc/apache2/envvars,增加一行:

    export LD_LIBRARY_PATH=/usr/lib/php5/20060613+lfs/

d)重启HTTP Server,仍以Apache2为例:

    /etc/init.d/apache2 restart

4. 使用PDO DBSQL

创建好数据库后,我们用PDO接口来访问它:将以下PHP程序保存到HTTP服务器的根目录(如htdoc/)目录下并命名为pdo_dbsql.php:

<?php
try {
    $db = new PDO("sqlite:/tmp/test.db");

    /*** The SQL SELECT statement ***/
    $sql = "SELECT * FROM Friends";
    $db->exec($sql);

    /*** Print Query Results ***/
    echo "<table><tr><th>ID</th><th>Last Name</th>";
    echo "<th>First Name</th><th>Phone</th></tr>";
    foreach ($db->query($sql) as $row) {
        echo "<tr>";
        echo "<td>".$row["id"]."</td>";
        echo "<td>".$row["LastName"]."</td>";
        echo "<td>".$row["FirstName"]."</td>";
        echo "<td>".$row["Phone"]."</td>";
        echo "</tr>";
    }
    echo "</table>";

    /*** close the database connection ***/
    $db = null;
} catch(PDOException $e) {
    echo $e->getMessage();
}
?>

使用Web浏览器访问我们编写好的pdo_dbsql.php(如http://192.168.1.131/pdo_dbsql.php),即可看到使用PDO的运行结果:

5. 结束语

本文我们介绍了如何将PDO数据引擎从SQLite迁移到DBSQL上来.对于直接采用DBSQL的用户而言,数据迁移一步可直接跳过,直接创建新的DBSQL数据库就好了.DBSQL与SQLite相比具有更高的并发性和性能,是值得PHP开发者尝试的全新SQL数据库引擎.

分类: Berkeley DB, 赵汝聪 标签: , ,
  1. 2010年4月23日11:37 | #1

    不知道您文中实践所用的PHP版本是多少,我测试用的PHP版本是5.3.2,我在pdo_sqlite.so中并未找到libsqlite3.so.0。
    后来我尝试在PHP编译配置参数中加上 –with-pdo-sqlite=shared,/opt/dbsql/,此时configure在检测 -lsqlite3时出错,我修改了一下configure文件,把它检测-lsqlite3的C程序修改成直接return 0,然后添加-lpthread -ldl -lrt 然后编译成功,也能够正常使用。不过我觉得我这种方法太不优雅了,也不知道会不会有其他问题,希望能有更标准的方法。
    感谢中国研发团队的支持。

  2. 赵汝聪
    2010年4月26日21:35 | #2

    @好大的风
    你好,我的PHP版本是PHP 5.2.6. 重新编译php的话工作量有点大了,不推荐.建议还是集中精力解决pdo_sqlite.so的问题.首先请您用”ldd pdo_sqlite.so”检查一下您的pdo_sqlite.so依赖于哪些库.必要时将输出结果贴在这里我们一起分析一下.谢谢!

  3. kcmb007
    2010年6月17日16:44 | #3

    我在arm linux 上用ex_access.c 编译出来的程序生成了一个库文件access.db, 然后用dbsql去查询, 输出如下, 麻烦帮忙分析一下,是编译的问题还是其他问题
    #./dbsql access.db
    /dev/shm/access.db: library build did not include support for locking
    /dev/shm/access.db: library build did not include support for locking
    /dev/shm/access.db: library build did not include support for locking
    /dev/shm/access.db: library build did not include support for locking
    /dev/shm/access.db: library build did not include support for locking
    /dev/shm/access.db: PANIC: Operation not supported
    /dev/shm/access.db: unable to join the environment
    Error: unable to open database “access.db”: database disk image is malformed

  4. 赵汝聪
    2010年6月18日10:24 | #4

    你好,ex_access.c程序生成的db文件是Berkeley DB数据库文件,并非合法的Berkeley DB SQL数据库文件。因此不能用DBSQL这个工具打开。

本文的评论功能被关闭了.
Դ