Каков рекомендуемый эквивалент каскадного удаления в MongoDB для отношений N: M?

Предполагая, что следующая схема "схема/связь" является рекомендуемой практикой для обработки удаления с помощью операции каскадного удаления как??

Реляционная схема:

  +---------+                                    +--------+
  | Student |-*--------1-[Enrollment]-1--------*-| Course |
  +---------+                                    +--------+

MongoDB:

  +---------+                    +--------+
  | Student |-*----------------*-| Course |
  +---------+                    +--------+

Учитывая этот классический дизайн зачисления студентов на курсы, наличие набора курсов для студентов и наоборот, похоже, является подходящей моделью данных при использовании MongoDB (это ничего не касается таблицы отношений/регистрации). Но исходя из реляционного мира, как я должен обрабатывать семантику удаления курса? То есть, когда курс удаляется, все записи "регистрации" также должны быть удалены. То есть, я должен удалить курс из коллекции каждого студенческого рекорда. Похоже, я должен запустить 2 запроса: один для удаления курса, а затем удалить его из каждой коллекции учеников. Есть ли способ иметь один запрос для выполнения этого "каскадного удаления", например, семантики без дополнительного запроса? Необходимо ли изменить модель данных?

ПРИМЕЧАНИЕ. Для всех других случаев использования приведенная выше модель данных работает очень хорошо:

  • Удаление ученика => просто удалит этого студента и связанную с ним коллекцию курсов, удаленных вместе с ним.
  • Студент, желающий отказаться от курса =>, просто удалит его из студенческой коллекции курсов.
  • Добавить ученик/курс => по существу. Просто добавьте его в соответствующую "таблицу".

Единственная сложная вещь - обработка удаления курса. Как я должен обрабатывать этот сценарий в MongoDB, так как я родом из реляционного фона и не могу понять это.

Ответ 1

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

По-видимому, это не вещь mongodb, а скорее концепция NoSQL, в которой менее изменяющиеся данные (курсы) могут храниться отдельно. И так как удаление Курса не будет очень частым действием, его вполне достаточно, чтобы пройти все записи, чтобы удалить его.

С другой стороны, вы можете позволить, чтобы это было так, как есть. В вашей логике приложения просто игнорируйте значения Курсов в документе Студента, которые вообще не имеют reference_id в документе курса. Но в этом случае вы должны убедиться, что старый удаленный Course_id не используется повторно.

ИЛИ просто используйте удаленные флаги в документе курса и обрабатывайте все остальное в логике вашего приложения.

Ответ 2

Я собираюсь ответить на основе рекомендаций команды Монго. Я также пришел из реляционной базы данных, и у меня были некоторые проблемы в начале понимания понятий. Команда Mongo рекомендует проектировать с идеей схемы "Application-Driven", поэтому сначала вам нужно выяснить, какие части данных идут вместе. Помните, что в Монго не существует такой концепции транзакций, даже если мы изобретаем драйвер, который обрабатывает транзакции, мы должны реализовать наше собственное решение для этого. Это означает, что если у меня есть два бизнес-объекта, которые требуют обновления в одно и то же время, и я не могу терпеть сбой в этой операции, я должен объединить их в один документ (атомный).

В вашем случае у вас есть два документа: "Студент и курсы", а также отношение между ними (студент поступает на курсы N). Я полагаю, что курсы не должны постоянно меняться, поэтому их можно хранить в другой коллекции. Но дело в том, что связь между ними, в этом случае вам нужно атомически удалить ученика и все курсы, в которых он участвовал. Поэтому лучшим подходящим решением для этого является встраивание отношения в Student и сохранение отдельной коллекции курсов. Когда вы удаляете ученика, отношение одновременно отбрасывается:

Студент Json:

{ _id: ObjectId('...'), name:"John", lastname:"Smith", 
courses: [ 1, 100, 50, 67 ], ...
}

Курсы могут быть разделены между ними. Это способ справиться с этим в Монго. Атомные операции должны быть встроены в один документ. Я предположил, что курсы - это список курсов, которые не так сильно меняются, если они разработаны Студентом, мы могли бы немного изменить решение.