面向文档的数据库 CouchDB(2)

来源:developerWorks 中国 作者:成 富
  


清单 4. 请求带附件的文档时的响应内容
{ 
   "_id": "testdoc", 
   "_rev": "3-1364618102", 
   "_attachments": { 
       "Screenshot.png": { 
           "stub": true, 
           "content_type": "image/png", 
           "length": 164279 
       } 
   } 
 }

独立型附件是 CouchDB 0.9 中新增的功能,可以在不改变文档的情况下,对附件进行操作。另外,不需要对附件进行 base64 编码。要创建独立型附件,只需要发送 PUT 请求到databasename/doc_id/attachment?rev=rev_id就可以创建或更新一个名为attachment的附件。 PUT 请求的内容类型(Content-Type)和内容指明了附件的类型和数据。

在介绍完 CouchDB 的 REST API 之后,下面在使用 CouchDB 的时候如何对应用进行建模。





为应用建模

由于关系数据库的流行,很多开发者对于实体 - 关系(Entity-Relation,ER)模型非常熟悉。而 CouchDB 使用的是面向文档(Document oriented)的模型。在使用 CouchDB 的时候,需要完成从 ER 模型到文档模型的思维方式的转变。下面通过几个具体的例子来说明如何在 CouchDB 中对于一些典型的场景进行建模,并与关系数据库中的建模方式进行比较。

描述实体

第一个场景是对实体的描述。关系数据库中使用表来表示实体。数据库表是有固定的模式的,该模式定义了表中每行数据应该满足的格式。表中每行数据都对应于实体的一个实例。比如应用中如果需要描述“注册用户”和“图书”两种实体的话,就需要两张不同的表。而在 CouchDB 中,所有的实体都是以文档来描述的。文档是没有模式的,可以用任意的 JSON 对象来表示。同一实体的实例在结构上也可能不同。这更能反映问题域中数据的真实状态。比如对“人”这一实体进行描述时,有一个字段是“传真号码”。因为不是所有人都拥有传真机,这一字段是可选的。如果用关系数据库来建模的话,则需要在表中添加一列表示传真号码。对于没有传真机的人来说,该列的值为null。而如果用 CouchDB 中的文档来描述的话,对于有传真机的人,其 JSON 对象中就有一个属性表示“传真号码”,否则的话就没有此属性。 CouchDB 强于关系数据库的另外一个特性是可以非常容易的表示复杂数据类型。通常来说,关系数据库中表的列只能是简单数据类型。而 CouchDB 中的文档由于用 JSON 来描述,可以使用任意复杂的嵌套结构。同样是对“人”这一实体的描述,另外一个有用的信息是“家庭住址”。“家庭住址”可以简单地用一个字符串来表示,也可以拆分成“国家”、“省(市)”、“县”和“街道”等多个字段来表示。对于后者,如果用关系数据库来描述的话,则需要使用多个列或是额外的表;而用 CouchDB 的文档来描述的话,可以直接把复杂的 JSON 对象作为字段的值,如{"address" : {"country" : " 中国 ", "city" : " 北京 "}}。比起关系数据库来说,要更加简单和自然。

描述一对一和一对多关系

第二个场景是描述一对一和一对多的关系。在关系数据库中,实体之间的一对一和一对多关系是通过外键来描述。比如在一个电子商务应用中,订单与其中包含的单项商品是一对一或一对多的关系。如果用关系数据库来描述的话,需要在表示单项商品的表中添加一个字段作为外键,引用到订单的主键。在 CouchDB 中,一般来说有两种方式可以描述。第一种方式是把相关的实体内嵌在主文档中。如在表示某个订单的文档,可以有一个字段是用来表示其中包含的单项商品,如代码清单 5 所示。不过这种方式只适用于相关的实体数量比较少的情况,否则的话,会导致文档过大而影响性能。另外一种方式是用分开的文档来表示这两种实体,并在其中一个文档中添加一个字段,其值是另外一个文档的 ID 。这种做法类似于关系数据库中的外键引用方式。代码清单 5 中也给出了使用这种方式表示的订单和单项商品的文档。


清单 5. 描述一对多关系
// 用内嵌文档描述一对多关系
 { 
  "_id" : "order001", 
  "type" : "order", 
  "username" : "Alex", 
  "created_at" : "Tue Jun 02 2009 21:49:00 GMT+0800", 
  "line_items":[ 
    { 
	  "name" : " 杜拉拉升职记 ", 
	  "price" : "17.7", 
	  "quantity" : 1 
	 }, 
    { 
	  "name" : " 狼图腾 ", 
	  "price" : "24", 
	  "quantity" : 2 
	 } 	
  ] 
 } 

 // 用分开的文档描述一对多关系
 { 
  "_id" : "order001", 
  "type" : "order", 
  "username" : "Alex", 
  "created_at" : "Tue Jun 02 2009 21:49:00 GMT+0800" 
 } 
 { 
  "_id" : "line_item_001", 
  "order_id" : "order001", 
  "name" : " 杜拉拉升职记 ", 
  "price" : "17.7", 
  "quantity" : 1 
 } 
 { 
  "_id" : "line_item_002", 
  "order_id" : "order001", 
  "name" : " 狼图腾 ", 
  "price" : "24", 
  "quantity" : 2 
 }

