DynamoDB атомно обновляемый счетчик - PullRequest
0 голосов
/ 19 сентября 2018

DynamoDB новичок здесь, заинтересованный в изучении баз данных NoSQL.

У меня есть сценарий, где у меня есть таблица, в которой есть ключ раздела userId, ключ сортировки времени и числовой дескриптор.Дескриптор представляет собой последовательный счетчик, который увеличивается на 1.

Вот пример таблицы:

userId, time, handle
0     , 123 , 1
0     , 456 , 2
1     , 123 , 1
1     , 234 , 2
0     , 789 , 3
1     , 345 , 3

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

ЧтоЯ хочу иметь возможность сделать, это добавить новую запись для userId 0, для времени 891 и иметь дескриптор 1 больше, чем последняя записанная запись для userId 0 - который будет предпоследней строкой в ​​базе данных, то есть 3 + 1= 4.

Наивным способом является запрос базы данных для userId 0, сортировка по последней отметке времени (если это вообще возможно), чтобы получить дескриптор (3).Это первый запрос.Затем вы создадите запрос put_item в базе данных, который добавляет 1 к дескриптору (3 + 1 = 4) и создает новую запись.

Очевидно, что здесь есть условие гонки, когда между запросом на чтение и созданиемВ запросе put_item другая лямбда / API / конечная точка могла зафиксировать новую запись в базе данных с тем же дескриптором (4), например (1, 888, 4).Когда я фиксирую свою исходную запись (0, 891, 4), дескриптор равен 4, тогда как теперь он должен быть 5.

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

Дайте мне знать, если мой вопрос не ясен.

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

То, что вы пытаетесь сделать: «назначить монотонно увеличивающееся числовое значение в качестве уникального идентификатора» - это анти-паттерн с распределенными базами данных (noSql или иным образом)

Подумайте и рассмотрите проблему.

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

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

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

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

0 голосов
/ 20 сентября 2018

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

...