为租户设计具有外键约束的 SQL 模式

标签 sql database postgresql database-schema multi-tenant

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

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

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

对于这种情况下什么是好的解决方案,以及是否有任何替代方法可以实现相同目标而没有数据不一致的潜在风险,我将不胜感激。

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

Sample schema design

最佳答案

这里有两个基本选项。

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

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

您的第二个选择是在传递引用的地方删除 tenant_id。在这种情况下,您始终可以通过联接查找它,但在绑定(bind)使用行级安全性时,这会表现不佳。

关于为租户设计具有外键约束的 SQL 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41485558/

相关文章:

database - DBInputFormat多记录处理

javascript - Order By (alias) then Order by second sequelize

mysql - 开始新的更改操作之前缺少逗号。 (在 "CHARACTER SET"附近)

sql - 使用列值 postgresql 创建间隔

postgresql - 在 PostgresQL 中将整数转换为时间戳

sql - 如何在 Postgres 9.6+ 中生成长度为 N 的随机、唯一、字母数字 ID?

mysql - 我如何按 2 个值、项目数量和警报中位数进行排序(当项目低于此点时,他们会收到通知)

c# - 每种语言的 sitecore 中最受欢迎的项目。

mysql - 查询需要 30 多分钟 -- 我怎样才能加快速度? (包括解释和架构)

php - 并行 cron 作业选取相同的 SQL 行