Edit (January 2015):
Yes, you can add a global secondary index to a DynamoDB table after its creation; see here, under "Global Secondary Indexes on the Fly".
Old Answer (no longer strictly correct):
No, the hash key, range key, and indexes of the table cannot be modified after the table has been created. You can easily add elements that are not hash keys, range keys, or indexed elements after table creation, though.
From the UpdateTable API docs:
You cannot add, modify or delete indexes using UpdateTable. Indexes can only be defined at table creation time.
To the extent possible, you should really try to anticipate current and future query requirements and design the table and indexes accordingly.
You could always migrate the data to a new table if need be.
Answer from rpmartz on Stack OverflowDynamodb: add GSI to existing Dynamodb table via CDK deploy
AWS Cloud Formation - GSI not creating on existing table
amazon web services - Populate GSI attributes in Dynamodb if GSI is added on an existing table - Stack Overflow
Duration estimation for DynamoDB GSI creation on existing table
Why is the DynamoDB GSI not showing the item count?
Can a DynamoDB range key be a GSI key?
How many GSIs can be created in DynamoDB?
Videos
Edit (January 2015):
Yes, you can add a global secondary index to a DynamoDB table after its creation; see here, under "Global Secondary Indexes on the Fly".
Old Answer (no longer strictly correct):
No, the hash key, range key, and indexes of the table cannot be modified after the table has been created. You can easily add elements that are not hash keys, range keys, or indexed elements after table creation, though.
From the UpdateTable API docs:
You cannot add, modify or delete indexes using UpdateTable. Indexes can only be defined at table creation time.
To the extent possible, you should really try to anticipate current and future query requirements and design the table and indexes accordingly.
You could always migrate the data to a new table if need be.
Just got an email from Amazon:
Dear Amazon DynamoDB Customer,
Global Secondary Indexes (GSI) enable you to perform more efficient queries. Now, you can add or delete GSIs from your table at any time, instead of just during table creation. GSIs can be added via the DynamoDB console or a simple API call. While the GSI is being added or deleted, the DynamoDB table can still handle live traffic and provide continuous service at the provisioned throughput level. To learn more about Online Indexing, please read our blog or visit the documentation page for more technical and operational details.
If you have any questions or feedback about Online Indexing, please email us.
Sincerely, The Amazon DynamoDB Team
Hi there,
I need to create a GSI for an existing production table, and have been investigating the costs and duration for the creation itself but I'm not really sure if I'm doing a correct estimation.
Basically, I have a table with 90 million records, with an average size of 0.2kb per record.
From what I've been investigating -> 1 WCU = 1 write of up to 1 KB/s
So, let's round to 100.000.000 records * 0.2kb avg item size = 20.000.000kb to process
Then, I would set 5000 WCU to the GSI for the creation, so it would be 5000kb/s which should process the 20.000.000kb in 1.1h
However, it smells like this estimation is far from reality.
Another doubt is how the attributes affect the duration of the GSI creation? I have 10 non_key_attributes and an "INCLUDE" projection_type.
I appreciate your thoughts on this.
Thanks in advance!
Here is the update-table document.
Example:
aws dynamodb update-table --table-name <tableName> --global-secondary-index-updates file://gsi-command.json
Create a JSON file based with either update, create or delete action:-
Keep one of the action (update, create or delete) from below sample JSON and update the attribute definitions accordingly
[
{
"Update": {
"IndexName": "string",
"ProvisionedThroughput": {
"ReadCapacityUnits": long,
"WriteCapacityUnits": long
}
},
"Create": {
"IndexName": "string",
"KeySchema": [
{
"AttributeName": "string",
"KeyType": "HASH"|"RANGE"
}
...
],
"Projection": {
"ProjectionType": "ALL"|"KEYS_ONLY"|"INCLUDE",
"NonKeyAttributes": ["string", ...]
},
"ProvisionedThroughput": {
"ReadCapacityUnits": long,
"WriteCapacityUnits": long
}
},
"Delete": {
"IndexName": "string"
}
}
...
]
There is a small section in the Options section of the Update Table documentation that mentions the required options specific to creating a new global secondary index which requires that the attribute-definitions include the key elements of the new index. Just adding that option to the end of the example provided by @notionquest should do the trick.
aws dynamodb update-table --table-name <tableName> --global-secondary-index-updates file://gsi-command.json --attribute-definitions AttributeName=<attributeName>, AttributeType=<attributeType>