如何为已有DynamoDB表设置三列GSI?是否需修改KeySchema?
解决DynamoDB GSI设置与控制台操作问题
首先明确:不需要修改原表的KeySchema。原表的主键(UserId作为HASH,Created作为RANGE)是主表的核心结构,全局二级索引(GSI)是附加的独立索引,完全不需要改动主表的键结构。
关于GSI的核心认知:为什么控制台只能设置两个键?
DynamoDB的GSI本身只支持最多两个索引键:一个必选的HASH键,一个可选的RANGE键。你提到的三个字段(UserId、TargetUserId、Created)不需要都作为索引键——可以把其中两个设为GSI的HASH/RANGE键,第三个字段通过**投影(Projection)**的方式包含到GSI中,这样查询GSI时就能直接获取该字段,无需回表查询主表。
如何设计符合需求的GSI?
具体的设计取决于你的查询场景,这里提供两种常见的方案:
方案1:按TargetUserId + Created查询(需要获取UserId)
如果你的主要查询需求是“根据TargetUserId和Created时间范围查询对应的UserId”,可以这样创建GSI:
- GSI的HASH键:
TargetUserId(注意要和字段的实际类型一致,比如数字用N,字符串用S) - GSI的RANGE键:
Created(和原表类型一致,S) - 投影设置:包含
UserId字段(或者直接投影所有字段)
方案2:按UserId + TargetUserId查询(需要获取Created)
如果你的查询需求是“根据UserId和TargetUserId查询对应的Created时间”,则GSI设计为:
- GSI的HASH键:
UserId(N类型) - GSI的RANGE键:
TargetUserId(对应类型) - 投影设置:包含
Created字段
控制台操作步骤(解决“只能设两个键”的困惑)
在AWS控制台操作时,步骤如下:
- 进入DynamoDB控制台,打开
Images表,切换到**“索引”**标签页。 - 点击**“创建索引”**,选择“全局二级索引”。
- 在“索引键”部分,设置你的GSI HASH键和RANGE键(比如
TargetUserId作为HASH,Created作为RANGE)。 - 滚动到“投影”部分:
- 如果你只需要第三个字段(比如
UserId),选择**“指定属性”**,然后在输入框中添加UserId; - 如果需要所有字段,直接选择**“所有属性”**;
- 若只需要主键相关字段,选择**“仅键”**。
- 如果你只需要第三个字段(比如
- 设置读写容量单位(和原表保持一致或按需调整),点击“创建索引”即可。
代码示例(用AWS CLI创建GSI)
如果用CLI操作,这里是一个创建TargetUserId-Created-Index的命令(假设TargetUserId是数字类型N):
aws dynamodb update-table \ --table-name Images \ --attribute-definitions AttributeName=TargetUserId,AttributeType=N \ --global-secondary-index-updates '[ { "Create": { "IndexName": "TargetUserId-Created-Index", "KeySchema": [ {"AttributeName": "TargetUserId", "KeyType": "HASH"}, {"AttributeName": "Created", "KeyType": "RANGE"} ], "Projection": { "ProjectionType": "INCLUDE", "NonKeyAttributes": ["UserId"] }, "ProvisionedThroughput": { "ReadCapacityUnits": 5, "WriteCapacityUnits": 5 } } } ]'
注意:如果TargetUserId之前没有在表的属性定义中声明,必须通过--attribute-definitions参数添加它的类型定义。
投影类型的选择建议
- ALL:最方便,查询GSI时无需回表,但会占用更多存储和写入吞吐量,适合字段较少或查询频繁的场景;
- INCLUDE:只投影需要的字段,平衡存储成本和查询效率,是大多数场景的首选;
- KEYS_ONLY:存储量最小,但查询时需要回表获取其他字段,适合只需要主键信息的查询。
内容的提问来源于stack exchange,提问作者Roman Newaza
相关产品推荐
相关产品推荐

