DynamoDB: запрашивает все похожие элементы определенного типа

#amazon-dynamodb #dynamodb-queries #amazon-dynamodb-index

#amazon-dynamodb #dynamodb-запросы #amazon-dynamodb-index

Вопрос:

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

Допустим, в моей таблице хранятся такие элементы, как users , items и devices . Я сохраняю идентификатор для каждого из этих элементов в качестве ключа раздела. Каждый идентификатор имеет префикс своего типа, такой как user-XXXX , item-XXXX amp; device-XXXX .

Теперь проблема в том, как я могу запрашивать только определенный тип объекта? Например, я хочу получить все users , как мне это сделать? Это было бы возможно, если бы begin_with оператор был разрешен для ключей раздела, чтобы я мог искать префикс, но ключи раздела допускают только оператор равенства.

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

Любые предложения приветствуются.

Ответ №1:

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

Если вы храните свои данные с ключом раздела <type>-<id> , вы поддерживаете шаблон доступа «извлекать элемент по идентификатору». Вы правильно отметили, что вы не можете использовать begins_with для ключа раздела, оставляя вас без четкого способа получить коллекцию элементов этого типа.

Я думаю, вы на правильном пути, создав ключ раздела <type> (например, Users , Devices и т.д.) Со Значимым ключом сортировки. Однако, поскольку ваши элементы неравномерно распределены по таблице, вы сталкиваетесь с возможностью горячего раздела.

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

У вас также есть возможность распределять данные по разделам в DynamoDB, эффективно реализуя свой собственный кэш. Например, допустим, у вас есть веб-приложение, у которого есть список «10 лучших устройств» прямо на главной странице. Вы могли бы создать разделы DEVICES#1 , DEVICES#2 , DEVICES#3 ,…, DEVICES#N , в каждом из которых хранятся 10 лучших устройств. Когда вашему приложению необходимо получить 10 лучших устройств, оно может случайным образом выбрать один из этих разделов для получения данных. Это может не сработать для раздела такого размера, как Users , но это довольно аккуратный шаблон для рассмотрения.

Расширяя эту идею дальше, вы могли бы разделить устройства по какой-либо другой значимой метрике (например, <manufactured_date> или <created_at> ). Это позволило бы более равномерно распределить ваши Device элементы по всей базе данных. Ваше приложение будет отвечать за запрос всех разделов и объединение результатов, но вы уменьшите / устраните проблему с горячими разделами. В документах AWS DynamoDB этот шаблон обсуждается более подробно.

Вряд ли существует универсальный подход к моделированию данных DynamoDB, который может сделать моделирование данных супер сложным! Ваши конкретные шаблоны доступа будут определять, какое решение лучше всего подходит для вашего сценария.

Ответ №2:

Имея в виду лучшие практики создания единой таблицы и равномерного распределения элементов по разделам

Быстро выделяя две упомянутые здесь вещи.

  1. Определенно, равномерное распределение ключей разделов является наилучшей практикой.
  2. Наличие записей в одной таблице в общем смысле позволяет избежать необходимости нормализации, как в реляционной базе данных. Другими словами, его можно создавать с дублированной / избыточной информацией. Таким образом, не обязательно объединять все возможные данные в одну таблицу.

Теперь проблема в том, как я могу запрашивать только определенный тип объекта? Например, я хочу получить всех пользователей, как мне это сделать?

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

И создание нескольких таблиц — плохая практика

Я не думаю, что иметь более одной таблицы считается плохим. Плохо, если мы храним точно так же, как нормализованные таблицы, и нам приходится использовать JOIN для объединения данных.

Сказав это, какой подход был бы лучшим.

  1. Принципиальное отличие состоит в том, чтобы сначала подумать о запросах, которые будут получены при проектировании таблицы. Это даже подскажет, является ли DynamoDB правильным выбором. Например, требование выбирать каждого пользователя может быть вообще плохим вариантом использования для решения DynamoDB.
  2. Шаблоны запросов дополнительно подскажут, какой ключ раздела лучше всего использовать. Выбор DynamoDB здесь из-за большого объема и в основном неизменяемых записей?
  3. Всегда ли у меня под рукой ключ раздела для выполнения выбора, который мне нужно выполнить?
  4. Как будут выглядеть инструкции по обновлению, будет ли у него снова ключ раздела для выполнения обновлений?
  5. Нужно ли мне дополнительно фильтровать по дополнительным столбцам и может ли это быть порядком сортировки по умолчанию?

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

Комментарии:

1. Разные объекты не будут иметь никакой связи друг с другом, и между ними нет соединений. У нас будет идентификатор ключа раздела, когда мы собираемся обновить указанный элемент. Я думаю, что в этом случае использование нескольких таблиц — неплохой выбор, в конце концов.

2. Да @SyedWaqas в этом случае несколько таблиц — правильный выбор. На самом деле с точки зрения dynamodb будет более гибко выбирать разные единицы чтения и записи для каждой таблицы и соответствующим образом настраивать.