在数据库表中实现唯一性

时间:2014-05-02 20:09:50

标签: database oracle database-design oracle11g relational-database

我正在为具有以下要求的现有系统开发多租户数据库:

  • 租户有一对多实体。
  • 实体可能只属于一个租户。
  • 实体具有一个全局唯一标识符。
  • 实体具有一对多唯一别名。
  • 实体具有其他非唯一属性。
  • 对于任何给定的租户,别名可能只存在一次。

为了帮助说明,以下实体都是有效的:

|-------------------------------------|
| 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" |
|---------------------------------------------------------------------------------------------|

这方面的关键挑战是“对于任何给定的租户,别名可能只存在一次”。需求。如果没有这个,设计将如下所示:

Option 1

但是,这种方法不允许在TENANT + ALIAS上放置唯一索引。这可能是需要unique constraint to span multiple columns的另一种情况,这在技术上是不可能的。

其他几个主题似乎触及了这一点,但没有描述完全相同的情况:

下面列出了一些其他选项,每个选项都有一些缺点。我最初的目标是Oracle 11g,但理想情况下,如果可能的话,设计中不会使用专有的DBMS结构。此外,此时只有一个应用程序将使用数据库,因此可以强制执行某些要求,但同样,这也不是理想的。

选项1

Option 1

如上所述,这违反了“对于任何给定的租户,别名可能只存在一次。”

选项2

Option 2

这种方法有效,虽然感觉有点沉重,但拖拉租户和已经唯一的实体ID。

选项3

Option 3

这种方法可行,但不强制要求“实体可能只属于一个租户”。应用程序代码可以在必要时防止这种情况发生,但理想情况下,我甚至根本不在数据库中允许这种可能性。例如,此方法允许以下无效实体,其中单个实体在其他租户中具有别名:

|-------------------------------------|
| Tenant   | Entity ID | Entity Alias |
|-------------------------------------|
| tenant-A | entity-1  | entity-a     |
| tenant-B | entity-1  | entity-b     |
|-------------------------------------|

选项4

Option 4

这种方法将允许看似合适的“选项1”设计,但使用Oracle物化视图有效地连接表并允许在它们之间应用唯一性约束。这种方法似乎有效,虽然我对物化视图没有任何过去的经验,所以我可能需要做一些进一步的测试,以确保我不会忽视任何其他问题。已知的缺点是这是特定于Oracle的,物化视图确实有一些固有的缺点,例如需要额外的磁盘空间,并且可能会对插入/更新的性能产生一些影响,因为视图也需要更新。

选项5

选项5将使用“选项1”或“选项3”以及一些触发器来强制执行缺失的要求。我希望尽可能不使用触发器,因为它们也可能有点沉重,可能是特定于DBMS的,并且不太可能是管理需求的最有效方法。

摘要

从表面上看,这似乎不应该是一个独特或难以解决的问题,但没有一个选项感觉非常合适。此时,我倾向于选项2 或者选项3 ,但我还是不相信。有一个简单的选择,或者我可以忽略的解决方案吗?

1 个答案:

答案 0 :(得分:0)

我们最后继续使用选项2 ,以便TENANT_IDENTITY都包含ENTITY_ALIAS。这似乎是最安全的方法,满足数据模型的所有要求,并且几乎没有缺点。此外,这种方法提供了最佳基础,如果合适,我们可以在此基础上轻松迁移到任何其他方法。

enter image description here