首页 > Berkeley DB XML, 赵汝聪 > 采用Berkeley DB XML PHP建立原生XML Web服务器

采用Berkeley DB XML PHP建立原生XML Web服务器

2009年10月12日 赵汝聪

近十年来,XML应用越发广泛,政府也推出了《基于XML的电子公文格式规范》等标准。那么,在需要XML数据库引擎的情况下,采用原生XML数据库Berkeley DB XML(以下简称BDB XML)取代MySQL(或其它传统DB)做后台数据库是一个更好的选择。

BDB XML是Oracle推出的一款开源原生XML数据库。与传统数据库相比,原生XML数据库的优势有:
1. 可以直接操作XML文件,XML数据无损–在某些场合,无损的数据源意味着法律效力。
2. 原生检索方式,支持XQuery和XPath,符合XML习惯。
3. 性能优化:原生XML数据库会针对XML特点进行各种优化,如插入文档索引、建立节点ID等。
4. 支持相同数据的不同视图。

和其它原生XML数据库相比,BDB XML优势有:
1. 完整的ACID 事务处理、自动恢复、热备份、用于分布式事务的HA支持。
2. 支持XQuery(含XQuery Update)和XPATH。
3. 可以利用其特有的二进制元数据存取大容量二进制对象(非XML数据)。
4. 支持全Unicode字符集,中文存储、查询都不成问题。
5. 提供一套容器和迭代器接口访问和操作查询结果。
6. 提供交互式命令行工具。

以上第三点是一个非常实用的特性,某种程度上它补足了XML应用的”最后一公里“:比方说,你正在为教育部门开发一个考生管理数据库,需要将考生的资料存成XML文档,那么存取照片(二进制数据)就相当麻烦。一般来讲传统的选择有两种:一是转换为Base64Binary格式嵌入到XML文档中,这意味着存取两端都需要转换大量图片数据,效率就很低下;二是为每个照片生成一个引用再另存它处,只在XML文档中保留一个引用,这种方法不但复杂,而且把数据从文档中分割了出来,损失了ACID特性,管理不便。而使用BDB XML就可以将照片数据直接以二进制元数据的形式嵌入到XML文档中,存取都非常方便,还可以基于数据库实现图像/视频检索。

下面,介绍一下BDB XML PHP的安装过程:

安装Apache+PHP环境

好吧,这是一个烂大街的话题,网上一抓一大把。下面以Debian 5.0和apache2为例:
用aptitude安装以下软件包:

apache2
libapache2-mod-php5
php5
php5-dev
php5-cgi

安装完毕。启动Apache服务器:

sudo /etc/init.d/apache2 start

测试一下是否安装成功,首先找到http的根目录(本机环境是/var/www),在该目录下生成php测试文件test.php(内容如下):

<?phpinfo();?>

用浏览器打开网页服务器的test.php,如果安装成功,会打开php信息页。

安装BDB XML PHP

移步http://www.oracle.com/technology/software/products/berkeley-db/xml/index.html下载源码包dbxml-2.5.13.tar.gz,并放置在$HOME目录下。下面以Linux上的安装为例:

cd $HOME
tar zxf dbxml-2.5.13.tar.gz
cd dbxml-2.5.13
./buildall
cd db-4.8.24/php_db4
phpize
./configure --with-db4=$PWD/../../install
make
sudo make install
cd ../../dbxml/src/php/
phpize
./configure --with-dbxml=$PWD/../../../install
make
sudo make install

接下来编辑/etc/php5/apache2/php.ini和/etc/php5/cgi/php.ini文件(可能路径略有不同),把以下两行加到Dynamic Extensions段:

extension=db4.so
extension=dbxml.so

大功告成,为保安全,最好重启一下Apache服务器。到此BDB XML PHP全部安装成功。在实际应用中,需要特别注意帐户和权限问题:要保证Apache的运行帐户对容器(Container)文件及其所在目录有读写权限。