描述多对多关系

最后一个场景是描述多对多的关系。在关系数据库中,实体之间的多对多关系一般是通过额外的关联表来实现的。比如一个典型的场景是应用中“注册用户”与“角色”之间的关系,一个用户可以同时具备多个角色,一个角色也可以同时有多个用户。在关系数据库中,用户和角色都各自用一张表来描述,它们之间的关联关系存放在另外一张表中,该表包含用户和角色的外键引用与其它附加信息。 CouchDB 中有两种方式来描述多对多关系。第一种类似于一对多关系中的内嵌文档方式,只是内嵌的不是文档本身,而只是文档的 ID 。第二种做法类似于关系数据库中的关联表,使用一个额外的关联文档来描述关系。代码清单 6 中给出了使用这两种做法描述用户和角色的实例。


清单 6. 描述多对多关系
// 用内嵌文档 ID 描述多对多关系
 { 
  "_id" : "user1", 
  "username" : "Alex", 
  "email" : "alexcheng1982@gmail.com", 
  "roles":["db_admin","backup_admin"] 
 } 
 { 
  "_id" : "db_admin", 
  "name" : " 数据库管理员 ", 
  "priority" : 2 
 } 

 // 用关联文档描述多对多关系
 { 
  "_id" : "user1", 
  "username" : "Alex", 
  "email" : "alexcheng1982@gmail.com" 
 } 
 { 
  "_id" : "db_admin", 
  "name" : " 数据库管理员 ", 
  "priority" : 2 
 } 
 { 
  "_id" : "user_role_001", 
  "user_id" : "user1", 
  "role_id" : "db_admin" 
 }

上面说明了如何在 CouchDB 中使用文档来对一些典型的应用场景进行建模。下面将介绍开发 Web 应用的具体内容。





实战开发

开发 Web 应用

CouchDB 不仅是一个数据库服务器,同时也是一个应用服务器。在前面对 REST API 的介绍中,说明了如何把 CouchDB 作为一个数据库服务器来使用。下面将介绍如何将 Web 应用运行在 CouchDB 上。

由于 CouchDB 的 REST API 使用 JSON 作为展现形式,因此使用 CouchDB 的 Web 应用只需要编写浏览器端的代码就可以使用 JavaScript 与 CouchDB 进行交互;而 CouchDB 所支持的附件功能,又使得浏览器端的 HTML、JavaScript 和 CSS 代码可以直接存放在 CouchDB 中。这样 CouchDB 中不但保存了 Web 应用的数据,也保存了 Web 应用的逻辑。也就是说,只需要 CouchDB 就可以构建一个完整的 Web 应用运行环境。

在 CouchDB 中,一个 Web 应用对应的是一个设计文档。这个 Web 应用可以操作 CouchDB 中保存的文档型数据。当需要创建新的 Web 应用的时候,只需要创建新的设计文档即可。 CouchDB 使得 Web 应用的部署和管理变得非常简单,只需要通过 REST API 管理设计文档即可。从更大的角度来说,CouchDB 有可能创造一种新的 Web 应用开发模式。在这种模式中,CouchDB 中保存的文档型数据可以为每个应用开发者所使用,开发者在数据之上创建满足各种需求的 Web 应用。

本文中将以一个具体的小型网站作为实例来介绍使用 CouchDB 开发 Web 应用中的细节。该网站是一个类似“豆瓣”的用户点评网站。在该网站中用户可以对图书进行编辑和评价。

使用 CouchApp

CouchApp 是一个开发使用 CouchDB 的 Web 应用的小型框架。它的主要功能是可以把一个文件系统的目录转换成 CouchDB 中的一个设计文档。在开发的时候,可以按照一般 Web 应用的结构来组织文件系统,当需要测试和部署的时候,只需要一条命令就可以把该目录保存到 CouchDB 中。 CouchApp 目前有 Python 和 Ruby 两种语言的版本,本文中使用的是 Python 版本。由于目前 CouchApp 正在开发中,所以最好是从源代码安装。代码清单 7 中给出了 CouchApp 的安装脚本。


清单 7. CouchApp 安装脚本
sudo apt-get install git 
 git clone git://github.com/jchris/couchapp.git 
 cd couchapp 
 python setup.py build 
 sudo python setup.py install

时间:2009-08-07 09:10 来源:developerWorks 中国 作者:成 富 原文链接

好文,顶一下
(3)
100%
文章真差,踩一下
(0)
0%
------分隔线----------------------------


把开源带在你的身边-精美linux小纪念品
无觅相关文章插件,快速提升流量