我有一个访问大量JSON数据的Web应用程序。
我想使用键值数据库来存储Web应用程序的不同用户(不是数据库用户)拥有/共享的JSON数据。每个用户应该只能访问他们拥有或共享的记录。
在关系数据库中,我会在记录表中添加一列Owner
,或者在一个单独的表中管理共享所有权,并在应用程序端检查访问权限(Python)。对于关键价值商店,我想到了两种方法。
如果我使用USERID_RECORDID
之类的密钥然后在访问记录之前编写代码来检查USERID
该怎么办?这是一个好主意吗?它不适用于用户之间共享的记录。
我可以在值数据中存储一个或多个USERIDs
,并检查数据是否包含尝试访问记录的用户的ID。性能可能比将用户ID作为密钥的一部分要慢,但共享所有权是可能的。
答案 0 :(得分:2)
您描述的两种解决方案都有一些限制。
您指出,在密钥中包含所有者ID并不能解决共享数据的问题。但是,如果您添加另一个键/值对,则此解决方案可能是可接受的,其中包含与此用户(key: userId:shared, value: [id1, id2, id3...])
共享的内容的ID。
您的第二个提案,其中包括被授予对给定内容的访问权限的用户列表,当且仅当您的应用程序需要进行查询以检索有权访问的用户列表时才可以一个特定的内容。如果您需要列出给定用户可以访问的所有内容,此设计将导致您的性能不佳,因为K / V商店将必须扫描所有记录 - 这种类型的数据库引擎通常不允许您创建一个索引来优化这种请求。
从更一般的角度来看,对于NoSQL数据库,尤其是Key / Value存储,必须根据应用程序的请求来定义模型。它可能会导致您复制一些信息。应用程序负责维护数据的一致性。
例如,如果您需要获取给定用户的所有内容,无论该用户是内容的所有者还是与他共享这些内容,我建议您为该用户创建一个密钥,其中包含正如我已经说过的那样,该用户的内容ID。但是,如果您的应用还需要获取允许访问给定内容的用户列表,则应在此内容的字段中添加其ID。这将导致类似于:
key: contentID, value: { ..., [userId1, userID2...]}
当您删除对用户的给定内容的访问权限时,您的应用(而不是数据存储区)必须从内容值中删除userId,并从该用户的内容列表中删除contentId。
此设计可能意味着您的应用会发出多个请求:例如,一个用于获取允许访问给定内容的用户ID列表,以及一个或多个用于获取这些用户配置文件的用户ID。然而,这不应该是一个问题,因为K / V商店通常具有非常高的性能。