1

私はページ階層(mongodbドキュメント)に取り組んでいます:

{
    _id: 012,
    content: "lorem ipsum whatever...",
    subpages: [123,234,345,456], // page ids
}

ページ構造は実際には非常に動的であるため、多くの更新が多くの読み取りと同時に発生します。ただし、すべての変更(サブページを別のページに移動するなど)には、少なくとも2つの更新操作が必要です。

// move 123 into page 234
db.pages.update({"_id":012}, {$pull:{"subpages":123}});
db.pages.update({"_id":234}, {$push:{"subpages":123}});

// delete page 345
db.pages.update({"_id":012}, {$pull:{"subpages":345}});
db.pages.remove({"_id":345});

ページの移動やページのアトミックな削除(階層の状態が悪くなるのを防ぐため)などの操作を実行する(または実行できるようにモデルを設計する)方法はありますか?

ノート

私が今見ている可能性の1つは、トランザクションIDを含むすべてのページに「lockedBy」フィールドを追加してドキュメントを手動でロックすることです。ただし、最初のロック操作が完了するまで2番目のロック操作をブロックする場合は、継続的にポーリングするというアイデアは好きではありません(https://jira.mongodb.org/browse/SERVER-2244を参照)。また、ロックはアプリケーションによって管理されるため、ロック操作中に何らかの理由でアプリケーション(またはその1つのインスタンス)がダウンした場合、他のトランザクションに影響を与えることなく、何らかの方法でドキュメントのロックを解除する必要があります。

http://www.mongodb.org/display/DOCS/Trees+in+MongoDBも調べましたが、どの例(単一のドキュメントを除く)でもこの問題を解決していないようです。ただし、16 MBのドキュメントサイズの制約とページの移動が難しいため、階層全体を1つのドキュメントにまとめることは避けたいと思います(基本的に、変更のたびにドキュメント全体をアップサートする必要があります)。

更新

1ページで最大10000のサブページをサポートしたいと考えています。ページのIDは少なくとも6文字の長さです。そのことを念頭に置いて、サブページの順序を追跡する必要があるため、mySQLから移行しました。mySQLには配列構造がないため、これを行う唯一の方法は、位置列を使用することです。ページが頻繁に移動する場合、平均位置を計算し、位置の値が長くなりすぎたときにインデックスを再作成するのはコストがかかります。また、IDのコンマ区切りリストを列に入れたい場合は、10000サブをサポートするために、VARCHAR(65536文字の制限がある)ではなく、TEXT列(ディスクから読み取る)を使用する必要があります。ページ。

4

1 に答える 1

2

取引はありません。アトミック操作がありますが、一度に1つのドキュメントに対してのみ操作します。信頼できる更新を行うための唯一の選択肢は、階層全体を1つのドキュメントにまとめることです。ドキュメントの制限を超えても心配する必要はありません。16MBは多くの整数です。

また、これは「通常の」リレーショナルトランザクションデータベースの方がはるかに便利な例だと思います。

于 2012-07-20T20:15:15.040 に答える