Используя AWS Appsync с DynamoDB, следует ли моделировать отношения, сохраняя «избыточные копии» связанных данных в одной таблице (денормализация)? - PullRequest
0 голосов
/ 11 октября 2018

Я недавно читал этот раздел в документации 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) упоминают проблемы с производительностью в качестве основной причины, по которой вам следует всегда запрашивать только одну таблицу.
...