小编典典

如何在多个表之间实施唯一性

sql

我在MySQL服务器中有以下表格:

Companies:
- UID (unique)
- NAME
- other relevant data

Offices:
- UID (unique)
- CompanyID
- ExternalID
- other data

Employees:
- UID (unique)
- OfficeID
- ExternalID
- other data

在每个数据库中,UID是唯一的标识符,由数据库创建。

有一些外键可以确保UID上的Employee-> Office-> Company之间的链接。

办公室和员工中的ExternalID字段是公司(实际上是我的客户)提供给我的应用程序的ID。客户端没有(也不在乎)我自己的ID,而我的应用程序从他们那里收到的所有数据仅根据其ID(即我的表中的ExternalID)进行标识。

即来自客户端的伪语言请求就像“我是X公司,为我的员工Y更新数据”。

我需要对CompanyID和Employees.ExternalID的组合实施唯一性,因此在我的数据库中,同一公司的员工不会有重复的ExternalID。

我在考虑3种可能的解决方案:

  1. 更改雇员的架构以包括CompanyID,并在两个字段上创建唯一约束。

  2. 强制执行触发器,该触发器在员工中更新/插入后将验证唯一性。

  3. 在应用程序级别(即我的接收服务)上执行检查。

我的替代dbadmin-in-me说(3)是最糟糕的解决方案,因为它不会保护数据库在应用程序错误或其他情况下的不一致性,并且很可能是最慢的解决方案。

触发器解决方案可能是我想要的,但它可能会变得复杂,尤其是如果需要在单个语句中执行多个插入/更新,而我不确定性能与(1)相比。

并且(1)看起来是最快,最简单的方法,但是这与我对关系模型的理解背道而驰。

SO
DB专家的意见是关于每种方法的利弊的,特别是如果有可能添加额外的间接级别(即公司->办公室->部门->员工)并且需要保留相同的唯一性时,尤其如此(公司员工)。


阅读 190

收藏
2021-04-22

共1个答案

小编典典

您是对的-#1是最好的选择。
当然,我会一眼就质疑它(因为快捷方式),但是知道确保员工仅与一家公司相关的业务规则-这是有道理的。

另外,我还有一个外键,将雇员表中的公司编号与办公室表中的公司编号相关联。否则,您允许员工与没有办公室的公司建立联系。除非那是可以接受的…

如果无法在数据模型中证明这种关系,则触发器是万不得已的方法,并且从应用程序提供逻辑服务意味着逻辑是集中的-
除非有人放弃约束(这意味着您有更大的问题,否则没有发生坏数据的​​机会) )。

2021-04-22