我正在为具有以下要求的现有系统开发多租户数据库:
为了帮助说明,以下实体都是有效的:
|-------------------------------------| | Tenant | Entity ID | Entity Alias | |-------------------------------------| | tenant-A | entity-1 | entity-a | | tenant-A | entity-1 | entity-b | | tenant-A | entity-1 | entity-c | | tenant-B | entity-2 | entity-a | |-------------------------------------|
但是,考虑到以下因素:
|-------------------------------------| | Tenant | Entity ID | Entity Alias | |-------------------------------------| | tenant-A | entity-1 | entity-a | |-------------------------------------|
以下实体无效:
|---------------------------------------------------------------------------------------------| | Tenant | Entity ID | Entity Alias | Reason | |-------------------------------------|-------------------------------------------------------| | tenant-B | entity-1 | entity-b | "entity-1" cannot belong to multiple tenants | | tenant-A | entity-2 | entity-a | "entity-a" is an alias already used within "tenant-A" | |---------------------------------------------------------------------------------------------|
这方面的关键挑战是“对于任何给定的租户,别名可能只存在一次”。需求。如果没有这个,设计将如下所示:
但是,这种方法不允许在TENANT + ALIAS上放置唯一索引。这可能是需要unique constraint to span multiple columns的另一种情况,这在技术上是不可能的。
其他几个主题似乎触及了这一点,但没有描述完全相同的情况:
下面列出了一些其他选项,每个选项都有一些缺点。我最初的目标是Oracle 11g,但理想情况下,如果可能的话,设计中不会使用专有的DBMS结构。此外,此时只有一个应用程序将使用数据库,因此可以强制执行某些要求,但同样,这也不是理想的。
如上所述,这违反了“对于任何给定的租户,别名可能只存在一次。”
这种方法有效,虽然感觉有点沉重,但拖拉租户和已经唯一的实体ID。
这种方法可行,但不强制要求“实体可能只属于一个租户”。应用程序代码可以在必要时防止这种情况发生,但理想情况下,我甚至根本不在数据库中允许这种可能性。例如,此方法允许以下无效实体,其中单个实体在其他租户中具有别名:
|-------------------------------------| | Tenant | Entity ID | Entity Alias | |-------------------------------------| | tenant-A | entity-1 | entity-a | | tenant-B | entity-1 | entity-b | |-------------------------------------|
这种方法将允许看似合适的“选项1”设计,但使用Oracle物化视图有效地连接表并允许在它们之间应用唯一性约束。这种方法似乎有效,虽然我对物化视图没有任何过去的经验,所以我可能需要做一些进一步的测试,以确保我不会忽视任何其他问题。已知的缺点是这是特定于Oracle的,物化视图确实有一些固有的缺点,例如需要额外的磁盘空间,并且可能会对插入/更新的性能产生一些影响,因为视图也需要更新。
选项5将使用“选项1”或“选项3”以及一些触发器来强制执行缺失的要求。我希望尽可能不使用触发器,因为它们也可能有点沉重,可能是特定于DBMS的,并且不太可能是管理需求的最有效方法。
从表面上看,这似乎不应该是一个独特或难以解决的问题,但没有一个选项感觉非常合适。此时,我倾向于选项2 或者选项3 ,但我还是不相信。有一个简单的选择,或者我可以忽略的解决方案吗?
答案 0 :(得分:0)
我们最后继续使用选项2 ,以便TENANT_ID
和ENTITY
都包含ENTITY_ALIAS
。这似乎是最安全的方法,满足数据模型的所有要求,并且几乎没有缺点。此外,这种方法提供了最佳基础,如果合适,我们可以在此基础上轻松迁移到任何其他方法。