Нормализация MongoDB, внешний ключ и присоединение

Прежде чем погрузиться в MongoDB в глубокие времена, я подумал, что задаю довольно простой вопрос о том, нужно ли вообще погрузиться в него или нет. У меня нет опыта работы с nosql.

Я немного читал о некоторых преимуществах баз данных документов, и я думаю, что для этого нового приложения они будут действительно замечательными. Это всегда хлопот, чтобы делать фавориты, комментарии и т.д. Для многих типов объектов (много отношений m-to-m) и подклассов - это своего рода боль, с которой приходится иметь дело.

У меня также есть структура, которая будет больно определять в SQL, потому что она чрезвычайно вложенна и переводит на документ намного лучше, чем 15 разных таблиц.

Но я смущен несколькими вещами.

  • Желательно, чтобы ваша база данных была нормализована? Я действительно не хочу обновлять несколько записей. Это все еще, как люди подходят к дизайну базы данных в MongoDB?

  • Что происходит, когда пользовательские избранные книги и этот выбор все еще хранятся в пользовательском документе, но затем книга удаляется? Как отношения отделяются без внешних ключей? Я лично отвечаю за удаление всех ссылок?

  • Что произойдет, если пользователь воспользовался книгой, которая больше не существует, и я запрашиваю ее (какое-то соединение)? Должен ли я делать какую-либо отказоустойчивость здесь?

Ответ 1

MongoDB не поддерживает отношения внешнего ключа на стороне сервера, нормализация также не рекомендуется. Вы должны встроить свой дочерний объект в родительские объекты, если это возможно, это увеличит производительность и сделает ненужные внешние ключи. Тем не менее, это не всегда возможно, поэтому существует специальная конструкция под названием DBRef, которая позволяет ссылаться на объекты в другой коллекции. Это может быть не так быстро, потому что БД приходится делать дополнительные запросы для чтения объектов, но позволяет использовать ссылку на внешний ключ.

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

Если ваша схема более сложная, то, вероятно, вы должны выбрать реляционную базу данных, а не nosql.

Существует также книга о разработке баз данных MongoDB: Document Design for MongoDB

ОБНОВЛЕНИЕ Книга выше недоступна, но из-за популярности MongoDB их довольно много. Я не свяжу их всех, так как такие ссылки могут измениться, простой поиск на Amazon показывает несколько страниц, поэтому не должно быть проблем, чтобы найти некоторые.

Подробнее см. страницу руководства MongoDB для "Ссылки вручную" и DBRefs для получения дополнительных сведений и примеров

Ответ 2

Выше, @TomaaszStanczak утверждает

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

Нормализация не обескураживается Монго. Чтобы быть ясным, мы говорим о двух принципиально разных типах отношений, которые могут иметь два объекта данных. В одном из одного дочернего объекта принадлежит исключительно родительский объект. В этом типе отношений монгольский способ заключается в встраивании.

В другом классе отношений два сущности существуют независимо - имеют независимые времена жизни и отношения. Монго хочет, чтобы такого рода отношения не существовало, и он с трудом молчит о том, как справиться с этим. Встраивание - это просто не решение. Нормализация не обескуражена или не поощряется. Монго просто дает вам два механизма борьбы с ним; Manual refs (аналогично ключу с ограничением внешнего ключа, связывающим две таблицы) и DBRef (другой, немного более структурированный способ сделать то же самое). В этом случае используются базы данных SQL.