Как структурировать отношения в БД Azure Cosmos? - PullRequest
0 голосов
/ 19 декабря 2018

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

В настоящее время моя структура выглядит следующим образом;

// user document
{
id: 123,
postIds: ['id1','id2']
}

// post document
{
id: 'id1',
ownerId: 123
}
{
id: 'id2',
ownerId: 123
}

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

Я также обеспокоен производительностью, если у пользователя 10 000 постов, это 10000 поисков, которые я должен сделать, чтобы разрешить все посты ..

Это правильный метод для моделирования отношений сущностей?

1 Ответ

0 голосов
/ 03 января 2019

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

ПОЧЕМУ НОРМАЛИЗИРУЕТСЯ?

Первое, что я заметил в вашем посте: вы ищете какой-то уровень ссылочной целостности (https://en.wikipedia.org/wiki/Referential_integrity), который является чем-тоэто необходимо, когда вы разбиваете более крупный объект на составляющие его части. Также называется нормализацией.

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

https://docs.mongodb.com/manual/core/data-model-design/#normalized-data-models

Но действительно ли это вам нужно? Поскольку вы решили использовать базу данных документов JSON, вам следует использоватьтот факт, что он может сохранить весь документ, а затем просто сохранить документ ВСЕ со всеми данными владельца: имя, фамилия или все другие данные, которые вы имеете оПользователь, который создал документ.Да, я говорю, что вы можете оценить не наличие поста и пользователя, а просто постов с информацией о пользователе внутри. Это может быть на самом деле очень правильно, так как вы будете уверены, что получите ТОЧНЫЕ данные для существующего пользователяна момент создания поста.Скажем, например, я создаю пост, и у меня есть биография "X".Затем я обновляю свою биографию до «Y» и создаю новый пост.В двух постах будут разные биографии авторов, и это совершенно правильно, поскольку они точно отражают реальность.

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

Если все авторы, чтобы существовать в вашей системе, ДОЛЖНЫ опубликовать сообщение в блоге, этого вполне может быть достаточно.Но, возможно, вы захотите, чтобы автор написал его биографию и был включен в вашу систему, даже до того, как он напишет сообщение в блоге.

В этом случае вам необходимо НОРМАЛИЗОВАТЬ модель и создать новый тип документа, просто дляавторы.Если это ваш случай, то вам также необходимо выяснить, как справиться с ситуацией, описанной ранее.Когда автор обновит свою собственную биографию, вы просто обновите документ автора или создадите новый?Если вы создадите новый, чтобы вы могли отслеживать все изменения, вы также обновите все предыдущие посты, чтобы они ссылались на новый документ, или нет?

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

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

ПОСТОЯННОСТЬ

Предположим, что вы действительно хотитечтобы записи и пользователи хранились в отдельных документах, и вы нормализуете свою модель.В этом случае имейте в виду, что базы данных Cosmos DB (но в целом NoSQL) НЕ ПРЕДЛАГАЮТ никакой нативной поддержки для обеспечения ссылочной целостности, так что вы в значительной степени сами по себе.Индексы могут, конечно, помочь, поэтому вы можете захотеть проиндексировать свойство ownerId, чтобы, например, перед удалением автора вы могли эффективно проверить, есть ли какие-либо сделанные им сообщения в блоге, которые в противном случае останутся сиротами.Другой вариант - вручную создать и сохранить ДРУГОЙ документ, который для каждого автора отслеживает написанные им сообщения в блоге.При таком подходе вы можете просто посмотреть на этот документ, чтобы понять, какие записи в блоге принадлежат автору.Вы можете попытаться автоматически обновлять этот документ с помощью триггеров или сделать это в своем приложении. Просто имейте в виду, что когда вы нормализуетесь в базе данных NoSQL, поддерживать согласованность данных - это ВАША ответственность.Это полная противоположность реляционной базе данных, где вы несете ответственность за поддержание согласованности данных при их ненормализации.

PERFORMANCES

Производительность МОЖЕТ быть проблемой, но вы обычно не моделируете, чтобы поддерживать производительность в первую очередь.Вы моделируете, чтобы убедиться, что ваша модель может представлять и хранить необходимую вам информацию из реального мира, а затем вы оптимизируете ее, чтобы иметь достойную производительность с базой данных, которую вы выбрали.Поскольку разные базы данных будут иметь разные ограничения, модель будет адаптирована к этим ограничениям.Это не что иное, как старая и старая дискуссия о «логическом» и «физическом» моделировании.

В случае с Cosmos DB у вас не должно быть запросов, которые пересекаются, поскольку они более дорогие.

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

Теперь, хотя это может показаться разумным выбором, это будет только при наличии МНОГО авторов.Например, если у вас есть только один, все данные и запросы будут помещены в один раздел, что значительно снизит вашу производительность.Помните, что на самом деле Cosmos DB RU распределяется между всеми доступными разделами: например, с 10.000 RU вы обычно получаете 5 разделов, что означает, что все ваши значения будут распределены по 5 разделам.Каждый раздел будет иметь максимальный лимит 2000 RU.Если все ваши запросы используют только один раздел, ваша реальная максимальная производительность - это 2000, а не 10000 RU.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...