Oracle:FK在多个父表中引用PK

时间:2011-03-29 14:43:01

标签: sql oracle foreign-key-relationship referential-integrity

在Oracle 10g中,是否可以为外键定义参照完整性约束以引用多个父表中的主键。

例如:

DEPT_AMER

DEPT_ID
10个
11个
12

DEPT_APAC

DEPT_ID
13个
14个
15

DEPT_EMEA

DEPT_ID
16个
17个
18

EMP

EMP_ID DEPT_ID
500 11
501 15

我希望EMP.DEPT_ID能够引用DEPT_AMER,DEPT_APAC&中的某个部门ID。 DEPT_AMER。有没有办法定义参照完整性来满足这种需求。所有3个表中的DEPT_ID都是从一个公共序列生成的,并保证是唯一的。

如果无法使用参照完整性约束,是否有更好的方法来维护此数据的完整性?

4 个答案:

答案 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;
    /