2016-02-29 4 views
0

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

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

Idea 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; } 
} 

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

ответ

0

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

Я лично рекомендовал бы первую идею, потому что вам не нужно обновлять существующие документы, когда некоторые данные изменяются в записях пользователя. Использование include on query/load time - довольно приятная функция ravendb, которая может помочь вам при извлечении вложенных записей из базы данных. Просто убедитесь, что вы не забудьте включить все вложенные документы - иначе вы можете получить много обращений.

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