Отношения "многие ко многим" с базой данных NoSQL
Я хочу реализовать структуру таксономии (гео-термины) для моего узла.приложение js с базой данных NoSQL. У меня была аналогичная структура таксономии с MySQL, но пришло время двигаться вперед и узнать что-то новое, поэтому я решил попробовать другой подход и использовать NoSQL (ориентированный на документ) для моего тестового приложения. Структура таксономии проста - есть пять различных уровней: страна (то есть Великобритания) → регион (Англия) → графство (Мерсисайд) → город/городок / деревня (Ливерпуль) → часть города (Toxteth).
очевидный выбор-использовать древовидную структуру, но дьявол в деталях-исторически некоторые города и поселки принадлежали другим графствам. Идея заключалась в том, чтобы пометить людей, которые родились в определенных городах или поселках, этими терминами и фильтровать их позже по тегам geo, поэтому я должен уважать тот факт, что Ливерпуль или Манчестер (среди прочих) были частью Ланкашира в то время, когда некоторые люди родились. В противном случае результат, который получит любой пользователь с моим Geo-фильтром, будет неправильный.
пример: Джон Доу родился в Блэкберне (Ланкашир) еще в 1957 году. Пол Браун родился в 1960 году в Ливерпуле (Ланкашир, ныне Мерсисайд). Джорджия Доу (урожденная Джонс) родилась в Виррале (Чешир, ныне Мерсисайд) 5 лет спустя. Их сын Ринго родился в Ливерпуле (Мерсисайд к тому времени) в 1982 году.
Джон Ланкастер по рождению, пол Ланкастер и Мерсисидер, Джорджия из Чешира и Мерсисайда в то же время, Ринго из Мерсисайд. Поэтому их следует классифицировать соответствующим образом, когда я ищу по округам. Но с простой структурой "один ко многим", которая следует за современной структурой страны, они никогда не будут отфильтрованы так, как должны быть.
как реализовать коллекцию с учетом сложности ее структуры с помощью решений NoSQL (прежде всего, ориентированных на документы)? Я погуглил его и сделал некоторые исследования над стеком*, но все еще не знал, что с ним делать дальше. Есть несколько возможных способов решить это в моем мнение:
-
используйте SQL-подобную структуру данных:
{ {'name': 'United Kingdom', 'unique_id': 1}, {'name': 'England', 'unique_id': 2, 'parents': [1]}, {'name': 'Merseyside', 'unique_id': 3, 'parents': [2]}, {'name': 'Lancashire', 'unique_id': 4, 'parents': [2]}, {'name': 'Liverpool', 'unique_id': 5, 'parents': [3, 4]}, }
-
использовать древовидную структуру с некоторыми ссылками:
{ {'name': 'United Kingdom', 'unique_id': 1 {'name': 'England', 'unique_id': 2] {'name': 'Merseyside', 'unique_id': 3] {'name': 'Liverpool', 'unique_id': 5, 'alternate_parents': [4]}, }, {'name': 'Lancashire', 'unique_id': 4}, }, }, }
-
используйте древовидную структуру без ссылок (один ко многим) и добавьте тег" альтернативный родитель " в документ вручную:
{ {'name': 'United Kingdom', 'unique_id': 1 {'name': 'England', 'unique_id': 2] {'name': 'Merseyside', 'unique_id': 3] {'name': 'Liverpool', 'unique_id': 5}, }, {'name': 'Lancashire', 'unique_id': 4}, }, }, }
придерживайтесь SQL.
- попробуйте реализовать без базы данных таксономии.
Дайте мне совет по этому поводу вопрос пожалуйста. Я новичок с любым NoSQL (в настоящее время я не разрабатывал такие базы данных), поэтому для меня есть реальная проблема дизайна.
и я новичок в стеке* так что не стесняйтесь поправлять меня, если я сделал что-то не так с этим сообщением :) спасибо!
редактировать Я выбрал @Jonathan answer в качестве решения. Я думаю, что это лучше подходит для моих нужд (в моей базе данных будут храниться другие документы и помечать их этими терминами), особенно с функциональностью mapReduce предложено @Valentyn.
но если для вашего приложения нет коллекций документов, то графическая база данных (основанная на отношениях, а не на документах), предложенная @Philipp, вероятно, является лучшим решением.
2 ответов
во-первых, выбор между NoSQL и базой данных SQL трудно, если вы не знакомы с основными принципами. Если это единственные данные, которые вы храните, перейдите к реляционному (SQL). Если есть больше данных (что я предполагаю), и для этого требуется больше переплетенной схемы, придерживайтесь NoSQL руки вниз.
Я бы выбрал реляционный маршрут, чтобы он не стал слишком сложным... начните несколько собраний; одно для стран, региона и так далее. Не отчаивайтесь делать схемы реляционных (SQL) типов в базе данных NoSQL; в большинстве случаев они являются лучшим решением.
затем в каждой из подгрупп есть поле, которое называет родителя.
например:
{
{'name': 'United Kingdom'},
{'name': 'United States'}
}
{
{'name': 'England', 'parent': 'United Kingdom'},
{'name': 'California', 'parent': 'United States'}
}
таким образом, ваш набор данных не становится настолько вложенным, что возвращаемые данные неуправляемы. Затем вы можете захватить страны и соответствующие регионы... и т. д. с легкостью.
удачи!
EDIT: ответ на OP вопросы:
(во-первых, я бы рекомендовал MongoDB-это отличное решение для всех.)
потому что когда вы начинаете работать с MongoDB, вы поймете, что он хранит данные на жестком диске. Если вы отредактируете такую огромную запись, она, скорее всего, будет отодвинута на заднюю часть диска, что сделает ваш жесткий диск похожим на швейцарский сыр. Как только вы доберетесь до этой точки, вам придется сделать ремонт, чтобы конденсировать его еще раз. Кроме того, таким образом данные проще разделить в приложении, таким образом, если вам нужно что-то сделать с данными, вам не придется применять его ко всему объекту. Я предполагаю, что у вас будет большой набор данных, так как в мире есть много разных мест.
Не беспокойтесь слишком много о таких вещах. Вы можете использовать ID для родителя и сопоставлять детей с ID, если вы планируете много менять имена. Я сделал это так, потому что думал, что тебе это не понадобится. изменение базы данных местоположений.
-
вместо массива я бы использовал вложенный документ для хранения нескольких родителей. Таким образом, его можно легко запросить и проиндексировать. Я бы использовал следующий метод:
{ { 'name': 'England, 'parent': { 1: 1, 568: 1 } } }
таким образом, вы можете использовать свою идею индексов и найти, где db.region.$.568
= 1
из-за комментария, который вы сделали, я предполагаю, что вы имеете в виду "MongoDB", когда говорите "NoSQL". Есть много других технологий баз данных, обычно называемых NoSQL, которые полностью отличаются, но это, похоже, тот, который вы имеете в виду.
не очень хорошая идея, потому что для получения всей цепочки таксономии вам нужно будет выполнить несколько запросов к базе данных, которых обычно следует избегать.
и 3. Один документ, который является огромным дерево также не является хорошей идеей, потому что MongoDB имеет ограничение 16 Мб на документ. Когда вы создаете огромные монолитные документы, вы можете достичь этого предела.
Я думаю, что MongoDB может быть не лучшим решением для вашего варианта использования. Вы рассматривали возможность использования графическая база данных? MongoDB оптимизирован для автономных документов, которые стоят сами по себе. Но фокус баз данных график на наборах данных, где у вас есть много сущностей, которые определяются их отношения с другими субъектами. Это очень похоже на твой кейс.