支持多维度查询排序的DynamoDB JobOffer表设计咨询
DynamoDB JobOffer 表最优设计方案
所有设计完全覆盖你列的5类访问需求,全程用Query实现,无Scan操作,不提前加冗余的country字段,兼顾当前单国家业务场景和后续扩容需求。
基表核心配置
基表采用复合主键结构,不需要配置任何本地二级索引(LSI):
- 分区键(PK):
offer_id(字符串类型),存储全局唯一的职位ID,直接匹配「获取单个JobOffer详情」的需求,单条查询直接指定PK等值条件即可,延迟稳定在个位数毫秒。 - 排序键(SK):
sk(字符串类型),固定存值"OFFER"即可,属于预留字段,后续如果要给职位挂载投递记录、面试安排等关联数据,不用改表结构直接复用同一张表即可。
关于LSI的说明:LSI必须和基表共用相同分区键,且仅能在创建表时同步创建,后续无法增删改,适用场景极窄。你的业务里除了单条职位查询,其他所有查询的过滤维度都和
offer_id无关,LSI完全派不上用场,全部查询能力用全局二级索引(GSI)实现即可,灵活度更高,后续随时可以新增GSI不影响线上业务。
全局二级索引(GSI)配置
单表默认支持20个GSI,以下8个GSI完全在配额内,所有GSI投影模式统一设为ALL,查询时不需要回表拉取数据,性能更高:
- GSI1(公司维度-发布时间排序)
- 分区键:
company_id(字符串,职位所属公司的唯一ID) - 排序键:
publish_time(数字类型,存毫秒级Unix时间戳) - 覆盖场景:查询指定公司下的所有职位,
ScanIndexForward设为false返回最新发布在前,设为true返回最早发布在前。
- 分区键:
- GSI2(公司维度-薪资排序)
- 分区键:
company_id - 排序键:
monthly_salary(数字类型,统一转换为税前月均薪资,单位为人民币元,不要存薪资区间字符串) - 覆盖场景:查询指定公司下的所有职位,
ScanIndexForward设为false返回薪资从高到低,设为true返回薪资从低到高。
- 分区键:
- GSI3(公司+城市维度-发布时间排序)
- 分区键:
company_city(字符串,写入时直接拼接公司ID和标准化城市值,比如COMP001#110000,城市用统一行政编码避免同地异名问题) - 排序键:
publish_time - 覆盖场景:查询指定公司下指定城市的职位,按发布时间新旧排序。
- 分区键:
- GSI4(公司+城市维度-薪资排序)
- 分区键:
company_city - 排序键:
monthly_salary - 覆盖场景:查询指定公司下指定城市的职位,按薪资高低排序。
- 分区键:
- GSI5(全平台维度-发布时间排序)
- 分区键:
shard_id(数字类型,写入时随机分配0~N范围内的整数值) - 排序键:
publish_time - 覆盖场景:跨所有公司查询全量职位,按发布时间排序。
- 分区键:
- GSI6(全平台维度-薪资排序)
- 分区键:
shard_id - 排序键:
monthly_salary - 覆盖场景:跨所有公司查询全量职位,按薪资高低排序。
- 分区键:
- GSI7(城市维度-发布时间排序)
- 分区键:
city(字符串,存标准化城市编码/名称) - 排序键:
publish_time - 覆盖场景:跨所有公司查询指定城市的职位,按发布时间新旧排序。
- 分区键:
- GSI8(城市维度-薪资排序)
- 分区键:
city - 排序键:
monthly_salary - 覆盖场景:跨所有公司查询指定城市的职位,按薪资高低排序。
- 分区键:
关键设计细节说明
全量查询的分区键解法
你之前纠结的无过滤条件全量查询的分区键问题,不要硬套业务字段(比如country),用逻辑分片键shard_id是标准解法:
- 初期分片数N按1-2年的业务预估设置即可,单分片控制数据量在5GB以内、读峰值在1000RCU以内就不会有热点问题。比如初期1年预估上线10万条职位,N设为5就足够;如果预估百万级数据,N设为20即可。
- 写入职位时给
shard_id随机赋一个0~N-1的整数,保证数据均匀分散到所有分片,不会出现单分区过热或者数据倾斜。 - 查询全量数据时,应用层并行发起N次
Query请求,每次指定一个shard_id值,拿到所有分片的返回结果后在应用层做归并排序,就能得到全局有序的结果,性能完全满足业务需求。后续数据量上涨直接扩大N的取值范围即可,老数据不需要迁移,完全兼容。 - 这个方案比你之前考虑的country字段方案灵活得多,没有冗余字段,也不会出现单分区承载全量数据的性能瓶颈,等后续真的支持多国家业务时,直接把GSI5/GSI6的分区键换成
country#shard_id即可,改造成本极低。
避坑提示
- 所有城市字段必须做标准化处理,统一用行政区域编码或者固定格式的字符串,不要同时存“北京”“北京市”“beijing”这类同地异名的值,否则会出现查询漏数。
shard_id必须随机生成,不要按写入顺序递增分配,否则会导致写请求集中在最新的分片上引发热点。- 薪资字段必须统一单位和口径做数值化存储,不要存“15k-20k”这类字符串,否则无法正确排序。
- 所有排序方向的切换不需要修改索引配置,直接调整
Query接口的ScanIndexForward参数即可,false为降序,true为升序。
内容的提问来源于stack exchange,提问作者Alex_Dms
相关产品推荐
相关产品推荐

