6

簡単な例を挙げましょう。注文とショッピング カートがあります。これを永続化する方法の 1 つは、Order ドキュメントと Cart ドキュメントを保存することです。Order ドキュメントには、関連するカート ドキュメントの UUID を値とする「shopping-cart」というフィールドを含めることができます。これを行うもう 1 つの方法は、カート全体の連想配列を含む「ショッピング カート」フィールドを含む注文ドキュメントを保存することです。つまり、カートを独立したドキュメントとして明示的に保存する代わりに、カート ドキュメントを注文ドキュメントに埋め込みます。

Cart を永続化する必要があると後で決定した場合はどうなるでしょうか。両方の方法を組み合わせて、カートが不完全な間は別々に保ち、確定/購入されたときに注文ドキュメントに埋め込むことができると思います。

CouchDB に外部キー制約がないことを心配していますが、どちらの方法も機能します。最初の方法では、カート ドキュメントが削除され、破損したデータ セットが残る可能性があります。

どの方法を使用するかをどのように決定しますか? これらの方法の 1 つは、CouchDB にとってより慣用的なものですか? 私が見逃した方法はありますか?

私はCouchDBを初めて使用するので、多かれ少なかれ正規化された構造を持つことの利点/欠点を理解するのは困難です。

4

2 に答える 2

4

一方、それらが 1 対 1 でない場合は、複雑なキーを使用して、ビューの照合を使用して結合を行うことができます。

function(doc) {
  if (doc.type == 'order') {
    emit([doc.cartid, 1], doc);
  } else if (doc.type == 'cart') {
    emit([doc.id, 0], doc);
  }
}

ドキュメントは、cartid によって、カートの後に来る注文と照合されます。アプリケーション コードはこのストリームに簡単に参加でき、startkey と endkey を使用して特定の carid でクエリを実行できます。

参照:照合規則については、照合を表示します。

reduce を使用してそれらを結合することもできます。

map 関数を次のように変更するだけです。

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

これは、carid、注文ドキュメントの配列、およびカート ドキュメントであるカートごとに 1 つのドキュメントを返します。

上記のコードにエラーがある場合は申し訳ありませんが、それらを試すのに便利なcouchdbテストインスタンスがありません. ただし、一般的なアイデアは理解できるはずです。詳細については、CouchDB wiki を参照してください。

于 2009-11-05T02:50:10.193 に答える
0

Order オブジェクトと Cart オブジェクトが 1 対 1 の関係にある場合 (そのように聞こえます)、2 番目のアプローチが最も理にかなっています。関連するオブジェクトを 1 つに保持するだけです。これにより、探しているデータの整合性が得られ、簡単になります;-)

于 2009-11-04T14:33:10.270 に答える