Uniqueness in DynamoDB secondary index

NO they don't. Indexes are updated asynchronously, meaning they'll be eventually consistent, and which also means that dynamodb won't be able to enforce uniqueness at the time when you make the update call (it won't check for uniqueness on the secondary indexes, as that's an async operation; if it does, it will have no way to return a failure, as the real-time call would already have finished).

On a side note, that's also the reason why you can only perform Scan or Query on a GSI index, but not GetItem (i.e. GetItem is expected to return one item, but there can be many corresponding to given secondary index in the absence of uniqueness constraint).


Secondary indexes don't guarantee uniqueness. From the docs:

In addition, remember that global secondary indexes do not enforce uniqueness

http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html


It is actually possible to ensure the uniqueness of a GSI by combining transactions and multiple tables.

E.g. lets say your main table has these indexes:

record_id (partition key) name (GSI)

If you want to ensure that "name" is unique in this table, create a secondary table with the following indexes:

name (partition key)

Then when creating documents in the main table, do it as part of a transaction where you also create a document in the second table with a special conditions ensuring that the name does not exist already, e.g. the transaction would have the following updates:

PutItem(Table=mainTable, ConditionExpression='attribute_not_exists(#RECORD_ID)',...)

PutItem(Table=namesTable,ConditionExpression='attribute_not_exists(#NAME)',...)

Removing an item from the main table can also ensure both documents are removed from both tables in a transaction, which basically ensures referential integrity.