繁体   English   中英

如何在多个表中强制使用唯一身份验证

[英]How to enforce uniques across multiple tables

我在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. 更改Employees的架构以包含CompanyID,并在两个字段上创建唯一约束。

  2. 强制执行触发器,在Employees中更新/插入时验证唯一性。

  3. 强制检查应用程序级别(即我的接收服务)。

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

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

并且(1)看起来是最快速和最简单的方法,但有点违背我对关系模型的理解。

SO DB专家对每种方法的利弊有何看法,特别是如果有可能增加额外的间接水平 - 即公司 - >办公室 - >部门 - >员工,同样的独特性需要保留(公司职员)。

你是对的 - #1是最好的选择。
当然,我会乍一看(由于快捷方式),但了解业务规则以确保员工只与一家公司相关 - 这是有道理的。

另外,我有一个外键,将employee表中的companyid与office表中的companyid相关联。 否则,您允许员工与没有办公室的公司相关联。 除非那是可以接受的......

如果无法在数据模型中演示关系,触发器是最后的手段,并且从应用程序服务逻辑意味着逻辑是集中的 - 除非有人放下约束(这意味着你有更大的问题),否则不会有坏数据发生的机会)。

您公司提供的每个表都应该将CompanyID包含在公司提供的ID上的“UNIQUE KEY”中。

公司提供的参照完整性应使用公司提供的ID:

CREATE TABLE company (
        uid INT NOT NULL PRIMARY KEY,
        name TEXT
        );

CREATE TABLE office (
        uid INT NOT NULL PRIMARY KEY,
        companyID INT NOT NULL,
        externalID INT NOT NULL,
        UNIQIE KEY (companyID, externalID),
        FOREIGN KEY (companyID) REFERENCES company (uid)
        );

CREATE TABLE employee (
        uid INT NOT NULL PRIMARY KEY,
        companyID INT NOT NULL,
        officeID INT NOT NULL,
        externalID INT NOT NULL,
        UNIQIE KEY (companyID, externalID),
        FOREIGN KEY (companyID) REFERENCES company(uid)
        FOREIGN KEY (companyID, officeID) REFERENCES office (companyID, externalID)
        );

等等

将auto_increment_increment设置为您拥有的表的数量。 SET auto_increment_increment = 3; (你可能想在my.cnf中设置这个)

然后手动将每个表的起始auto_increment值设置为不同的值,第一个表为1,第二个表为2,第三个表为3

表1将具有1,4,7,10,13等值

表2将具有2,5,8,11,14等值

表3将具有类似3,6,9,12,15等的值

当然这只是一个选项,我个人认为它只是一个组合价值。 可以像TableID,AutoincrementID一样简单,其中TableID在所有行中都是常量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM