在Bigtable中建模正向和反向查询问题

时间:2018-12-11 20:07:21

标签: database google-cloud-platform bigtable google-cloud-bigtable

假设我们具有以下三个实体:

Organization
 - id

Role
 - id

Member
 - id

可以将角色授予组织中的成员,从而为该成员授予对该组织的某些访问控制权限。 我希望能够回答以下两个查询

  1. 列出在给定组织内具有给定角色的所有成员的ID(例如,给定一个Role ID和Org ID会给我列出成员列表)。
  2. 列出成员在给定组织内已被授予的所有角色的ID(例如,给定成员ID和组织ID会给我列出角色列表)。

我正在尝试找到有关如何在Bigtable中对此建模的建议(理想情况下是为原子突变设置一行)...我也愿意接受其他技术建议(我正在尝试在我自己的约束范围内进行设计公司给了我)。


如果我们使用Bigtable行键org#{orgID}#role#{roleID}#member#{memberID}为上述关系建模,我可以轻松回答第一个问题。但是,它不允许我轻松地回答第二个问题。如果我复制数据并存储另一个行键org#{orgID}#member#{memberID}#role#{roleID},则可以轻松回答第二个问题,但是现在我要管理两行,并且无法保证两者之间的原子更新,因此可能导致一致性问题。 / p>

社区中有人遇到过类似的问题吗?如果是这样,您如何解决呢?

2 个答案:

答案 0 :(得分:3)

Cloud Bigtable本身不支持二级索引,这就是您只需要一行并且能够有效地运行这两个查询而无需全表扫描的需求。您已经确定的替代方法是通过确保最终一致性的过程编写两行。这可能足以满足您的需求,具体取决于系统的基本要求。

根据您的约束(云提供商,数据规模,原子性,多区域复制等),最好使用标准关系数据库(例如Postgres,MySQL)或Google Cloud Spanner。< / p>

使用Spanner可能的方法来完成此任务:

  • 具有一个表示成员<->角色关系的表。将RoleID作为该行的主要索引,然后为MemberID添加一个Secondary Index,您就可以对其中任何一个运行查询。

  • 采用具有Member,Role和MemberRole连接表的传统关系数据库路由。使用Spanner,您应该通过Transaction进行原子更新。查询时,可能会遇到跨多个拆分的读取问题,但是您必须进行一些实际测试才能查看性能。

答案 1 :(得分:3)

披露:

  • 我负责Cloud Bigtable的产品管理。
  • 我与人共同创建了JanusGraph项目。

通读您的问题陈述,听起来您想使用关系数据库或图形数据库。每个人都有自己的优点/缺点。

关系DBMS方法

his answer中Dan所述,您可以通过Google Cloud SQLGoogle Cloud Spanner使用托管的MySQL或PostgreSQL,具体取决于您对规模,复制,一致性,与现有代码的兼容性的需求。 / frameworks等。

图形数据库方法

或者,您可以使用graph database,它可以帮助您轻松地对此信息进行建模并有效地对其进行查询。

例如,您可以部署Janusgraph on GKE with Bigtable and Elasticsearch并使用Gremlin language查询数据,each vertex in a separate row in Bigtable是许多图形数据库支持的标准图形遍历/查询语言。

请注意,JanusGraph + Bigtable继承了Bigtable的事务性(如您所述,它是行级原子的)。由于JanusGraph存储different storage backend,因此仅单顶点更新将是原子更新。如果您想通过JanusGraph进行交易更新,则可能需要使用FoundationDB,例如

  • BerkeleyDB(本地非分布式存储后端)
  • many(JanusGraph社区的最新贡献)

您可以考虑使用other Neo4j on GCP个图形数据库,其中一些还支持Gremlin或其他图形查询语言。例如,您可以根据需要部署try_emplace(),它支持Gremlin和Cypher。