多租户应用迁移AWS场景下DynamoDB单表设计方案咨询
DynamoDB 单表设计方案(适配多租户层级业务)
基础表配置
- 表名可自定义,示例:
MultiTenantBizDB - 主键采用复合主键:分区键(PK)字段为
PK,排序键(SK)字段为SK - 可按需开启DynamoDB流,用于客户累计交易数、门店交易数等聚合字段的异步更新
核心实体存储规则(PK/SK定义)
组织(Organisations)
- PK值:
ORG#<OrganisationID> - SK值:
#METADATA#<OrganisationID> - 存储其余业务字段:
name、owner、createdAt,无需预存门店列表字段,可通过查询直接获取,避免写入放大
门店(Outlets)
- PK值:
ORG#<OrganisationID> - SK值:
OUTLET#<OutletID> - 存储其余业务字段:
outletName、customerCount、transactionCount、createdAt
客户(Customers)
- PK值:
CUST#<CustomerID> - SK值:
#METADATA#<CustomerID> - 存储其余业务字段:
organisationID、outletID、firstName、lastName、email、totalTransactions、totalSpent、createdAt
交易记录(Transactions)
- PK值:
CUST#<CustomerID> - SK值:
TXN#<createdAt>#<TransactionID> - 存储其余业务字段:
transactionID、organisationID、outletID、type、value、createdAt
全局二级索引(GSI)配置
用于覆盖主表无法直接支持的多维度查询需求
GSI1(门店维度索引)
- 分区键字段:
GSI1PK,排序键字段:GSI1SK - 各实体字段赋值规则:
- 门店实体:
GSI1PK = OUTLET#<OutletID>,GSI1SK = #METADATA#<OutletID> - 客户实体:
GSI1PK = OUTLET#<OutletID>,GSI1SK = CUST#<CustomerID> - 交易记录实体:
GSI1PK = OUTLET#<OutletID>,GSI1SK = TXN#<createdAt>#<TransactionID>
- 门店实体:
GSI2(客户检索索引)
- 分区键字段:
GSI2PK,排序键字段:GSI2SK - 仅客户实体赋值该索引字段,做多租户隔离:
GSI2PK = ORG#<OrganisationID>- 姓名检索场景赋值:
GSI2SK = <lastName>#<firstName>#<CustomerID> - 邮箱检索场景赋值:额外新增倒排项,
GSI2SK = EMAIL#<email>#<CustomerID>,查询时指定前缀即可匹配
访问模式对应实现方案
- 根据客户ID查询客户详情:主表直接查询,
PK = CUST#<客户ID>,SK = begins_with("#METADATA#")返回单条客户记录 - 按客户姓名或邮箱搜索客户:GSI2查询,指定分区键为
ORG#<对应组织ID>,排序键前缀匹配搜索内容即可,例:搜索姓名为李四的客户,GSI2SK = begins_with("李#四#");搜索邮箱为xxx@xx.com的客户,GSI2SK = begins_with("EMAIL#xxx@xx.com#") - 查询指定门店下的所有客户:GSI1查询,
GSI1PK = OUTLET#<门店ID>,GSI1SK = begins_with("CUST#")返回该门店全量客户 - 查询指定客户的所有交易记录:主表查询,
PK = CUST#<客户ID>,SK = begins_with("TXN#")返回该客户所有交易,默认按交易时间排序 - 查询指定门店的所有交易记录:GSI1查询,
GSI1PK = OUTLET#<门店ID>,GSI1SK = begins_with("TXN#")返回该门店全量交易 - 查询指定门店在指定时间段内的交易记录:GSI1查询,
GSI1PK = OUTLET#<门店ID>,加排序键范围条件:GSI1SK between "TXN#<起始时间戳>#" and "TXN#<结束时间戳>#"返回对应时间段交易 - 查询指定组织下的所有门店:主表查询,
PK = ORG#<组织ID>,SK = begins_with("OUTLET#")返回该组织下所有门店 - 根据门店ID查询门店详情:GSI1查询,
GSI1PK = OUTLET#<门店ID>,GSI1SK = begins_with("#METADATA#")返回单条门店详情;若已持有对应组织ID,也可直接主表查询PK = ORG#<组织ID>+SK = OUTLET#<门店ID>,性能一致
内容的提问来源于stack exchange,提问作者chinds
相关产品推荐
相关产品推荐

