Вопрос моделирования для RavenDB (или других баз данных, ориентированных на doc)

#nosql #ravendb

#nosql #ravendb

Вопрос:

Интересно, как некоторые из более опытных (или те, у кого есть идеи получше, чем у меня) справились бы с моим конкретным сценарием моделирования…

У меня есть типичный сценарий «Категория -> Подкатегория -> Третья категория», и я не уверен, правильно ли я его отображаю. Я сопоставляю это непосредственно с маршрутом MVC, поскольку raven, похоже, хорошо справляется с этим. Под конечной категорией (которая может быть на первом, 2-м или 3-м уровнях) будет список элементов, связанных только с этим уровнем категории. Итак, у нас может быть что-то вроде:

Категория одного уровня: ‘/ Politics /’

Категория второго уровня: «Политика / люди» или «Политика / веб-сайты»

Трехуровневая категория: «Спорт / профессионал / волейбол» или «Спорт / Колледж / Футбол»

В традиционной СУБД это легко сделать с помощью первичных / внешних ключей нескольких объединений … итак, интересно, как бы я справился с Raven?

Из того, что я прочитал, должен ли я хранить URI или ключ ‘sports / pro / volleyball’ целиком в списке элементов, которые подпадают под него?

т. е. —

 public class CategoryItem
{
     public string FriendlyName {get;set;} // Volleyball or Pro Volleyball
     public string CategoryURI {get;set;}  // i.e. - "/sports/pro/volleyball/"
     public string content {get;set;}  // i.e. - "Who is the best Pro Volleyball Athlete?"
     public List<string> Comments {get;set;}
}

// then we could store something like this:

var survey1 = new CategoryItem();
survey1.CategoryURI = "/sports/pro/volleyball/"
survey1.Content = "Who is the best female pro volleyball player?";
survey1.Comments.Add(new Comment("Misty May"));

var survey2 = new CategoryItem();
survey2.CategoryURI = "/sports/pro/volleyball/";
survey2.Content = "Who is the best male pro volleyball player?";
survey2.Comments.Add(new Comment("Some guy I don't kow");

// asuumes ravenSession was alreadyopened... 
ravenSession.Store(survey1);
ravenSession.Store(survey2);
ravenSessoin.SaveChanges();


//{ ...... etc .....  }
//Then I can query by CategoryURI without needing joins (denormalization)....  i.e. - 

var items = session.Query<CategoryItem>()
                 .Where(x => x.CategoryURI == "/sports/pro/volleyball/");
  

Или я должен создать элемент списка элементов фактического класса category? У каждого элемента будет список собственных комментариев … это означает, что все хранится в одном документе в Raven — т. Е. —

 public class Category
{
    public string FriendlyName {get;set;} // i.e. - "Volleyball" or "Pro Volleyball"
    public string URI {get;set;}  // i.e. -  "/sports/pro/volleyball"  which is the MVC path
    public List<CategoryItem> Items {get;set;}
}

public class CategoryItem
{
     public string Content {get;set;}
     public List<string> Comments {get;set;}
}

var vballCat = new Category();
vballCat.FriendlyName = "Pro Volleyball";
vballCat.URI = "/sports/pro/volleyball/";  // equivalent to the MVC route

var catItem = new CategoryItem().
catItem.Content = "Who is the best male pro volleyball player?";
catItem.Comments.Add("Misty May");
catItem.Comments.Add("Some Guy 1");
vballCat.Items.Add(catItem);

ravenSession.Store(vballCat);
ravenSession.SaveChanges();
  

….. теперь, как только я извлеку основной cat, т. Е. — «/ sports / pro / volleyball /» У меня уже есть все, что мне нужно, в нем

 var items = session.Query<Category>()
                 .Where(x => x.URI == "/sports/pro/volleyball/");
  

{ …………. и т. д …………… }

Теперь здесь я могу просто выполнить итерацию по коллекции Items и ее коллекции комментариев …. использует ли это быструю загрузку? Что, если бы у меня был миллион комментариев под одним элементом категории? Когда я загружу основную категорию, она также загрузит все миллион комментариев !?!?

Я был бы признателен за любую помощь, которую вы можете предоставить. Извините, если этот пример / вопрос неясен… Я постараюсь что-нибудь прояснить, если вам, ребята, это нужно. Еще раз спасибо!

Ответ №1:

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

Еще одна вещь, которую следует помнить, это то, что запрос по идентификатору обычно выполняется быстрее, чем выполнение запроса. Это означает, что если у вас есть идентификаторы, которые уже очень похожи на идентификаторы документов, вы могли бы также СДЕЛАТЬ их идентификаторами документов.

Комментарии:

1. Хорошо, имеет смысл. Итак, во 2-м примере, допустим, у меня есть категория с 500 элементами, каждая с 500-1000 комментариями, что составляет в общей сложности 250-500 тыс… что вы думаете? Использовать первый вариант?