2009-12-23 96 views
12

我是CouchDB的新手,并了解它。我没有遇到CouchDB对参照完整性的支持。 我们可以为CouchDB文档中的字段创建外键吗?CouchDB是否支持参照完整性?

例如,是否可以确保供应商数据库中提供订单文档中使用的供应商名称?

CouchDB是否支持引用完整性? 是否有可能在文档中将字段设置为主键?

回答

11

不,CouchDB不会像这样做外键,所以你不能让它为你处理系统的参照完整性。您需要处理应用程序级别的供应商检查。

至于是否可以使字段成为主键,主键是_id字段,但是您可以使用任何有效的json作为db上视图的关键字。因此,例如,您可以创建一个供应商订单视图作为关键。

function(doc) { 
    if (doc.type == 'order') 
    emit(doc.vendor,doc); 
} 

会抢在具有与价值秩序type属性,并将它们添加到使用其供应商的关键视图中的数据库中的所有文档。

Intro to CouchDB views

8

这些问题是令人难以置信的关系数据库特有的。

在CouchDB或任何其他非RDBMS中,您不会像存储在RDBMS中那样存储数据,因此以这种方式设计关系可能并不是最好的。但是,为了让您了解如何做到这一点,我们假设您有一份供应商文档以及一系列需要“关联”回供应商文档的订单文档。

没有主键,文档有一个_id,这是一个uuid。如果您有供应商的文档,并且您正在创建类似订单的新文档,则可以参考供应商文档_id。

{"type":"order","vendor-id":"asd7d7f6ds76f7d7s"} 

要查找所有订单为特定供应商,你将有一个地图视图类似:

function(doc) { if (doc.type == 'order') {emit(doc['vendor-id'], doc)}} 

文档_id不会改变,所以“诚信”在那里,就算你更改供应商文档上的其他属性,如其名称或账单信息。如果您将供应商名称或供应商文档中的其他属性直接粘贴到订单文档中,如果您想要批量更改它们,则需要编写脚本。

希望能有所帮助。

+2

参照完整性是做自己动手,换句话说。程序员必须记住首先创建供应商文档,然后编写引用其** __id **的项目,因为CouchDB无法为他们强制执行。同样,删除程序员在删除供应商之前必须记住自己先删除与供应商相关的订单--CouchDB不会为他们做这件事。所以CouchDB会让你不断进入不一致的状态;没有支持保护它。 – 2010-06-15 13:07:29

+0

我不会在没有提及它的“不一致状态”的情况下调用一个悬而未决的文档,因为这种情况下的状态是从其他文档中删除的引用。但是你在这里对语义的描述是准确的。引用只是索引,删除文档不会推断某些较大的事务将清理后向引用,尽管它会清除前向引用。 – mikeal 2010-06-15 22:08:07

+0

更重要的是,couchdb服务器具有REST-3能力(如果需要使用设计文档,则可以构建REST-4功能)。对于文档数据库,应用术语“参照完整性”对于视频游戏来说没有多大意义。这不是一个关系数据库,并不假装。 – 2011-07-04 12:38:03

0

虽然不可能建立一个FK约束,可以采用沙发的Validate功能

function(newDoc, oldDoc, userCtx, secObj) { 
    if(newDoc && newDoc.type) switch(newDoc.type){ 
     case 'fish': 
      var allSpecies = ['trout','goldfish']; 
      if(!allSpecies.contains(newDoc.species)){ 
       throw({forbidden : 'fish must be of a know species'}); 
      } 
      break; 
     case 'mammals': 
      if(!['M','F'].contains(newDoc.sex)){ 
       throw({forbidden : 'mammals must have their sex listed'}); 
      } 
      break; 
    } 
} 

现在,如果一个人真的很聪明(我不是),他们可能会做一个调出该数据库本身的物种清单...这将是一个外键。

您可能还需要在读了起来: How do I DRY up my CouchDB views?