Существует отношение "один-к-нескольким", где связанные данные ограничены, малы и часто считываются вместе.
→Встроить связанные данные в виде вложенного объекта или массива в основной документ.
Почему: Оптимизирует производительность чтения, извлекая все необходимые данные за одно точечное чтение, минимизируя затраты RU и задержку. Избегает клиентских объединений.
Источник↗
Отношение "один-ко-многим", где сторона "много" неограниченно растет или обновляется независимо от стороны "один".
→Хранить связанные элементы как отдельные документы и использовать ID родительского документа в качестве ссылки.
Почему: Предотвращает превышение документами лимита в 2 МБ и избегает высоких затрат RU при обновлениях больших встроенных массивов.
Источник↗
Документ содержит массив, который со временем может неограниченно расти, рискуя превысить лимит размера документа в 2 МБ (например, журналы событий, комментарии).
→Разделить массив на несколько "корзинчатых" документов. Когда корзина достигает порогового значения размера/количества элементов, создать новую.
Почему: Поддерживает управляемый размер отдельных документов, сохраняя при этом логическую группировку связанных данных.
Моделирование отношения "многие-ко-многим", например, студенты и курсы, или статьи и теги.
→Для ограниченных отношений дублируйте данные отношений с обеих сторон (например, встройте ID курсов в документ студента, ID студентов в документ курса). Для неограниченных используйте отдельный контейнер документов "соединение" или "граница".
Почему: Денормализация оптимизирует запросы в обоих направлениях (студенты в курсе, курсы для студента), не требуя объединений. Контейнер соединения используется для неограниченных случаев.
Моделирование иерархических данных (например, организационная структура, категории продуктов) и необходимость запроса всех потомков узла.
→Хранить массив всех ID или имен предков (путь) в каждом документе.
Почему: Позволяет эффективно запрашивать поддеревья с помощью одного фильтра `ARRAY_CONTAINS`, избегая дорогостоящих рекурсивных поисков.
Документ имеет неограниченный массив (например, комментарии в блоге), но наиболее частый запрос требует только N последних элементов.
→Встроить подмножество последних элементов в основной документ и хранить все элементы как отдельные ссылочные документы.
Почему: Оптимизирует основной путь чтения для производительности и стоимости, при этом позволяя получать доступ ко всему набору данных при необходимости.
Хранение последовательности неизменяемых событий для сущности и необходимость запроса текущего состояния или аналитических агрегатов.
→Хранить события в одном контейнере, разбитом по ID сущности. Используйте Change Feed или Synapse Link для вычисления и хранения материализованных представлений или агрегатов.
Почему: Предоставляет полный аудиторский след и разделяет модель записи от различных моделей чтения, предлагая высокую гибкость.
Необходимо сохранить состояние связанных данных в определенный момент времени (например, адрес клиента в заказе).
→Встроить копию (снимок) связанных данных в документ, а не ссылаться на них.
Почему: Обеспечивает историческую точность, отвязывая документ от будущих изменений ссылочных данных.
Прием высокочастотных временных рядов данных (например, показания датчиков IoT) и запрос по устройству в определенных временных диапазонах.
→Использовать ID устройства в качестве ключа секции. Агрегировать показания в документы, сгруппированные по времени (например, почасовые или поминутные), вместо одного документа на каждое показание.
Почему: Резко сокращает количество документов и RU записи, одновременно сопоставляя данные для эффективных запросов по временным диапазонам в рамках одной секции.
Необходимо выполнить несколько операций создания, обновления или удаления как единую атомарную транзакцию.
→Использовать функцию TransactionalBatch SDK. Все операции должны быть нацелены на один и тот же логический ключ секции.
Почему: Предоставляет гарантии ACID для до 100 операций в пределах одной секции, гарантируя, что либо все операции успешно завершаются, либо все они завершаются сбоем.
Документы должны автоматически удаляться из контейнера по истечении определенного периода (например, 30 дней).
→Включить Time to Live (TTL) для контейнера и установить значение `ttl` по умолчанию в секундах (например, 2592000 для 30 дней). Значение `ttl` -1 для отдельного документа переопределяет значение по умолчанию и предотвращает истечение срока действия.
Почему: TTL — это бесплатная функция, которая использует оставшиеся RU для выполнения фоновых удалений, предоставляя эффективный и автоматический способ управления жизненным циклом данных.
Необходимо хранить большие бинарные объекты (изображения, видео, документы > 2 МБ), связанные с метаданными Cosmos DB.
→Хранить бинарный объект в Azure Blob Storage. Хранить URI к блобу в документе Cosmos DB вместе с метаданными.
Почему: Cosmos DB оптимизирован для структурированных метаданных и имеет лимит размера документа в 2 МБ. Blob Storage — это экономичный и масштабируемый сервис для хранения больших объектов.