6

RavenDBなどのドキュメントデータベースが非リレーショナルであるとすると、複数のドキュメントに共通するデータの重複をどのように回避しますか?複製しても問題がない場合、そのデータをどのように維持しますか?

4

2 に答える 2

12

ドキュメントデータベースでは、データをある程度複製する必要があります。その程度は、システムとユースケースによって異なります。

たとえば、単純なブログとユーザー集計がある場合、次のように設定できます。

  public class User 
  {
    public string Id { get; set; }
    public string Name  { get; set; }
    public string Username  { get; set; }
    public string Password  { get; set; }
  }

  public class Blog
  {
     public string Id  { get; set; }
     public string Title  { get; set; }

     public class BlogUser
     {
       public string Id  { get; set; }
       public string Name  { get; set; }
     }
  }

この例では、BlogUserクラスをBlogクラス内にネストし、Blogに関連付けられたUserAggregateのIdプロパティとNameプロパティを使用しています。これらのフィールドはブログクラスが関心を持っている唯一のフィールドであり、ブログが表示されているときにユーザーのユーザー名やパスワードを知る必要がないため、これらのフィールドを含めました。

これらのネストされたクラスはシステムのユースケースに依存するため、慎重に設計する必要がありますが、一般的な考え方は、1回の読み取りでデータベースからロードでき、必要なすべてのデータを含む集計を設計することです。それらを表示または操作します。

これにより、User.Nameが更新されたときに何が起こるかという問題が発生します。

ほとんどのドキュメントデータベースでは、更新されたユーザーに属するBlogのすべてのインスタンスをロードし、Blog.BlogUser.Nameフィールドを更新して、それらをすべてデータベースに保存する必要があります。

Ravenは、更新の集合関数をサポートしているため、わずかに異なります。そのため、RavenDBに対して単一の更新を実行できます。これにより、ユーザーのブログのBlogUser.Nameプロパティが更新され、それらをすべて個別にロードして更新する必要がなくなります。

すべてのブログのRavenDB内で(手動で)更新を行うためのコードは次のようになります。

  public void UpdateBlogUser(User user)
  {
    var blogs = session.Query<Blog>("blogsByUserId")
                  .Where(b.BlogUser.Id == user.Id)
                  .ToList();

    foreach(var blog in blogs)
       blog.BlogUser.Name == user.Name;

    session.SaveChanges()
  }

例として、SaveChangesに追加しました。RavenDBクライアントは作業単位パターンを使用するため、これは実際にはこのメソッド以外の場所で発生するはずです。

于 2010-06-08T13:03:17.600 に答える
2

私見の質問に対する「正しい」答えはありません。それは、複製するデータがどれだけ可変であるかに本当に依存します。

ドキュメントDBの設計とリレーショナルに関する多くの回答については、RavenDBのドキュメントを参照してください。ただし、ドキュメント構造の設計に関する考慮事項ドキュメントの「関連付けの管理」セクションを具体的に確認してください。つまり、ドキュメントDBは、共有データをドキュメントに埋め込みたくない場合に、IDによる参照の概念を使用します。これらのIDはFKとは異なり、完全性を確保して解決するのは完全にアプリケーション次第です。

于 2010-06-05T22:00:33.017 に答える