Как я могу избежать дублирования данных в базе данных документов, как RavenDB?

учитывая, что базы данных документов, такие как RavenDB, являются нереляционными, как избежать дублирования данных, которые имеют несколько документов? Как вы поддерживаете эти данные, если их можно дублировать?

2 ответов


с базой данных документов вы должны дублировать свои данные в некоторой степени. Что это за степень, будет зависеть от вашей системы и вариантов использования.

например, если у нас есть простой блог и пользовательские агрегаты, мы могли бы настроить их как:

  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 со свойствами Id и Name пользовательской совокупности, связанной с блогом. Я включил эти поля, поскольку они являются единственными полями класса Blog интересно, что ему не нужно знать имя пользователя или пароль пользователя при отображении блога.

эти вложенные классы будут зависеть от ваших вариантов использования систем, поэтому вы должны тщательно их проектировать, но общая идея заключается в том, чтобы попытаться создать агрегаты, которые могут быть загружены из базы данных с одним чтением, и они будут содержать все данные, необходимые для их отображения или управления ими.

Это затем приводит к вопросу о том, что происходит, когда пользователь.Имя обновляется.

С большинством баз данных документов вам придется загрузить все экземпляры блога, которые принадлежат обновленному пользователю, и обновить блог.Блогер.Имя поля и сохранить их все обратно в базу данных.

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 использует шаблон единицы работы, и поэтому это действительно должно произойти где-то вне этого метода.


нет ни одного "правильного" ответа на ваш вопрос ИМХО. Это действительно зависит от того, насколько изменчивы данные, которые вы дублируете.

посмотри документация RavenDB для многих ответов о дизайне БД документов против реляционных, но, в частности, ознакомьтесь с разделом" управление ассоциациями"Конструктивные Соображения Структуры Документа документ. Короче говоря, document DBs используют понятия ссылки по идентификаторам, когда они не хотят встраивать общие данные в документе. Эти идентификаторы не похожи на FKs, они полностью зависят от приложения для обеспечения целостности и разрешения.