【问题标题】:SQL schema design with foreign key constraint for tenants租户外键约束的 SQL 模式设计
【发布时间】:2017-01-05 21:04:42
【问题描述】:

我正在设计一个用于多租户场景的数据库。 我最近了解到,为了强制在相互引用的表之间保持租户 ID 一致,我需要让表的主键同时包含表 ID 和租户 ID。然后,外键必须同时引用表 ID 和租户 ID。

这似乎按预期工作,但如果我有不引用租户的表怎么办?在下面的示例中,我有一个不直接引用租户的 playlist_item。我在这里看到的一个问题是 playlist_item 可能会引用与其所属的播放列表不具有相同租户的内容。

一种可能的解决方案是将tenant_id 包含在数据库中存在的所有表中,以便能够一直引用租户,但这对我来说似乎有点麻烦,因为 playlist_item(在这种情况下)已经通过其与播放列表的所有者关系隐含了tenant_id。

我希望能深入了解在这种情况下什么是一个好的解决方案,以及是否有任何替代方法可以实现相同的目标,而不会出现数据不一致的潜在风险。

(这只是一个示例,不是实际的数据库)

【问题讨论】:

  • 被引用的列(在外键关系中)必须始终在被引用的表中形成唯一键(PostgreSQL 中的主键或唯一约束)。所以你实际上不能创建上面的例子,除非idplaylistcontent 的主键。如果它是唯一约束,那么它“只是”主键的一部分是没有意义的(因为它本身就是唯一的)。换句话说:您应该决定哪些实体可能具有重叠的 ID(跨租户)。您的 user 表 f.ex。可能有。
  • 你是对的,我还需要在表 id 上有一个唯一索引。结果是:主键(id,tenant_id)和唯一(id)。对吗?
  • 这在技术上是可行的,但主键应该始终是唯一的最小列集。因此,一种可能性是使用id 作为主键创建表,并将tenant_id 包含到其中的 一些 中(如果它们可以通过另一个外键连接到租户,则不需要) 或在任何地方使用 id + tenant_id 主键。

标签: sql database postgresql database-schema multi-tenant


【解决方案1】:

这里有两个基本选项。

首先是添加额外的外键和唯一约束,其中包括 tenant_id,如果这样做,您可以确保全面引用同一个租户。如果您想使用行级安全策略,请执行此操作,因为它会解决检查安全性时的一系列性能问题。

在这种情况下,播放列表将在 (id, tenant_id) 上具有第二个唯一索引,而 playlist_item 将在 (playlist_id, tenant_id) 上具有引用该索引的外键。

您的第二个选择是将tenant_id 删除它被传递引用的位置。在这种情况下,您始终可以通过连接查找它,但在绑定使用行级安全性时效果不佳。

【讨论】:

    猜你喜欢
    • 2013-01-30
    • 2017-03-21
    • 2013-04-10
    • 2017-06-17
    • 1970-01-01
    • 1970-01-01
    • 2012-02-24
    • 2011-12-11
    • 1970-01-01
    相关资源
    最近更新 更多