使用DynamoDB

时间:2015-09-15 11:59:46

标签: rest authentication database-design amazon-dynamodb data-modeling

我正在寻找一些最佳实践,一般是对机密分层数据进行建模,特别是使用DynamoDB。

最好用一个例子来解释这个场景: 假设我们有一些users。每个user都有products个。每个product都包含多个parts

典型用例:

  • 列出给定products
  • 的所有user
  • 列出给定parts
  • 的所有product

到目前为止,我已经在DynamoDB中对此进行了这样的建模:

Users
----------------
HashKey:  UserId


Products
-------------------
HashKey:  UserId
RangeKey: ProductId


Parts
-------------------
HashKey:  ProductId
RangeKey: PartId

数据是保密的,可通过经过身份验证的REST端点访问,其中身份验证令牌可以映射到UserId。允许每个用户 通过某些组概念查看其他用户的数据。

列出给定用户的所有产品很简单,因为UserId是产品表中的关键字:

GET /users/111/products变为简单的Query(Table=Products, UserId=111)

但请考虑列出给定产品的所有部分的情况:

GET /users/111/products/222/parts

如果我只是做一个Query(Table=Parts, ProductId=222),那么我将快速获得所需的数据,但我不会保护其他用户查询属于用户111的数据,只要他们知道ProductId 222(实际上,ID:s当然是UUID:s或类似的,所以不容易猜到):

GET /users/119/products/222/parts

...将导致恶意用户119检索不属于他的数据,前提是没有做任何事情来解决这个问题。 所以在这里我想我需要做一些像这样的事情:

  1. 首先进行另一个查询以确保产品222实际上属于给定用户
  2. 复制零件表中的UserId并将其包含在查询条件中(这基本上意味着它在扫描时将匹配所有行或行通过ProductId标识的集合:Query(Table=Parts, ProductId=222, UserId=111)
  3. 在Parts表中也使用UserId作为哈希键,而不是将ProductId作为二级索引
  4. UserId_ProductId
  5. 上使用Parts(“111_222”)等复合HashKey

    如果我需要返回401而不是空数据,则选项1似乎是唯一的方法。但是,如果我们想象一个更深层次的数据,例如“具有带有附件的部分的消息的收件箱的用户”似乎这种方法最终可能很昂贵(列出部分P的所有附件可能导致查询以检查部分P属于消息M,消息M属于收件箱I和那个收件箱我属于用户U,依此类推。)

    对于哪种方法最有利,有没有人有任何好的论据?或者我做了一些愚蠢的事情,应该完全以其他方式对我的数据进行建模?

0 个答案:

没有答案