Уникальность во вторичном индексе DynamoDB

#amazon-web-services #amazon-dynamodb

#amazon-веб-сервисы #amazon-dynamodb

Вопрос:

Вопрос:

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

Пример:

У меня есть таблица DynamoDB комментариев с первичным ключом post_id и ключом диапазона comment_id. Кроме того, существует локальный вторичный индекс с ключом диапазона date-user_id.

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

Запись 1: post_id: 1 comment_id: 1 дата-user_id: 2014_06_24-1

Запись 2: post_id: 1 comment_id: 2 дата-идентификатор пользователя: 2014_06_24-1

Запись 3: post_id: 1 comment_id: 3 дата-идентификатор пользователя: 2014_06_24-2

Когда я выполняю запрос, указывающий вторичный индекс, и передаю условие post_id, равное 1, а date-user_id равно 2014_06_24-1, я получаю количество 2, и я ожидаю количество 1.

Почему вторичный индекс содержит две записи с одним и тем же ключом первичного ключа / диапазона.

Ответ №1:

Вторичные индексы не гарантируют уникальность. Из документов:

Кроме того, помните, что глобальные вторичные индексы не обеспечивают уникальность

http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html

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

1. Я думаю, @justin.m.преследуйте unique() их после их извлечения: (

2. @justin.m.chase Для этого вам следует использовать транзакцию: aws.amazon.com/fr/blogs/database /…

Ответ №2:

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

Кстати, это также причина, по которой вы можете выполнять сканирование или запрос только по индексу GSI, но не GetItem (т. Е. Ожидается, что GetItem вернет один элемент, но их может быть много, соответствующих данному вторичному индексу при отсутствии ограничения уникальности).

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

1. GSI не использует пары DynamoDB, поскольку их не нужно активировать для создания GSI, но вам нужны потоки dynamodb для глобальных таблиц

2. DynamoDB использует средство распространения журнала для обновления таблиц GSI — это объясняется в этом действительно классном докладе Ясо Соренсена re: inven Amazon DynamoDB под капотом: как мы создали гипермасштабную базу данных

Ответ №3:

На самом деле можно обеспечить уникальность GSI путем объединения транзакций и нескольких таблиц.

Например, допустим, в вашей основной таблице есть эти индексы:

идентификатор записи (ключ раздела) имя (GSI)

Если вы хотите убедиться, что «имя» уникально в этой таблице, создайте вторичную таблицу со следующими индексами:

имя (ключ раздела)

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

PutItem(таблица = MainTable, ConditionExpression=’attribute_not_exists(#RECORD_ID)’,…)

PutItem(таблица= namesTable,ConditionExpression=’attribute_not_exists(#NAME)’,…)

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

Ответ №4:

Каждый элемент в локальном вторичном индексе (LSI) имеет соотношение 1: 1 с соответствующим элементом в таблице. В приведенном выше примере, хотя запись 1 и запись 2 в LSI имеют одинаковое значение ключа диапазона, элемент в таблице, на который они указывают, отличается. Следовательно, ключи индекса (хэш или хэш диапазон) не являются уникальными.

Глобальный вторичный индекс (GSI) в этом аспекте похож на LSI. Каждый элемент GSI содержит ключи хэша таблицы и диапазона (соответствующего элемента). Более подробная информация доступна по адресу http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html#GSI.Projections

Ответ №5:

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

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

Вот как будут выглядеть наши записи

 {
  pk: '<post_id>_<comment_id>',
  record_type: 'record',
  date-user_id: '2022-05-13_<user-id>',
  comment: 'some comment'
}
{
  pk: 'unique-index#2022-05-13_<user-id>',
  record_type: 'unique-index'
}
  

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

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