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. 描述一对多关系

 

 

描述多对多关系

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

清单 6. 描述多对多关系

 

 

posted on 2019-12-03 00:40  huangzhihao  阅读(834)  评论(0编辑  收藏  举报