多租户

通过为多个客户组织(称为租户)提供单独的数据分区,您可以在应用中支持“多租户”。如此,您可以为每个租户自定义“数据值”,同时为所有租户使用相同的“数据架构”。这还提高了预配新租户的效率,因为在添加租户时无需更改数据结构。

多租户的优势

通过 Datastore 模式 Firestore,多租户应用可为每个租户分别使用数据孤岛,同时仍可确保以下几点:

  • 使用单个项目
  • 针对种类使用单个逻辑结构
  • 使用单个索引定义集,因为从逻辑角度来看,种类对于每个租户而言都是相同的

Datastore 模式通过提供“命名空间”实现多租户

多租户和分区数据

Datastore 模式使用“分区”来隔离每个租户的数据。每个分区用分区 ID 标识,分区 ID 由项目 ID 和命名空间 ID 组成。一个实体属于单个分区,查询范围也限定为单个分区。

为实体指定命名空间

在创建实体时指定命名空间:创建实体后,将无法更改命名空间。如果没有为实体明确指定命名空间,则会自动给实体分配“默认命名空间”,该命名空间没有字符串标识符

使用父实体的命名空间

一个实体及其所有祖先实体属于且仅属于一个命名空间。这意味着当您使用另一个指定为父实体的实体创建实体时,子实体将位于其父实体所在的命名空间中:您无法指定其他命名空间。

示例用例

多租户的一个主要优势是使同一应用为多个客户组织提供服务。为了实现这一优势,对于给定种类,应用在任何命名空间都应该具有相同的行为。例如,从应用的角度来看,一个命名空间中 Task 种类的实体在逻辑上应与所有其他命名空间中 Task 种类的实体相同。这样,应用便可使用单个索引定义集来支持 Task 查询,而不管哪些命名空间包含 Task 实体。

例如,假设某个任务列表应用为每个用户建立数据孤岛。该应用可以根据用户名定义命名空间,从而生成以下分区:

Partition ID: project:"my_project_id"/namespace:"Joe"
Partition ID: project:"my_project_id"/namespace:"Alice"
Partition ID: project:"my_project_id"/namespace:"Charlie"

应用可以按照以下方式定义 Task 种类的逻辑结构,以用于所有命名空间:

kind: Task
properties:
 - "done", Boolean
 - "created", DateTime
 - "description", String, excluded from index

当用户创建 Task 种类的实体时,实体将存储在用户自己的分区中,从而在孤岛中生成数据。应用在各命名空间中一致地处理 Task 实体,因为对于 Task 种类只使用一种架构。具有孤岛数据和一致行为的应用便是多租户应用。

如果在不同的命名空间中,Task 种类的逻辑结构有所不同,则该应用不是多租户应用,因为它在各命名空间中以不同方式处理 Task 实体。例如,假设 Task 种类具有基于命名空间的不同架构:

  • Joe 命名空间中的 Task 实体从索引中排除 description 属性
  • Alice 命名空间中的 Task 实体在索引中包含 description 属性

应用可以为 Alice 的 Task 实体查询 description 属性,但是无法为 Joe 的 Task 实体查询 description 属性,因此该应用不是多租户应用。

在控制台中查看命名空间

如需查看项目中使用的命名空间的统计信息,请访问 Google Cloud 控制台中的 Datastore 信息中心页面。如需以编程方式确定项目中使用了哪些命名空间,请参阅命名空间查询

如果需要将租户内的数据分组,您可以按种类将数据分类,也可以整理与实体组高度相关的数据。

后续步骤