2
votes

I'm getting ready to rebuild a database that has 3 different tables all containing the same data. the difference is the HashKey for each, UserId, UserName, Email. I'm trying to combine them all into one table as I think the redundancy is bad as well as slow. What I plan on doing is have UserId as the HashKey, and having UserName and Email as secondary indexes. I have not found a way to have dynamoDb force uniqueness on the secondary indexes, so plan on using conditional writes that check for uniqueness in those before writing to the database. With SQL this would be very easy, is there a better way of doing this in DynamoDb? I need to be able to look up a user based off of either of the three UserId, UserName and Email. I'd like to keep this to one table and not use another table that references the Email to UserId or UserName to UserId.

1
The other question I had is can you use the high level api to do this, or are you required to use the low level api? I'm not finding much info on conditional writes or secondary indexes in the high level api docs. - Steve Smith
doing more more research it looks like conditional writes may not work as they appear to only check that "row" and won't check the entire table to see if that secondary index value is used IE. email. - Steve Smith

1 Answers

4
votes

You are correct that DynamoDB does not enforce uniqueness on Global Secondary Indexes.

If you are going to use a single DynamoDB table, the only thing that is enforced to be unique is the primary key (hash + optional range key). This is because an item is uniquely identified by that key. So to combine your tables into a single table will require that enforcement in the application logic.

Maintaining a Global Secondary Index for a uniquely identified key on a per item basis is the equivalent of maintaining a second table. The Global Secondary Index would require the same provisioned throughput as if you had created a second/third table. The benefit of using a Global Secondary Index is that you don't have to maintain the index yourself.

Just as a warning: Global Secondary Indexes are eventually consistent in DynamoDB. This means that even though you've received a 200 response for a PutItem, it may not show up immediately if you check the Global Secondary Index. This could lead to a race condition where you check for one of the values and it has not yet propagated to the index. You'd have the same issue if you maintain the index yourself - you'd need to lock on something to make sure the writes to all three tables are transactional.