I'm looking for a solution to a problem that I've discovered with my current DynamoDB application design.
Background: I have a Users
table with username
as the hash key. Other attributes include email
, password_digest
, and user details like Name
. I've set up a Global Secondary Index called EmailIndex
with email
as a the hash and projected a subset of the table's attributes to it.
My use case: I need to ensure uniqueness on both the username
and email
attributes. It's easy enough to do on the username
because it's the hash key. I had assumed that before saving a new user, I could do a lookup to the EmailIndex
to see if the email that the user wants to use isn't already in use, but I just recently realized that Global Secondary Indexes don't support strongly consistent reads. The consequence of this is that I won't be able to detect the scenario where two users sign up at approximately the same time using the same email address. When I do a Query
request on the EmailIndex
while processing the 2nd user's request, it'll return false and my code will assume that the email address has not been taken. However, in the background DynamoDB is really processing the PutItem
request for the 1st user that includes that same email address.
I'm currently heading towards replacing EmailIndex
with a UsersEmail
table and doing two writes (one to the Users
table and one to this new table) for every user save and update, just so that I can do a lookup on username
(from the Users
table) and email
(from the UsersEmail
table) as strongly consistent reads. Are there any other options that I've overlooked?