0

Currently, I am experimenting with a DynamoDB-based voting system with this single-table design:

  1. A vote item Primary Key is composed of a partition key "election_id", the sort key is a "voter_id", and an attribute "candidate" has a value of "candidate_id".
  2. A count item Primary Key is composed of a partition key "election_id" the sort key is the "candidate_id", and the attribute "count" contains the current count of votes for a given candidate for a given election.

The system allows voters to overwrite a previous vote item until the voting period is complete.

I have been unable to find a durable means to transactionally decrement the count for the previous candidate's count item, increment the count for the new candidate's count item, and overwrite the vote item with the newly selected candidate_id value.

While I have tested with DynamoDB Streams, I have also read opinions indicating Streams are not an uncompromisingly reliable means to keep track of counts -- although the previous value and new value "could" be used to subsequently increment/decrement counts.

Is there a means to test for an existing item and using that information, increment/decrement the respective counts, all within a transaction?
Or is there a more fundamental approach I am overlooking in solving this problem?

Loren
  • 190
  • 2
  • 14
  • 1
    Have you thought of not having the count table but doing an LSI using election_id/candidate_id, minimal projecting to get a count? Your RCU/WCU may end up being similar to having streams/extra table i/o. You could add a cache such as DAX in case the count needed to be read often. – cyberwombat Jun 09 '23 at 14:55
  • @cyberwombat, thank you for the excellent suggestion. In the event there is no transactional solution, the LSI makes perfect sense! The DAX would certainly help as well, but the cost is a bit steep. – Loren Jun 10 '23 at 06:18
  • 1
    Of course. DAX is in memory caching but ElastiCache w say Redis would be cheaper - you can also whip up your own caching in DynamoDB, storing the LSI result in another table with a TTL (not the built in one as you dont have much control over time) that you check on fetch and possibly refetch. I suppose if your count table also stores other stuff like election info then you'd be doing a few queries but if you are just using it to denormalize your data then an LSI/cache would work great. – cyberwombat Jun 10 '23 at 14:52

0 Answers0