Отношения - это суть любой базы данных, и отношения в базах данных NoSQL обрабатываются совершенно иначе, чем в базе данных SQL. Есть одно очень важное различие, которое вам нужно учитывать при создании базы данных NoSQL, а именно: базы данных NoSQL обычно всегда имеют JSON-подобную схему. Как только вы это усвоите, работать с отношениями станет намного проще.

Это сообщение можно отнести к категории новичков, но оно определенно полезно для всех, кто интересуется пониманием того, как отношения обрабатываются в базах данных NoSQL. Я предполагаю, что у вас есть базовое представление о том, что такое база данных, и, возможно, вы использовали хотя бы одну базу данных (SQL или NoSQL).

Если вы работаете с SQL, просто обратите внимание, что коллекция в NoSQL похожа на таблицу в SQL, а документ похож на строку в таблице.

В идеале есть 3 основных типа отношений, они указаны ниже:

Отношения один к одному

Отношение «один к одному», как следует из названия, требует, чтобы одна сущность имела исключительные отношения с другой сущностью, и наоборот. Давайте рассмотрим простой пример, чтобы лучше понять эти отношения ...

Отношения между пользователем и его учетной записью. С одним пользователем может быть связана одна учетная запись, а с одной учетной записью может быть связан только один пользователь.

Отношения «один к одному» можно урегулировать двумя способами…

Первый и самый простой - иметь только одну коллекцию, «пользовательская» коллекция и учетная запись этого конкретного пользователя будут храниться как объект в самом пользовательском документе.

Второй способ - создать другую коллекцию с именем account и сохранить ссылочный ключ (в идеале идентификатор учетной записи) в пользовательском документе.

Вы можете подумать, зачем мне вообще это нужно?

Этот способ обычно используется, когда возникает один из следующих трех сценариев…

  1. Основной документ слишком велик (документы MongoDB имеют ограничение на размер 16 МБ)
  2. Когда необходимо сохранить некоторую конфиденциальную информацию (возможно, вы не захотите возвращать информацию об учетной записи при каждом запросе GET пользователя).
  3. Когда существует исключительная потребность в получении данных учетной записи без данных пользователя (когда запрашивается «учетная запись», вы не хотите отправлять с ней информацию «пользователя» и / или когда запрашивается «пользователь», вы не хотите отправьте с ним информацию об учетной записи, даже если они оба связаны)

Отношение один ко многим

Отношение «один ко многим» требует, чтобы одна сущность имела исключительные отношения с другой сущностью, но другая сущность может иметь отношения с несколькими другими сущностями. Давайте рассмотрим простой пример, чтобы лучше понять эти отношения ...

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

Первый - хранить массив учетных записей в самой коллекции пользователей. Это позволит вам ПОЛУЧИТЬ все учетные записи, связанные с пользователем, за один вызов. MongoDB также имеет функции для передачи и извлечения данных из массива в документе, что позволяет довольно легко добавлять или удалять учетные записи пользователя, если это необходимо.

Второй способ - создать другую коллекцию с именем «account» и сохранить ссылочный ключ (в идеале ID учетной записи) в документе «user». Причины для этого те же, что и в случае отношений один на один.

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

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

Например, в этом случае, поскольку это банковское приложение (предположение), вы знаете, что большинство вызовов, которые вы сделаете, будут связаны с получением одного пользователя (возможно, при входе в систему) и еще одним вызовом для получения учетных записей, связанных с этим user (возможно, когда он переходит на вкладку учетных записей), и, следовательно, приведенная выше схема кажется довольно хорошей для этого варианта использования. Фактически, сохранение user_id в коллекции учетных записей было бы даже лучшим подходом в этом случае.

Теперь рассмотрим другой сценарий, на этот раз это открытый форум, пользователи могут создавать сообщения, и эти сообщения могут просматривать все. В этом случае лучше хранить user_id в коллекции сообщений, а не post_ids в коллекции пользователей, поскольку вы знаете, что ваша точка продажи - это список сообщений, который пользователи могут просматривать, и, следовательно, вызовы, которые вы в основном делаете, будут заключаться в получении сообщений list со связанными с ним пользовательскими данными (возможно, на самой домашней странице, например, на временной шкале Facebook). Таким образом, при обновлении вам не нужно будет обновлять две коллекции.

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

Отношение многие ко многим

Отношение многие ко многим не требует, чтобы какая-либо сущность имела исключительные отношения. Оба объекта могут иметь несколько отношений. Давайте рассмотрим простой пример, чтобы лучше понять эти отношения ...

Рассмотрите отношения между пользователями и продуктами в среде электронной коммерции. Есть список пользователей и список продуктов. Любой пользователь может купить любой продукт, то есть пользователь может купить несколько продуктов, а продукт может быть куплен несколькими пользователями. В этом случае есть только один идеальный способ справиться с этим.

Будет две коллекции: одна для пользователей, а другая - из продуктов. Каждый раз, когда пользователь покупает продукт, добавьте идентификатор продукта в качестве ссылки в коллекцию пользователя, и, поскольку пользователь может покупать несколько продуктов, эти идентификаторы должны храниться в виде массива.

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

Очевидно, что когда пользователь покупает какой-либо продукт, он должен перейти в другую коллекцию (возможно, в коллекцию buy_items), чтобы продукты там не обновлялись при обновлении продукта в коллекции продуктов (поскольку в идеале вы не должны делать изменения на уже купленные товары). Эти вещи на самом деле связаны с архитектурой приложения, которое вы создаете. При этом я мог бы начать писать статьи о планировании архитектуры базы данных, чтобы в ближайшее время осветить эти темы (надеюсь). А пока увидимся! (Я знаю, что не умею заканчивать посты 😛)