首页 文章

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

提问于
浏览
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

EMP_ID DEPT_ID
500 11
501 15

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

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

4 回答

  • 6

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

    如果新部门在南极开放,你会怎么做?添加另一个表?没有!你只需添加另一个dept_type .

  • 6

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

  • 1

    您可以定义约束,但它不会按照您的意愿执行 . 您永远无法向emp表添加任何内容,因为密钥DEPT_ID必须驻留在每个DEPT_表中 .

    假设您必须保留现有结构,最简单的方法是定义一个物化视图,将每个表合并到一个视图中 . 国际海事组织,这是一个有缺陷的实施 . 我会为DEPT_ info创建一个表,其中一列分割各种类型 .

  • 2

    您无法定义此类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;
        /
    

相关问题