在不同的DBMS中提取XML数据的最佳方法?

时间:2011-02-10 20:50:48

标签: php xml pdo

我正在编写一个基于PHP的Web应用程序,它使用PDO连接到多个数据库后端。目前它们是MySQL 5.1 +,SQLite 3.6+和PostgreSQL 8/9。其他系统可能会在以后添加,因为他们能够很好地理解我的SQL查询,或者我的抽象层可以转换查询。

现在我想以XML格式将日志数据存储在数据库中,因为这些日志事件的结构很大程度上取决于事件的类型。当大多数时候大多数列为NULL时,我不想为任何可能的日志信息添加单独的列。

但是如何在以后从数据库中恢复数据呢?我需要一种一致的方法来从SELECT查询中的XML文档中提取数据。我知道MySQL的ExtractValue()函数,我也可以通过PDO以某种方式向SQLite添加UDF(用户定义的函数)。但是我没有找到类似PostgreSQL的东西。然后我不知道哪种方式最适合将XML支持引入所有DBMS以便与相同的SQL查询一起使用。有没有人有解决方案或最佳实践?

更新:以下是此类日志记录的示例:

Num | Time        | EventId | UserId | Data
  1 | 2011-02-... |       1 |     42 | <data><messageid>123</messageid></data>
  2 | 2011-02-... |       2 |     43 | <data><messageid>123</messageid></data>
  3 | 2011-02-... |      23 |      7 | <data><oldname>006</oldname><newname>007</newname></data>

其中EventId描述发生的事件,例如锁定或解锁消息,或重命名用户。我可能想查询/ data / messageid(以及设置该XML值的相应EventIds)来查找告诉我想要绘制审核历史的特定消息的所有事件。

这不是像整个网页那样的大型XML文档,只是一种很好的结构化方法来保留我没有专用表列的所有值。并且它是可扩展的,所以如果我想象一个新的EventId数字,我可以存储该事件的任何数据块。绝不应该将XML值的条件作为我查询的唯一条件。行应首先通过其他标准(主要)缩小,如时间跨度或EventIds列表。

2 个答案:

答案 0 :(得分:1)

如果您正在努力实现数据库独立性,那么在您的数据库中存储XML将给您的抽象层带来相当大的负担,因为不幸的是,每个DBMS都以不同的方式处理它。这并不是说它无法完成,但是您将不得不在每个支持的数据库中研究XML功能(或缺乏功能)。 (我认为SQLite根本没有任何XML功能......)

如果您绝对必须使用XML,XQuery几乎是查询原始XML的理想方法,但关系数据库不支持它。 SQL / XML是在这些中查询XML的一种标准,但它没有被广泛实现。

否则,在表中包含大量空值确实没有坏处。据推测,您的应用程序代码无论如何都必须检查空值,无论它们来自数据库表还是来自不存在的XML元素......

答案 1 :(得分:1)

我会远离DB提供的XML功能,并将任何XML存储为BLOB。这可能意味着您必须复制一些数据;基本上你想要查询的任何东西。如果您希望所有这些都可查询,那么使用原生XML数据库会更好。

XML扩展通常只是令人眼花缭乱的原因是,即使服务器解析XML,它仍然需要通过网络发送;再次解码或解析。因此,通常最好将其作为字节序列流式传输并在客户端处理解析。唯一的例外是如果你想使用基于XML的访问方法(xpath或xquery查找);但是原生XML数据库比关系数据库更合适(&#34;猪上的口红&#34;)。

最后,不是将XML和关系数据库结合起来,更常见的双重设置是将数据库与搜索索引系统(如Lucene,Elastic Search)相结合;这为您提供强大的自由文本搜索和存储。然后,当修改数据库中的数据时,将逐步更新搜索索引。