您如何控制用户对键值数据库中记录的访问?

How do you control user access to records in a key-value database?

我有一个访问大量 JSON 数据的 Web 应用程序。

我想使用键值数据库来存储 Web 应用程序的不同用户(不是数据库用户)的 JSON 数据 owned/shared。每个用户应该只能访问他们拥有或共享的记录。

在关系数据库中,我会在记录 table 中添加一列 Owner,或者在单独的 table 中管理共享所有权,并在应用程序端检查访问权限( Python)。对于键值存储,我想到了两种方法。

作为密钥一部分的用户 ID

如果我使用像 USERID_RECORDID 这样的键,然后在访问记录之前编写代码来检查 USERID 怎么办?这是一个好主意吗?它不适用于用户之间共享的记录。

用户 ID 作为值的一部分

我可以在值数据中存储一个或多个 USERIDs 并检查数据是否包含尝试访问记录的用户的 ID。性能可能比将用户 ID 作为密钥的一部分慢,但共享所有权是可能的。

我想做的事情的典型模式是什么?

您描述的两种解决方案都有一些局限性。

  • 您自己指出,在密钥中包含所有者 ID 并不能解决共享数据的问题。但是,如果您添加另一个 key/value 对,包含与该用户共享的内容的 ID (key: userId:shared, value: [id1, id2, id3...])

  • ,则此解决方案可能是可以接受的
  • 当且仅当您的应用程序需要进行查询以检索用户列表时,您的第二个提案(其中包括被授予访问给定内容的用户列表)是可行的谁有权访问特定内容。如果您需要列出给定用户可以访问的所有内容,这种设计会导致性能不佳,因为 K/V 存储必须扫描所有记录 - 而这种类型的数据库引擎通常不允许您创建一个索引来优化这种请求。

从更一般的角度来看,对于 NoSQL 数据库,尤其是 Key/Value 存储,必须根据应用程序提出的请求来定义模型。它可能会导致您重复某些信息。应用程序有责任维护数据的一致性。

例如,如果您需要获取给定用户的所有内容,无论该用户是该内容的所有者还是与他分享了这些内容,我建议您为该用户创建一个密钥,包含正如我已经说过的,该用户的内容 ID 列表。但是,如果您的应用还需要获取允许访问给定内容的用户列表,您应该在该内容的字段中添加他们的 ID。这将导致类似的结果: key: contentID, value: { ..., [userId1, userID2...]}

当您删除用户对给定内容的访问权限时,您的应用(而不是数据存储)必须从内容值中删除 userId,并从该用户的内容列表中删除 contentId。

此设计可能意味着您的应用会发出多个请求:例如,一个请求获取允许访问给定内容的用户 ID 列表,一个或多个请求获取这些用户配置文件。然而,这应该不是真正的问题,因为 K/V 商店通常具有非常高的性能。