我在MySQL服务器中有以下表格:
Companies:
- UID (unique)
- NAME
- other relevant data
Offices:
- UID (unique)
- CompanyID
- ExternalID
- other data
Employees:
- UID (unique)
- OfficeID
- ExternalID
- other data
在每一个中,UID都是由数据库创建的唯一标识符。
有外键可以确保Employee之间的链接 - >办公室 - >公司在UID上。
办公室和员工中的ExternalID字段是公司(我的客户实际)提供给我的应用程序的ID。客户端没有(也不关心)我自己的ID,我的应用程序从它们收到的所有数据都是根据它们的ID(即我表中的ExternalID)来识别的。
即。来自客户端的伪语言请求就像“我是公司X,更新我的员工Y的数据”。
我需要对CompanyID和Employees.ExternalID的组合强制执行唯一性,因此在我的数据库中,同一公司的员工不会有重复的ExternalID。
我在想3种可能的解决方案:
更改Employees的架构以包含CompanyID,并在这两个字段上创建唯一约束。
实施触发器,在Employees中更新/插入时验证唯一性。
强制检查应用程序级别(即我的接收服务)。
我的替代方法 - dbadmin-in-me sais(3)是最糟糕的解决方案,因为它不会在应用程序错误或其他情况下保护数据库不一致,而且很可能是最慢的。
触发器解决方案可能是我想要的,但它可能会变得复杂,特别是如果需要在单个语句中执行多个插入/更新,并且我不确定性能与(1)。< / p>
并且(1)看起来是最快速和最简单的方法,但有点违背我对关系模型的理解。
SO DB专家对每种方法的利弊有何看法,特别是如果有可能增加额外的间接水平 - 即公司 - &gt;办公室 - &gt;部门 - &gt;员工和相同的唯一性需要保留(公司/员工)。
答案 0 :(得分:3)
你是对的 - #1是最好的选择 当然,我会乍一看(因为快捷方式),但知道业务规则以确保员工只与一家公司有关 - 这是有道理的。
另外,我有一个外键,将employee表中的companyid与office表中的companyid相关联。否则,您允许员工与没有办公室的公司相关联。除非这是可以接受的......
如果无法在数据模型中演示关系,触发器是最后的手段,并且从应用程序处理逻辑意味着逻辑是集中的 - 除非有人放下约束(这意味着你),否则不会发生错误数据的机会有更大的问题)。
答案 1 :(得分:1)
您公司提供的每个表都应该在公司提供的ID上的“UNIQUE KEY”中包含CompanyID
。
公司提供的参照完整性应使用公司提供的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)
);
等
答案 2 :(得分:0)
将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在所有行中都是常量。