2009-11-04 55 views
6

让我举个简单的例子:你有一个订单和一个购物车。我设想的一种方法是保存订单文档和购物车文档。订单文件可以有一个称为“购物车”的字段,其值是相关购物车文档的UUID。另一种我能想象得到的方式是使用包含整个购物车关联数组的“购物车”字段来保存订单文档。换句话说,我没有将购物车明确地保存为独立文件,而是将购物车文件嵌入到订单文件中。在CouchDB中实现外键的习惯用法是什么?

如果我们以后决定购物车应该是持久性的,那么返回的用户会发现他的半成品购物车在各个会话期间等着他呢?我想我们可以结合使用这两种方法,在不完整的情况下保持购物车分离,并在订单/购买时将其嵌入到订单文档中。

这两种方法都行得通,但我担心CouchDB没有外键约束;在第一种方法中,购物车文档可能被删除,给您一个损坏的数据集。

你如何决定使用哪种方法?这些方法之一对CouchDB更习惯吗?有没有我错过的方法?

我是CouchDB的新手,所以我很难看到具有或多或少规范化结构的优点/缺点。

回答

4

如果另一方面它们不是一对一的,那么使用复杂键可以使用视图归类来进行联接。

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维基有更多详细信息。

0

如果Order和Cart对象具有一对一的关系(这就是它的声音),那么第二种方法最有意义......只是将关联对象保存在一个关系中。这样可以提供所需的数据完整性并使其变得简单;-)

相关问题