我是CouchDB的新手并且了解它。我没有遇到CouchDB对参照完整性的支持。 我们可以在CouchDB文档中为字段创建外键吗?
例如是否可以确保供应商数据库中提供订单文档中使用的供应商名称?
CouchDB是否支持参照完整性? 是否可以将文档中的字段设为主键?
答案 0 :(得分:11)
不,CouchDB不会这样做外键,所以你不能让它为你处理系统的参照完整性。您需要在应用程序级别处理供应商检查。
至于是否可以将字段设为主键,主键是_id字段,但您可以使用任何有效的json作为db上视图的键。因此,例如,您可以创建一个以供应商为关键字的订单视图。
类似
function(doc) {
if (doc.type == 'order')
emit(doc.vendor,doc);
}
将获取数据库中具有值顺序的type属性的所有文档,并使用其供应商作为键将它们添加到视图中。
答案 1 :(得分: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 :(得分:0)
虽然无法创建FK约束,但可以使用Couch的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?