Как лучше реализовать структуру в MongoDB

Лучший способ реализовать структуру в MongoDB — начать не с коллекций, а с вопросов: какие данные читаются вместе, какие часто обновляются, что может бесконечно расти и какие фильтры будут в интерфейсе. MongoDB хорошо работает с вложенными документами, но не все нужно вкладывать в один огромный документ

Простое правило:

  • читается вместе и не растет бесконечно — можно вложить;
  • часто обновляется отдельно — лучше отдельная коллекция;
  • список может стать большим — лучше отдельная коллекция;
  • нужен быстрый фильтр — заранее думайте об индексе.

Пример: пользователь и адреса

Если у пользователя 1-3 адреса доставки, их можно хранить внутри документа:

{
  name: "Dinar",
  addresses: [
    { city: "Sochi", street: "Lenina", isDefault: true }
  ]
}

Так профиль пользователя читается одним запросом

Пример: пользователь и заказы

Заказы лучше хранить отдельно:

{
  _id: ObjectId("..."),
  userId: ObjectId("..."),
  status: "paid",
  total: 4900,
  createdAt: new Date()
}

Заказов может быть много, у них свой жизненный цикл, статусы, оплата и доставка. Если положить все заказы в пользователя, документ быстро станет неудобным

Вложение или ссылка

Вложение удобно, когда данные принадлежат документу и почти всегда нужны вместе. Ссылка удобна, когда объект живет отдельно: пользователь, заказ, товар, платеж, сообщение

Для ссылок храните ObjectId:

{
  userId: ObjectId("665f1c1a7b8c2e0012a4d111")
}

И добавляйте индекс:

db.orders.createIndex({ userId: 1, createdAt: -1 })

Как проверить структуру

Напишите 3-5 главных запросов приложения. Например:

db.orders.find({ userId }).sort({ createdAt: -1 }).limit(20)
db.products.find({ active: true, category: "hoodies" })
db.messages.find({ conversationId }).sort({ createdAt: -1 }).limit(50)

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

Антипример: все в одном документе

Плохой вариант для пользователя:

{
  name: "Dinar",
  orders: [
    { number: 1, items: [...], messages: [...], payments: [...] }
  ]
}

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

  • users — профиль пользователя;
  • orders — заказы с userId;
  • payments — платежи с orderId;
  • messages — сообщения с conversationId.

Так каждый тип данных получает свой жизненный цикл

Денормализация допустима

MongoDB не запрещает хранить небольшие копии данных. Например, в заказе можно хранить userName и userEmailSnapshot, чтобы старый заказ не менялся при изменении профиля пользователя. Главное — понимать, что это снимок данных, а не единственный источник правды

Частые ошибки

Копируют SQL-схему один в один

MongoDB не обязана повторять реляционную схему. Иногда вложенный объект проще и быстрее

Вкладывают бесконечные массивы

Комментарии, сообщения и события лучше хранить отдельными документами

Не думают о запросах

Структура должна помогать реальным чтениям и обновлениям

Не создают индексы

Даже хорошая структура будет медленной без индексов под частые фильтры

Боятся любых повторов данных

Небольшая денормализация часто нормальна, если она упрощает чтение и не создает путаницу в обновлениях

Что почитать дальше по MongoDB

Если нужен общий маршрут по теме, откройте рубрику MongoDB. Для соседних задач пригодятся эти разборы:

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x