如何为可选的现有唯一键强制执行参照完整性?

时间:2010-01-28 21:53:27

标签: database oracle foreign-keys constraints

我们有多个办事处,每个办事处内都有多个部门(一些部门的员工分布在多个办事处)。我们有两个现有的系统,以不同的方式识别员工:一,员工由IDA识别;其他员工由IDB确定。

如果员工由IDA识别,我们需要在SUPERVISOR_IDA中识别该员工的主管(如果有)。

我的表格如下:

IDA
IDB
SUPERVISOR_IDA
OFFICE
DEPARTMENT

员工可以在多个办公室或多个部门担任职务,因此同一个IDA或IDB可以存在多次,但办公室,部门或两者都不同。

问题是IDA可能为null(如果是,则IDB不为null)或IDB可以为null(如果是,则IDA不为null),或者两者都可以存在。

我正在尝试设置唯一和/或主键和约束,以确保数据库的完整性。

所以我在(IDA,IDB,OFFICE,DEPARTMENT)上创建了一个唯一的密钥。

这是我的问题:

我需要确保员工参考他们的主管。我希望有一个自引用外键,以便删除主管不会留下具有非空SUPERVISOR_IDA的孤立员工记录。但由于我需要在此表的唯一键中包含IDB,如果我创建此外键,我需要包含IDB:

local PARENT_IDA -> reference IDA
local OFFICE -> reference OFFICE
local DEPARTMENT -> reference DEPARTMENT
**local IDB -> reference IDB**

这是一个问题,因为员工IDB不应与主管IDB相同。

我知道似乎我试图在一张桌子上做太多事情,但实际上我的域名很难描述,所以我创建了员工/办公室/部门作为例子来说明我的问题。我真的无法将IDA和IDB拆分成单独的表,因为它们以某些有问题的方式交织在一起,并且存在一个,另一个或两者,具有一些无法分离的重要意义。

首先,我想在上述唯一键之外设置一个唯一键(IDA,OFFICE,DEPARTMENT),但与由单个列组成的唯一键不同,复合唯一键将处理(null,' A')和(null,'A')重复,而不是允许空列避免违反唯一性约束。

3 个答案:

答案 0 :(得分:2)

我认为问题出在模型上。该表应该有一个主键(如果IDA或IDB可以为null,那么它们不是PK列),外键应该引用PK。

我认为您正在尝试使用FK针对唯一索引在数据模型中强制实施一系列跨行验证规则,例如“员工只能由同一办公室和部门的某个人监督”, “IDA员工只能由另一名IDA员工监督”。

在实践中,当您考虑多个人可能同时更新不同行上的不同列时,很难执行这些操作。

也就是说,您可以尝试添加DEPT_IDA和OFFICE_IDA列,并仅在设置IDA时使用触发器将它们设置为DEPT和OFFICE。然后在这些列上创建英国

答案 1 :(得分:1)

我认为您的数据模型是错误的。您应该每位员工只有一份EMPLOYEE记录。然后,您可以在每个IDA和IDB上拥有unique个密钥。

因为员工在多个办公室工作,所以你需要一张表来表示; POSTS将是OFFICES和EMPLOYEES之间的交叉表。

关键是SUPERVISOR_IDA和SUPERVISOR_IDB是POSTS的属性,因此您可以在这些列和EMPLOYEES表之间强制执行外键。使用检查约束来确保如果由EMPLOYEE_IDA标识POSTS记录,则填充SUPERVISOR_IDA并且同样为EMPLOYEE_IDB。

答案 2 :(得分:0)

我不确定这是否适用于Oracle但在SQL Server中我会在SUPERVISORS表上创建一个触发UPDATE和DELETE的触发器。触发器将在EMPLOYEES表中查询SUPERVISORS.SUPERVISOR_IDA = EMPLOYEES.SUPERVISOR_IDA的任何记录。如果找到任何记录,它将回滚交易。

我发现此链接概述了您需要做的事情。

http://www.techonthenet.com/oracle/triggers/before_delete.php