3

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

例如:

DEPT_AMER

DEPT_ID
10
11
12

DEPT_APAC

DEPT_ID
13
14
15

DEPT_EMEA

DEPT_ID
16
17
18

电磁脉冲

EMP_ID DEPT_ID
500 11
501 15

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

如果引用完整性约束是不可能的,是否有更好的方法来维护这种数据完整性?

4

4 回答 4

6

如果所有表中的字段都相同,那么我建议将此模型重构为单个表并为遗留应用程序创建视图。有时这种设计用于分区,但 Oracle 会自动维护分区,应用程序级分区是多余的。

于 2012-11-28T15:33:30.177 回答
6

您在三个不同的表中有一个实体。最好的方法是将 DEPT_AMER + DEPT_EMEA + DEPT_APAC 加入一个名为 DEPT 的表中,并带有新字段 DEPT_TYPE(AMER 或 EMEA 或 APAC)。它对功能支持和性能更好。

如果在南极开设新部门,你会怎么做?添加另一个表?不!您只需添加另一个 dept_type。

于 2011-03-29T15:11:13.190 回答
2

您可以定义约束,但它不会做您想要的。您将永远无法向 emp 表添加任何内容,因为键 DEPT_ID 必须驻留在每个 DEPT_ 表中。

假设您必须保留现有结构,最简单的方法是定义一个物化视图,将这些表中的每一个合并到一个视图中。IMO,这是一个有缺陷的实现。我会为 DEPT_ 信息创建一个表,其中包含一个拆分各种类型的列。

于 2011-03-29T15:11:54.203 回答
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;
    /
于 2011-03-29T15:29:03.830 回答