我们有一个REST API,其中一部分显示用户的“目录”。目录是产品列表以及一些总体目录元数据(例如剩余的金额)。
我们正处于尝试将此元数据添加到目录响应的阶段,但却陷入了我们的数据库设计。支持商店是亚马逊的DynamoDB,它只是一个键值商店。值得注意的是,它支持主键(“哈希”)和辅助键(“范围”)。
目前我们的数据库条目如下:
{ customerId: "xxx", productId: "yyyy", productPrice: "zzz" }
我们可以或多或少地将这些直接转换为商品,这会产生
的响应{ products: [{ id: "yyyy", price: "zzz" }] }
但我们现在想要一个带元数据的回复,比如
{ metadata: { moneyLeft: 5 }, products: [{ id: "yyyy", price: "zzz" }] }
问题是,我们如何在我们的数据库中存储元数据?
方法#1:单独的数据库
使用主键customerId
创建单独的元数据表,并为所有元数据属性创建列。然后查询两个表(两个HTTP请求到DynamoDB),并汇总结果。
方法#2:面向查询
将当前表重新调整为专为此目录显示查询而设计。它将有两种类型的行,例如
{ customerId: "xxx", productId: "yyyy", productPrice: "zzz", type: "product" }
{ customerId: "xxx", moneyLeft: 5, type: "metadata" }
(虽然有点健壮)。然后我们可以执行查询以使用customerId = xxx
从表中选择所有行,并在我们的服务器代码中通过启用type
属性将它们转换为所需的响应。
我倾向于方法#2,因为似乎方法#1仍然停留在关系数据库思维中,并且它将涉及两个数据库调用(= HTTP请求)。但这太奇怪了,我不确定这是个好主意。也许还有第三种方法?我想真正的答案是“你应该使用文档数据库”,但到目前为止我们已经非常致力于DynamoDB了。
答案 0 :(得分:0)
桌子的范围键是什么?我假设哈希键是customerId ...
总的来说,在考虑NoSQL解决方案时,我发现自己在想“我要查询的内容”
如果您的查询始终是“查询所有带有customerId = XXX的项目”,那么我认为在那里放置另一个“元数据”项目是不好的设计。
更加强大和浪费的方法是将元数据连接到所有项目,但在更新方面它有自己的缺点。 (我也不推荐它)
我认为即使这听起来像是一种关系方法,在你的场景中我会坚持使用另一张桌子
此外,通过部分理解您的数据库,我仍然认为在不实际查询其目录的情况下查询用户的元数据是有意义的。