Реляционная модель RavenDB

Я работаю над побочным проектом по созданию форума, построенного поверх RavenDB. В настоящее время я пытаюсь выяснить отношения между авторами тем и пользователем «Последний ответ» в теме. В типичной реляционной модели я бы просто сохранил FK для пользователя, опубликовавшего тему, и присоединился к таблице ответов, чтобы получить автора самых последних ответов. Очевидно, что это не вариант использования Raven или любого другого хранилища документов.

Что было бы наиболее «оптимальным» способом осуществить это? В настоящее время я подбрасываю пару идей.

Идея 1: Сохраните FK автора в модели темы, добавьте объект JsonIgnored User, который я буду заполнять при загрузке темы, используя Include в моей загрузке сеанса (поэтому один запрос со стороны клиента просто делает загрузку сама и модель немного сложная). Затем, возможно, используйте индекс уменьшения карты, чтобы получить автора самых последних ответов (или даже тот же метод, что и получение автора темы, поэтому в зависимости от 1 или 2 запросов).

Идея 2: Сохранение в модели как автора, так и последнего ответившего пользователя. Основная «проблема» здесь — возможность устаревших данных (скажем, при изменении имени пользователя). Однако потенциально это можно облегчить с помощью фоновой задачи (или просто помнить об этом при обновлении пользовательского документа и возврате ко всем сообщениям от пользователя).

Пример рассматриваемых моделей.

public class User
{
    public string Id { get; set; }
    public string UserName { get; set; }
    public string PasswordHash { get; set; }
}

public class Topic
{
    public string Id { get; set; }
    public string Title { get; set; }
    public string Body { get; set; }

    // Idea 1 Relationships
    public string AuthorId { get; set; }
    [JsonIgnore]
    public User Author { get; set; } // Would need to be populated on loads from an Include on AuthorId
    public string MostRecentReplyUserId { get; set; }
    [JsonIgnore]
    public User MostRecentReplyUser { get; set; } // Same as Author

    // Idea 2 Relationships
    public User Author { get; set; }
    public User MostRecentReplyUser { get; set; }
}

Примечание. Я бы, скорее всего, добавил в модель User метод, возвращающий «чистую» версию, в которой я удалял бы такие вещи, как PasswordHash, и использовал бы их в Save for Idea 2.


person Justin Packwood    schedule 29.02.2016    source источник


Ответы (1)


В зависимости от ваших потребностей в случае обновления и производительности запросов оба способа могут быть лучшим выбором.

Лично я бы порекомендовал первую идею, потому что вам не нужно обновлять существующие документы, когда некоторые данные изменяются в пользовательских записях. Использование включения во время запроса/загрузки — довольно приятная функция ravendb, которая может помочь вам при извлечении вложенных записей из базы данных. Просто убедитесь, что вы не забыли включить все вложенные документы, иначе вы можете получить много обращений туда и обратно.

Встраивание документов (например, идея 1, но с сохраненным значением пользователей) может быть лучше, если ваша обработка данных отделена от извлечения данных, и у вас нет доступа к сеансу базы данных при преобразовании данных для передачи во внешний интерфейс. Мы используем такую ​​систему, которая в значительной степени зависит от этого (получение одного ввода и отображение подвески json значения) — это полностью отделяет логику извлечения данных от логики вывода (например, сопоставления с json). Недостаток здесь: вы должны убедиться, что существующие (встроенные) данные обновляются всякий раз, когда пользователь меняется, а данные, которые передаются по сети, больше, чем в идее 1.

person Daniel Nachtrub    schedule 01.03.2016