在CouchDB中实现外键的习惯用法是什么?
让我举个简单的例子:你有一个订单和一个购物车。我设想的一种方法是保存订单文档和购物车文档。订单文件可以有一个称为“购物车”的字段,其值是相关购物车文档的UUID。另一种我能想象得到的方式是使用包含整个购物车关联数组的“购物车”字段来保存订单文档。换句话说,我没有将购物车明确地保存为独立文件,而是将购物车文件嵌入到订单文件中。在CouchDB中实现外键的习惯用法是什么?
如果我们以后决定购物车应该是持久性的,那么返回的用户会发现他的半成品购物车在各个会话期间等着他呢?我想我们可以结合使用这两种方法,在不完整的情况下保持购物车分离,并在订单/购买时将其嵌入到订单文档中。
这两种方法都行得通,但我担心CouchDB没有外键约束;在第一种方法中,购物车文档可能被删除,给您一个损坏的数据集。
你如何决定使用哪种方法?这些方法之一对CouchDB更习惯吗?有没有我错过的方法?
我是CouchDB的新手,所以我很难看到具有或多或少规范化结构的优点/缺点。
如果另一方面它们不是一对一的,那么使用复杂键可以使用视图归类来进行联接。
function(doc) {
if (doc.type == 'order') {
emit([doc.cartid, 1], doc);
} else if (doc.type == 'cart') {
emit([doc.id, 0], doc);
}
}
该文档将通过Cartid进行整理,订单来自购物车之后。您的应用程序代码可以轻松加入此流,您可以使用startkey和endkey通过特定的cartid进行查询。
查看:View Collation查看排序规则。
您也可以使用reduce将它们连接在一起。
只要改变映射函数将此:
function(doc) {
if (doc.type == 'order') {
emit([doc.cartid, 1], {cartid: doc.cartid, orders: [doc]});
} else if (doc.type == 'cart') {
emit([doc.id, 0], {cartid: doc.id, orders: [], cart: doc);
}
}
,并添加减少功能是这样的:
function(keys, values) {
var out = {cartid: null, orders: [], cart: null};
for (idx in values) {
var doc = values[idx];
out['cartid'] = doc.cartid;
if (doc.cart) { out['cart'] = doc.cart };
for (idx2 in doc.orders) {
out.orders.push(doc.orders[idx2]);
}
}
return out;
}
这将每车返回一个文档,其中一个cartid,数组订购文件和购物车文件。
道歉,如果在上面的代码中有错误,但我没有一个方便的couchdb测试实例来试用它们。您应该了解一般想法,并且CouchDB维基有更多详细信息。
如果Order和Cart对象具有一对一的关系(这就是它的声音),那么第二种方法最有意义......只是将关联对象保存在一个关系中。这样可以提供所需的数据完整性并使其变得简单;-)