范例

从开心网的群共享页面http://www.kaixin001.com/group/file.php?gid=627784&fid=450163&start=0下载附件xmlData.tar.gz,解压后,将xmlData目录下的所有文件拷贝到http根目录下,然后执行:

./gen_cont.sh $HOME/dbxml-2.5.13/install/bin/dbxml

脚本即会生成一个容器:simple.dbxml。该容器内包含三百多个xml文档,形如:

<?xml version="1.0"?>
<产品>
    <种类>fruits</种类>
    <商品>Avocado</商品>
    <存货>
        <库存量单位>AvocfruijfHs18</库存量单位>
        <价格>0.24</价格>
        <存货>393</存货>
    </存货>
    <厂家>Simply Fresh</厂家>
</产品>

使用浏览器访问服务器上的simple.php页面,即可看到转换后输出的数据表。simple.php的内容如下:

<html>
<body>
<?
$contName = 'simple.dbxml'; // Container名字

// 创建Manager和Context
$mgr = new XmlManager();
$qc = $mgr->createQueryContext(); // Query Context
$qc->setDefaultCollection($contName); // 设置默认Container

// 打开Container
$cont = $mgr->openContainer($contName);

// 创建XQuery查询表达式,将数据提取出来并转换为html表格
$query = 'for $产品 in collection()/产品';
$query .= ' return <tr>';
$query .= '<td>{$产品/种类/string()}</td>';
$query .= '<td>{$产品/商品/string()}</td>';
$query .= '<td>{$产品/存货/价格/string()}</td>';
$query .= '<td>{$产品/存货/存货/string()}</td>';
$query .= '<td>{$产品/厂家/string()}</td>';
$query .= '</tr>';

// 输出表格头
?><table width='100%' border='frame'>
<tr><td>种类</td><td>商品</td><td>价格</td><td>存货</td><td>厂家</td></tr><?

// 查询并遍历结果,输出到表格
$results = $mgr->query($query, $qc);
while ($results->hasNext())
echo $results->next()->asString();

// 输出表格尾
?></table><?
?>
</body>
</html>

可见,只需30余行的代码就能完成xml数据库到网页表格的转换。例图:
bdb_xml_php_web

总结

至此,我们已经介绍了BDB XML PHP的安装和使用。至于更多BDB XML功能,如二进制元数据、环境、事务、排序、索引等,请关注后续文章。

  1. 石头
    2009年11月23日15:38 | #1

    BDB XML is amazing to embrace the power of the semi-structure data and document-based database.
    Could BDB XML be used like this post mentioned in the web service of enterprise application?

  2. 赵汝聪
    2009年11月24日10:25 | #2

    @石头
    Sure. There are many enterprise leaders using BDB XML: Autodesk, EMC, Juniper, Motorola, MXLogic, Suse, etc.
    BDB XML support Java, PHP and Python. You may chose the favorite interface to setup web service of enterprise application.

  3. 石头
    2009年12月8日14:52 | #3

    为什么我能在PHP命令行下运行,而不能在网页中运行呢?
    我使用的window操作系统,php5.2.10, 我把php_db4.dll和php_dbxml.dll文件拷贝到C:\Program Files\PHP\ext中,然后加入extension=php_db4.dll和
    extension=php_dbxml.dll到Dynamic Extensions段。

  4. 赵汝聪
    2009年12月8日17:39 | #4

    你好,网页运行不了的原因有很多。整个系统环境,包括WebServer/PHP/OS都有出错的可能。请告诉我出错的具体情况(Web上打印的错误,或者是截取一段php error log)。谢谢!

    在连接BDB XML之前,请确定你的WebServer+PHP可用。可按照本文编辑一个测试页面,看WebServer能否解析该文件并打印php信息。

    另外,根据你的描述,有可能是你改动的php配置文件是对应PHP命令行(php-cli)的,对应WebServer的配置文件一般是(php-cgi)。

  5. 石头
    2009年12月9日16:19 | #5

    谢谢你的帮助。
    我的PHP环境可以正常运行没有包含BDB XML的脚本。当运行以上范例时,显示的错误为无法找到XmlManager Class。
    在官网BBS,包括尝试过把BDB XML下所有的dll文件拷入C:\Program Files\PHP\ext中,都没有找到准确的答案,
    后来升级PHP到5.2.11版本,测试运行正常。当向php.ini加入BDB XML申明后启动apache,系统报警为某个内存地址不能读取。卸掉PHP,选择cgi方式而不是原有module方式应用PHP,结果依然。apache从2.2.11升级到2.2.14,结果不变。
    估计是PHP某些window版本和BDB XML冲突。

  6. 石头
    2009年12月10日11:40 | #6

    终于搞定了,分享一下吧
    在windows平台PHP中应用DBD XML的方法如下:
    1.首先安装,只需要选择安装core部分即可,然后在将bin目录,如C:\Program Files\Oracle\Berkeley DB XML 2.5.13\bin, 添加到系统环境变量中,重启电脑。
    2.复制bin目录中的php_db4.dll和php_dbxml.dll到extension_dir目录,如C:\Program Files\PHP\ext
    3.只需要追加extension=php_db4.dll,extension=php_dbxml.dll到php.ini中的Dynamic Extensions章节
    4.用CLI方式查看是否成功,如果成功,在cgi方式下也应该成功。

  7. 赵汝聪
    2009年12月10日16:34 | #7

    你好啊,祝贺你解决了这个问题,也感谢你在OTN官网上的分享。比较了一下你最后的解决方案和以前的操作,似乎先前在你的系统上没有成功,是因为没有添加/bin到系统环境变量并使之生效(重启电脑)?至于只安装Core部分还是完整安装,除了节省一些库文件空间,其它应该影响不大。

  8. 石头
    2009年12月11日09:20 | #8

    是的。我的电脑里有两个超级用户,而BDB XML只把/bin写入了安装用户的环境变量,这样php-cli在安装用户中可以成功运行。但是apache需要调用系统环境变量,所以php-cgi运行失败。
    结果和http://forums.oracle.com/forums/thread.jspa?messageID=3728487&#3728487说的一样。
    虽然xQuery在java和c++中是一样,但是其它的,如环境、容器、事务的使用确是差异很大,又找不到相应api文档或更翔实的示例说明。很期待你们进一步的PHP教程,中英文都没有关系。谢谢了 :)

  9. 石头
    2009年12月14日11:38 | #9

    是的。我的电脑里有两个超级用户,而BDB XML只把/bin写入了安装用户的环境变量,这样php-cli在安装用户中可以成功运行。但是apache需要调用系统环境变量,所以php-cgi运行失败。
    结果和http://forums.oracle.com/forums/thread.jspa?messageID=3728487&#3728487说的一样。
    很期待你们进一步的PHP教程,中英文都没有关系。谢谢了 :)

  10. 赵汝聪
    2009年12月15日15:03 | #10

    感谢你的关注,关于这个路径问题,应该在文档有特殊提示,我们应该补足这个细节,呵呵。
    关于下一步的教程,我们会尽力而为。其实在你了解容器、环境、事务的应用后,PHP只存在函数调用上的一些区别,不会成为很大障碍。我们可以参考范例目录dbxml-2.5.x/example/php/。
    此外,由于我们是开源软件,源代码本身也是很好的资源。如PHP API实现的都是PHP接口到C++接口的翻译,这部分代码全部在dbxml-2.5.x/src/php/目录下,全部不足5000行。比如想知道PHP接口如何设置WholeDocType,可以在src/php/下全文搜索Wholedoc,即可知C++里的定义XmlContainer::WholedocContainer对应为PHP里的XmlContainer_WholedocContainer。

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