【发布时间】:2010-12-29 09:24:21
【问题描述】:
我是 CouchDB 的新手,正在学习它。我没有遇到 CouchDB 对引用完整性的支持。 我们可以为 CouchDB 文档中的字段创建外键吗?
例如是否可以确保订单文档中使用的供应商名称在供应商数据库中可用?
CouchDB 是否支持参照完整性? 是否可以将文档中的字段设置为主键?
【问题讨论】:
标签: couchdb referential-integrity
我是 CouchDB 的新手,正在学习它。我没有遇到 CouchDB 对引用完整性的支持。 我们可以为 CouchDB 文档中的字段创建外键吗?
例如是否可以确保订单文档中使用的供应商名称在供应商数据库中可用?
CouchDB 是否支持参照完整性? 是否可以将文档中的字段设置为主键?
【问题讨论】:
标签: couchdb referential-integrity
不,CouchDB 本身不做外键,所以你不能让它为你处理系统的引用完整性。您需要在应用程序级别处理供应商检查。
至于是否可以将字段设置为主键,主键是_id字段,但是可以使用任何有效的json作为db上视图的键。因此,例如,您可以创建以供应商为键的订单视图。
类似
function(doc) {
if (doc.type == 'order')
emit(doc.vendor,doc);
}
将抓取数据库中具有类型属性和值顺序的所有文档,并使用它们的供应商作为键将它们添加到视图中。
【讨论】:
这些问题是非常具体的关系数据库。
在 CouchDB 或任何其他非 RDBMS 中,您不会像在 RDBMS 中那样存储数据,因此以这种方式设计关系可能不是最好的。但是,为了让您了解如何执行此操作,假设您有一份供应商文档和一堆需要“关联”回供应商文档的订单文档。
没有主键,文档有一个 _id,它是一个 uuid。如果您有供应商的文档,并且要为订单等内容创建新文档,则可以参考供应商文档 _id。
{"type":"order","vendor-id":"asd7d7f6ds76f7d7s"}
要查找特定供应商的所有订单,您将有一个类似的地图视图:
function(doc) { if (doc.type == 'order') {emit(doc['vendor-id'], doc)}}
文档 _id 不会更改,因此即使您更改了供应商文档上的其他属性(例如他们的姓名或帐单信息),也不会更改“完整性”。如果您将供应商文档中的供应商名称或其他属性直接粘贴到订单文档中,如果您想批量更改它们,则需要编写一个脚本。
希望能有所帮助。
【讨论】:
虽然无法创建 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?
【讨论】: