2

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.

  • 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 Feb 12 '15 at 15:59
  • 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 Feb 12 '15 at 19:42

1 Answers1

4

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.

Ben Schwartz
  • 1,716
  • 13
  • 14
  • Ya I wrap all our DB calls as transnational. I thought to check the secondary index to just do a get by that index if it returns something then I know it's not unique. I think that would leave me with 2 reads (check both secondary indexes) and one write. I thought that would be better than the 3 writes and then worrying about doing roll backs and everything that comes with having 3 tables of the exact same values. – Steve Smith Feb 11 '15 at 00:22
  • Correction from what I know, there shouldn't be the 2 reads just one write, the conditional write will check that email and username are unique. If they are it writes if not it fails and returns back to the application. – Steve Smith Feb 11 '15 at 14:26
  • Also another Questions does eventual consistency matter if I only have one table? It makes sense if there are multiple tables, but with one is it really eventually consistent? – Steve Smith Feb 11 '15 at 14:28