Я недавно читал этот раздел в документации ElasticSearch (или, если быть более точным, руководство).Это говорит о том, что вы должны попытаться использовать нереляционную базу данных намеченным способом, то есть вам следует избегать объединений между различными таблицами, поскольку они не предназначены для правильной обработки.Это также напоминает мне о разделе документов DynamoDB, в котором говорится, что большинству хорошо разработанных бэкэндов DynamoDB требуется только одна таблица.
Давайте возьмем в качестве примера базу данных рецептов, в которой каждый рецепт использует несколько ингредиентов.Каждый ингредиент может использоваться во многих различных рецептах.
Вариант 1 : для меня очевидный способ смоделировать это в AppSync и DynamoDB - начать с таблицы ingredients
, которая имеетодин элемент на ингредиент, хранящий все данные ингредиента, с ingredient id
в качестве ключа раздела.Затем у меня есть другая таблица recipes
с ключом разделения recipe id
и полем ingredients
, в котором хранятся все ingredient id
в массиве.В AppSync я мог затем запросить рецепт, выполнив запрос GetItem с помощью recipe id
, а затем разрешив поле ingredients
с помощью BatchGetItem в таблице ingredients
.Скажем, рецепт содержит в среднем 10 ингредиентов, так что это будет означать 11 запросов GetItem, отправленных в таблицы DynamoDB.
Опция 2: Я бы посчитал, что это операция по принципу соединения,по-видимому, не идеальный способ использования нереляционных баз данных.Итак, в качестве альтернативы я мог бы сделать следующее: сделать «избыточные копии» всех данных ингредиентов в таблице recipes
и не только сохранить туда ingredient id
, но и все другие данные из таблицы ingredients
.Это может резко увеличить использование дискового пространства, но, очевидно, дисковое пространство дешевое, и увеличение производительности за счет выполнения только одного запроса GetItem (вместо 11) может стоить того. Как будет обсуждаться позже в руководстве ElasticSearch , это также потребует дополнительной работы для обеспечения параллелизма при обновлении данных ингредиентов.Поэтому мне, вероятно, придется использовать поток DynamoDB для обновления всех данных в таблице recipes
, а также при обновлении ингредиента.Для этого потребуется дорогое сканирование, чтобы найти все рецепты с использованием обновленного ингредиента, и BatchWrite для обновления всех этих предметов.(Обновление ингредиентов может быть редким, поэтому увеличение производительности чтения может стоить этого.)
Мне было бы интересно услышать ваши мысли по этому поводу:
- Какой вариант будетВы выбираете и почему?
- Второй «более нереляционный способ» сделать это кажется болезненным, и я обеспокоен тем, что с появлением большего количества уровней / отношений (например, если пользователи могут создавать меню из рецептов),возникающая сложность может быстро выйти из-под контроля, когда мне придется несколько раз сохранять «избыточные копии» одних и тех же данных.Я не очень разбираюсь в реляционных базах данных, но эти вещи кажутся намного проще, когда все данные имеют свое уникальное местоположение, и вот оно (я думаю, это означает «нормализация»).
- Это
getRecipe
вВариант 1 действительно в 11 раз дороже (с точки зрения производительности и стоимости), чем в варианте 2?Или я что-то неправильно понимаю? - Будет ли вариант 1 более дешевой операцией в реляционной базе данных (например, MySQL), чем в DynamoDB?Несмотря на то, что это соединение, если я правильно понимаю, это всего лишь 11 («путь по NoSQL») операций GetItem.Может ли это все же быть быстрее, чем 1 SQL-запрос?
- Если у меня очень реляционная структура данных, может ли быть нереляционная база данных, такая как DynamoDB, плохим выбором?Или AppSync / GraphQL - это способ сделать его жизнеспособным выбором (разрешив вариант 1, который действительно легко построить)?Я читал некоторые мнения о том, что постоянная работа с отсутствующей возможностью соединения при запросах к базам данных NoSQL и необходимость делать это на стороне приложения являются основной причиной, по которой она не подходит.Но AppSync может быть способом решения этой проблемы.Другие мнения (в том числе документы DynamoDB) упоминают проблемы с производительностью в качестве основной причины, по которой вам следует всегда запрашивать только одну таблицу.