DynamoDB表设计、索引选型及异构数据存储问题咨询
DynamoDB表架构与索引设计问题解答
问题1:LSI相关疑问与现有设计优化
LSI适用场景
LSI(本地二级索引)适合同一份主表数据需要按多个维度排序查询的场景,且这些查询都是围绕主表的HASH键展开的。比如主表主键是User-ID(HASH)+ Order-Date(RANGE),如果需要按Order-Amount排序查询某个用户的所有订单,就可以创建一个以User-ID为HASH、Order-Amount为RANGE的LSI——它和主表共享存储分区,延迟更低,适合高频的同HASH键下多维度排序查询。
无排序键能否创建LSI?
是的,主表没有排序键(仅HASH主键)的话无法创建LSI。因为LSI的结构是「主表HASH键 + 自定义RANGE键」,必须依赖主表的HASH+RANGE主键结构才能创建。
成本理解是否正确?
这个理解完全正确:
- LSI没有额外存储和读写成本,它和主表共享存储容量,读写操作消耗的是主表的RCU/WCU;
- GSI是独立的物理表,有自己的存储容量和读写配额,会产生额外的存储和读写成本。
现有设计优化点
- 调整主表主键贴合高频查询:如果
User-ID+Brand是核心查询路径,可以把主表主键改为User-ID(HASH)+Brand(RANGE),直接用主表就能满足该查询需求,无需额外创建GSI_1,节省GSI成本;原唯一ID可作为普通属性保留,用于全局唯一查询。 - 优化GSI_2的结构:GSI_2仅用
Car-Reference作为HASH键,若后续有按Car-Reference+其他属性(如Create-Date)排序查询的需求,可提前给GSI_2添加RANGE键,避免后续修改索引的运维成本。 - 评估唯一ID的必要性:如果业务上没有必须用全局唯一ID查询的场景,可考虑去掉该主键,进一步简化表结构。
问题2:统计数据存储与区分查询
存入现有表是否合理?
完全合理。DynamoDB的宽表设计就是为了支持将不同类型的实体数据存储在同一张表中,这样可以减少表的数量,降低管理成本和运维复杂度,同时利用已有的索引能力,是降本的有效方案。
如何区分车辆信息行与统计行?
可以通过新增**InfoType属性**来区分两类数据:比如车辆信息行的InfoType设为vehicle,统计数据行的InfoType设为stats。在此基础上,有两种高效实现区分查询的方式:
- 调整GSI_1的RANGE键:将GSI_1的RANGE键改为
Brand#InfoType(把品牌和类型拼接成一个字符串,比如Toyota#vehicle、Toyota#stats)。查询时指定User-ID(HASH)+ 对应的Brand#InfoType(RANGE),就能精准筛选目标数据,避免过滤操作消耗额外RCU。 - 保留原有GSI结构,搭配FilterExpression:如果不想修改现有GSI,可在查询
User-ID+Brand时添加FilterExpression: InfoType = :type,指定要查询的类型(vehicle或stats)。不过这种方式会先查询出该User-ID+Brand下的所有数据再过滤,会消耗更多RCU,适合数据量较小的场景。
补充:统计数据行的主键(唯一ID)可设计为
user-{User-ID}-brand-{Brand}-stats这类格式,既保证全局唯一性,也能直观体现数据类型。
内容的提问来源于stack exchange,提问作者Safari
相关产品推荐
相关产品推荐

