两种文档数据库:一种是 IBM pureXML,它是构建在关系型引擎之上的XML数据库,提供了关系型(SQL/XML)以及非结构化(XQuery)查询语言;另一种是MarkLogic,它是构建在数据库新范式之上的数据库(或者称之为NoSQL),提供了非结构化查询语言(XQuery)。

  近期,在NoSQL数据库厂商中正在不断出现SQL趋势。其中一个例子就是Cassandra的CQL,以及更成熟的产品Hadoop基于SQL的接口。这是NoSQL正在尝试进入企业领域,总的来说是件好事儿。

  本文关注在关系型数据库与非关系型数据库的混合环境中所获得的经验和教训。

  为什么SQL与NoSQL发生了冲突?

  NoSQL也就是非SQL。对我来说这意味着将关注点转向非关系型数据库,可能会发现数据库的新接口。这是件好事儿!是否从企业的角度盲目地接受SQL?虽然SQL是正确的选择,但是你仍旧需要考虑相应的后果并确保SQL与NoSQL的协调一致。换句话说,这意味着开发者需要改变盲目的观念,减少对SQL的依赖。

  但是要当心:事情将会变得麻烦。SQL并不好用而且将会与非结构化数据产生冲突。

 

  数据模型

  在关系型数据库中:

RowSet -> SQL -> RowSet
  RowSet如下:

RowSet -> Item+
Item   -> INT | VARCHAR n | ...
  我不了解JSON数据模型,所以将讨论我非常熟悉的数据模型XPath数据模型:

XDM -> XPath/XQuery -> XDM
  XDM 如下:

XDM        -> Item+
Item       -> AtomicType | Tree
AtomicType -> integer | string | ...
...
  (上述定义有些简单但是能够说明问题).

  文档数据模型的不同之处在于树结构不是扁平的。

{
  "namespace": "person-2.0",
  "comments": "This guy asked me for a dinosaur sticker. What a nutter!",
  "person": {
    "handle": "dscape",
    "comments": "Please do not send unsolicited mail."
  }
}
  对上述数据模型可能的含义有多种解释:

SELECT comments from PERSON where handle = "dscape"
  查询指的是什么“comment”元素?如果你看下SQL/XML,那么查询有点像:

SELECT XMLQuery('$person/comments')
FROM PERSON
WHERE XMLExists('$person/person/handle')
  这让我得出了以下明显的结论:树需要一种方式进行遍历。在XML中是XPath,在JSON中可能是JSONSelect或者是其他命令。但是首先你需要一种标准的方法进行遍历。

  让上述挑战变得更加有趣的是schema的版本管理与演变。在关系型数据库中schema的版本管理及演变已经被忽略了,但是对文档来说它绝对不能被忽略。考虑一下微软的Word,他支持众多的版本,Word2003,2005,等等。

  灵活的、非结构化:在查询中我们假定句柄是person的一个孩子,有关我是个笨蛋的评论是该树的一个直接的后代。这注定会带来改变,因为SQL不支持文档的版本化,所以你必须对此进行扩展。

  查询非结构化数据的正确语言必须知晓版本。在XQuery中我们可以将查询表示为:

declare namespace p = "person-2.0" ;

for $person in collection('person')
let $comments-on-person := $person/p:comments
where $person/p:handle = "dscape"
return $comments-on-person
 

 

  以Frankenqueries为例

  有些人曾经将我称作Frankenqueries。这个称呼一直跟我到现在。

  让我们想象以下两个购物清单,一个是Joe的,另一个是Mary的。

marys-shopping.json
{ "fruit": {
   "apples": 2
}, "apples": 5 }


joes-shopping.json
{ "fruit": {
   "apples": 6,
   "oranges": 1
} }
  现在使用SQL/JSON扩展:

SELECT apples
  FROM LISTS
  返回值是什么?还记得RowSet输入与输出吗?

2, 5
---
6
  因此,尽管你非常明确地需要一些苹果,但是你得到的是2个RowSet而不是3个RowSet,而且其中一个RowSet包括一个字符串。如果你想返回三个字符串,那么有两个RowSet作为输入,三个RowSet作为输出。我不是数学家但是这听起来不是很好。

  如果你在使用能够处理非结构化信息的工具那么这并不是什么问题。使用javascript没有任何问题而且使用Xquery肯定也不存在问题。

  结论:用于非结构化数据的非常棒的语言

  尽管XQuery是用于非结构化信息的一个非常不错的语言,但是我不主张使用该语言。我要说的是对处理非结构化数据的真正的语言的需求。

  但是不要接受“依附于SQL”。SQL已经是明日黄花现在受宠的是NoSQL。给它一点时间,NoSQL将引起你的兴趣。另外编写运行在数据库上的javascript代码也有众多乐趣:不要让NoSQL和javascript离你而去。

  用于非结构化的SQL将会失败。然后用于非结构化数据的PL-SQL将会失败。你可以使用javascript编写应用并存储在CouchApp中,或者可以使用XQuery编写应用并存储在MarkLogic中,而且就应该这样!

  选择用于非结构化数据的查询语言时,检查列表如下:

  · 导航语言

  · 数据模型

  · 正则表达式

  · Lambdas

  · 高阶函数

  · 功能风格

  · 良好的字符串处理

  · 构件这样能够构建自己的类库

  · 应用服务器感知: 具有适合 REST的函数

  你可以选择或者忽略这个建议但是你将如一个失意的silverlight开发者那样以失败而告终。喜欢进行数据库创新的人将因开发者选择回归SQL而感到失落。