代码之家  ›  专栏  ›  技术社区  ›  Robert Campbell

在CouchDB中实现外键的惯用方法是什么?

  •  6
  • Robert Campbell  · 技术社区  · 16 年前

    让我举一个简单的例子:你有订单和购物车。我设想的一种持久化方法是保存订单文档和购物车文档。订单文档可以有一个名为“购物车”的字段,其值是相关购物车文档的UUID。我可以想象的另一种方法是使用包含整个购物车关联数组的“购物车”字段保存订单文档。换句话说,我没有将购物车显式地保存为独立文档,而是将购物车文档嵌入到订单文档中。

    虽然我担心CouchDB没有外键约束,但这两种方法都可以工作;在第一种方法中,可以删除购物车文档,从而留下损坏的数据集。

    你如何决定使用哪种方法?这些方法中有一种对CouchDB更惯用吗?我错过了什么方法吗?

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

    2 回复  |  直到 16 年前
        1
  •  4
  •   haim770    13 年前

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

    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);
      }
    }
    

    并添加一个reduce函数,如下所示:

    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;
    }
    

    如果上面的代码中有错误,我深表歉意,但我手头没有couchdb测试实例来尝试它们。不过,您应该了解总体思路,CouchDB wiki有更多细节。

        2
  •  0
  •   Joel Martinez    16 年前

    如果订单和购物车对象有一对一的关系(听起来就是这样),那么第二种方法最有意义。。。只需将关联对象包含在一个文件中即可。这为您提供了所需的数据完整性并使其变得简单;-)