在Oracle 10g中,是否可以为外键定义参照完整性约束以引用多个父表中的主键。
例如:
DEPT_ID
10个
11个
12
DEPT_ID
13个
14个
15
DEPT_ID
16个
17个
18
EMP_ID DEPT_ID
500 11
501 15
我希望EMP.DEPT_ID能够引用DEPT_AMER,DEPT_APAC&中的某个部门ID。 DEPT_AMER。有没有办法定义参照完整性来满足这种需求。所有3个表中的DEPT_ID都是从一个公共序列生成的,并保证是唯一的。
如果无法使用参照完整性约束,是否有更好的方法来维护此数据的完整性?
答案 0 :(得分:6)
您在三个不同的表中有一个实体。最好的方法是使用新字段DEPT_TYPE(AMER或EMEA或APAC)将DEPT_AMER + DEPT_EMEA + DEPT_APAC加入到名为DEPT的一个表中。它对功能支持和性能更好。
如果新部门在南极开放,你会怎么做?添加另一个表?没有!你只需添加另一个dept_type。
答案 1 :(得分:6)
如果所有表中的字段相同,那么我建议将此模型折射到单个表并为遗留应用程序创建视图。 有时,此设计用于分区,但Oracle会自动维护分区,并且应用程序级别分区是多余的。
答案 2 :(得分:2)
您可以定义约束,但它不会按照您的意愿执行。您永远无法向emp表添加任何内容,因为密钥DEPT_ID必须驻留在每个DEPT_表中。
假设您必须保留现有结构,最简单的方法是定义一个物化视图,将每个表合并到一个视图中。国际海事组织,这是一个有缺陷的实施。我会为DEPT_ info创建一个表,其中一列分割各种类型。
答案 3 :(得分:1)
您无法定义此类FK约束。 但您可以使用触发器验证数据完整性。 例如:
CREATE OR REPLACE TRIGGER emp_check_dept_id_trg
BEFORE INSERT OR UPDATE
on emp
FOR EACH ROW
DECLARE
l_res NUMBER;
BEGIN
SELECT count(*)
INTO l_res
FROM (
SELECT dept_id FROM DEPT_AMER WHERE dept_id = :NEW.DEPT_ID
UNION ALL
SELECT dept_id FROM DEPT_APAC WHERE dept_id = :NEW.DEPT_ID
UNION ALL
SELECT dept_id FROM DEPT_EMEA WHERE dept_id = :NEW.DEPT_ID
)
;
IF l_res = 0 THEN
raise_application_error(-20000, 'referential integrity violated');
END IF;
END;
/