Базы данных документов: избыточные данные, ссылки и т. Д. (В частности, MongoDB)

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

Таким образом, простой ответ - сохранить идентификатор пользователя в документе магазина или идентификатор магазина в документе пользователя. Тем не менее, часто требуется доступ к 1-2 другим частям данных для отображения, потому что идентификаторы бесполезны. Как, может быть, имя клиента или название магазина.

  1. Вы обычно храните дубликаты всего документа? Или просто хранить нужные вам данные? Может быть, зависит от размера документа, сколько вам нужно.
  2. Как вы справляетесь с тем, что у вас есть дубликаты данных? Вы идете выслеживать данные, когда они меняются? Обновлять данные через определенный промежуток времени, когда он загружен? Только дублировать, когда вы можете позволить себе устаревшие данные?

Буду признателен за ваш вклад и / или ссылки на любые "лучшие практики" или хотя бы обоснованное обсуждение этих тем.

3 ответа

Есть в основном два сценария: свежий и несвежий.

Свежие данные

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

В этом случае у вас будут некоторые накладные расходы из-за дополнительных запросов. Альтернативой является отслеживание всех местоположений дубликатов данных и обновление всех экземпляров при каждом обновлении. Это также связано с накладными расходами, особенно в отношениях N-to-M, подобных тому, который вы упомянули. Так или иначе, у вас будут некоторые накладные расходы, если вам потребуются свежие данные. Вы не можете иметь лучшее из обоих миров.

Устаревшие данные

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

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

Резюме

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

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

У @Niels есть хорошее резюме, но я думаю, что будет справедливо отметить, что вы можете "обмануть".

Допустим, вы хотите отобразить магазины, используемые пользователем. Очевидная проблема здесь заключается в том, что вы не можете "встроить" Магазин в Пользователя, поскольку Магазин сам по себе слишком важен. Но то, что вы можете сделать, это встроить некоторые данные магазина в пользователя.

Просто используйте материал, который вы хотите отобразить, например, "Название магазина". Таким образом, ваш объект User будет выглядеть так:

{
  _id : MongoID(),
  name : "Testy Tester",
  stores : [ 
             { _id : MongoID(), "name" : 'Safeway' },
             { _id : MongoID(), "name" : 'Walmart' },
             { _id : MongoID(), "name" : 'Best Buy' }
            ]
}

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

Чтобы ответить на ваши прямые вопросы:

  1. Нет дубликатов.
  2. Нет дубликатов.

;)

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

Теперь, чтобы ответить на ваш сценарий: вы хотите отношения "многие ко многим". Обычное решение здесь - создать третью "сквозную" или "мостовую" таблицу / коллекцию, вероятно, называемую StoreUsers:

StoreUsers
----------
storeuser_id
store_id
user_id

Вы добавляете запись к этому для каждой ссылки между магазинами и пользователями, будь то для другого магазина, другого пользователя или группы пользователей в одном магазине. Затем вы можете найти это независимо для магазина или для пользователя. MongoDB также поддерживает этот подход; это не зависит от СУБД.

Другие вопросы по тегам