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

Modeling Forward and Reverse Query Questions in Bigtable

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

Organization
 - id

Role
 - id

Member
 - id

可以将角色运行分配给组织内的成员,从而赋予该成员对该组织的某些访问控制权限。 我希望能够回答以下两个问题:

  1. 列出在给定组织中具有给定角色的所有成员的 ID(例如,给定角色 ID 和组织 ID 给我成员列表)。
  2. 列出某个成员在给定组织中被赋予的所有角色 ID运行(例如,给定一个成员 ID 和组织 ID 给我角色列表)。

我正在尝试寻找有关如何在 Bigtable 中对此进行建模的建议(理想情况下,原子突变只有一行)...我也对其他技术建议持开放态度(我正在尝试在限制我的公司给我)。


如果我们使用 Bigtable 行键 org#{orgID}#role#{roleID}#member#{memberID} 对上述关系建模,我可以轻松回答第一个问题。但是,它不允许我轻松回答第二个问题。如果我复制数据并存储另一个行键 org#{orgID}#member#{memberID}#role#{roleID} 那么我可以很容易地回答第二个问题,但是现在我有两行要管理并且原子更新不能在两者之间进行 gua运行teed,所以可能导致一致性问题。

社区中是否有人 运行 遇到过类似的问题,如果有,您是如何解决的?

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

根据您的限制条件(云提供商、数据规模、原子性、多区域复制等),您可能最好使用标准关系数据库(例如 Postgres,MySQL),或者 Google Cloud Spanner.

使用 Spanner 实现此目的的可能方法:

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

  • 走Member、Role和MemberRole加入的传统关系数据库路线table。使用 Spanner,您应该通过 Transaction 进行原子更新。在查询时,您可能会遇到跨多个拆分的读取问题,但您必须进行一些真实世界的测试才能了解您的性能。

披露:

  • 我领导 Cloud Bigtable 的产品管理。
  • 我共同创立了 JanusGraph 项目。

通读你的问题陈述,我听起来你想使用关系数据库或图形数据库。每个人都会有自己的 pros/cons.

关系型 DBMS 方法

正如 Dan 在 , you can use a managed MySQL or PostgreSQL via Google Cloud SQL, or Google Cloud Spanner 中提到的,取决于您对规模、复制、一致性、与现有 code/frameworks 的兼容性等方面的需求

图数据库方法

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

例如,您可以部署Janusgraph on GKE with Bigtable and Elasticsearch and query the data using the Gremlin language,它是许多图形数据库支持的标准图形traversal/query语言。

请注意,JanusGraph + Bigtable 继承了 Bigtable 的事务性(如您所述,它是行级原子的)。由于 JanusGraph 存储 each vertex in a separate row in Bigtable, only single-vertex updates will be atomic. If you want transactional updates via JanusGraph, you may need to use a different storage backend,例如

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

many other graph databases you can consider, some of which also support Gremlin or other graph query languages. For example, you can deploy Neo4j on GCP 如果你愿意,它支持 Gremlin 和 Cypher。