3

ログ分析アプリケーションを作成しているとしましょう。メインドメインオブジェクトはLogEntryになります。加えて。アプリケーションのユーザーは、関心のあるログエントリを説明するLogTopicを定義します。アプリケーションはログエントリを受信すると、それらをcouchDBに追加し、システム内のすべてのLogTopicsと照合して、トピックの基準に一致するかどうかを確認します。 。その場合、システムはエントリがトピックに一致することを記録する必要があります。したがって、LogEntriesとLogTopicsの間には多対多の関係があります。

これをRDBMSに保存する場合は、次のようにします。

CREATE TABLE Entry (
 id int,
 ...
)

CREATE TABLE Topic (
 id int,
 ...
)

CREATE TABLE TopicEntryMap (
 entry_id int,
 topic_id int
)

CouchDBを使用して、私は最初に2つのドキュメントタイプだけを試してみました。LogEntryタイプがあり、次のようになります。

{
  'type': 'LogEntry',
  'severity': 'DEBUG',
  ...
}

LogTopicタイプがあり、次のようになります。

{
  'type': 'LogTopic',
  'matching_entries': ['log_entry_1','log_entry_12','log_entry_34',....],
  ...
}

matching_entries各LogTopicドキュメントのフィールドを使用してLogEntryドキュメントIDのリストを格納することにより、関係を表していることがわかります。これはある程度までは正常に機能しますが、複数のクライアントが両方とも一致するエントリをトピックに追加しようとすると問題が発生します。どちらも楽観的な更新を試み、一方は失敗します。私が現在使用している解決策は、基本的にRDBMSアプローチを再現し、次のような3番目のドキュメントタイプを追加することです。

{
  'type':'LogTopicToLogEntryMap',
  'topic_id':'topic_12',
  'entry_id':'entry_15'
}

これは機能し、同時更新の問題を乗り越えますが、2つの予約があります。

  1. リレーショナルDBで行うので、このアプローチを使用しているだけだと心配しています。もっとcouchDBのような(リラックスできる?)ソリューションがあるのだろうか。
  2. ビューは、1回の呼び出しで特定のトピックのすべてのエントリを取得できなくなりました。以前のソリューションではそれが可能でした(include_docsパラメーターを使用した場合)。

誰かが私のためのより良い解決策を持っていますか?使用しているビューも投稿すると役に立ちますか?

4

3 に答える 3

11

私はこの質問をcouchdbユーザーのメーリングリストに相互投稿しま​​した.Nathan StottはChristopher Lenzによる非常に役立つブログ投稿を教えてくれました.

于 2009-12-01T03:25:00.453 に答える
4

あなたのアプローチは問題ありません。CouchDB を使用しても、リレーショナル モデリングを放棄するわけではありません。2 つのクエリを実行する必要がありますが、これは「結合」であるためです。結合を含む SQL クエリも低速ですが、SQL 構文を使用すると、クエリを 1 つのステートメントで表現できます。

CouchDB を数か月使用した経験で、次のことがわかりました。

  1. スキーマがないため、アプリケーション モデルを迅速かつ柔軟に設計できます
  2. CRUD があるため、アプリケーションを迅速かつ柔軟に開発できます
  3. さようならSQLインジェクション
  4. CouchDB での SQL 結合とは、もう少し作業が必要です。

必要に応じて、より複雑なクエリを作成するのにcouchdb-luceneも役立つことがわかりました。

于 2009-12-01T01:21:49.077 に答える
0

LogEntry がどの LogTopics に属しているかを認識できるように、関係を設定してみます。そうすれば、LogTopics を変更する必要がないため、LogEntry を挿入しても競合が発生しません。

次に、単純なマップ関数が、属する LogTopic ごとに 1 回 LogEntry を発行し、基本的に TopicEntryMap をオンザフライで構築します。

"map": function (doc) {
    doc.topics.map(function (topic) {
        emit(topic, doc);
    });
}

このように、引数を使用してビューをクエリする?key=<topic>と、トピックに属するすべてのエントリが得られます。

于 2010-08-13T12:25:23.200 に答える