FORGEIGN KEY(외래 키 또는 참조 키)는 자식 테이블에서 부모 테이블을 참조할 때,
올바른 데이터만 참조하도록(참조 무결성) 제약합니다.
외래 키는 부모 테이블과 자식 테이블 간 참조 무결성을 위한 제약 조건이므로,
자식 테이블에서 참조하는 칼럼을 부모 테이블에서 PRIMARY KEY 또는 UNIQUE로 설정해야 합니다.
부모 테이블을 만들고 자식 테이블에서 참조할 칼럼에 제약 조건을 설정하고, 로우를 입력합니다.
START
CREATE TABLE dept (
deptno NUMBER(2) CONSTRAINT dept_deptno_pk PRIMARY KEY,
dname VARCHAR2(15),
loc VARCHAR2(15)
);
INSERT INTO dept02 (deptno, dname, loc)
VALUES (10, '인사', '서울');
INSERT INTO dept02 (deptno, dname, loc)
VALUES (20, '개발', '광주');
INSERT INTO dept02 (deptno, dname, loc)
VALUES (30, '관리', '부산');
INSERT INTO dept02 (deptno, dname, loc)
VALUES (40, '영업', '경기');
COMMIT
END;
이제 자식 테이블을 만들고, 로우를 입력합니다.
START
CREATE TABLE emp02 (
empno NUMBER(4) CONSTRAINT emp02_empno_pk PRIMARY KEY,
ename VARCHAR2(15),
deptno NUMBER(2) CONSTRAINT emp02_deptno_fk REFERENCES dept02(deptno)
);
INSERT INTO emp02 (empno, ename, deptno)
VALUES (1000, 'John', 10);
INSERT INTO emp02 (empno, ename, deptno)
VALUES (2000, 'Smith', 20);
INSERT INTO emp02 (empno, ename, deptno)
VALUES (3000, 'Sam', NULL);
-- ORA-02291: integrity constraint (SCOTT.EMP02_DEPTNO_FK) violated - parent key not found
-- INSERT INTO emp02 (empno, ename, deptno)
-- VALUES (4000, 'Mike', 50);
COMMIT
END;
이제 각 테이블의 제약 조건을 데이터 사전을 통해 조회합니다.
SELECT
table_name,
constraint_type,
constraint_name,
r_constraint_name
FROM
user_constraints
WHERE
table_name IN ('DEPT02', 'EMP02')
ORDER BY
table_name ASC;
위의 결과에서, emp02 테이블의 참조키는 dept02 테이블의 기본키를 참조하는 것을 알 수 있습니다.
특정 칼럼을 참조하고 있는 자식이 있으면 해당 칼럼을 삭제할 수 없습니다.
만약 부모 테이블의 칼럼을 삭제하고 싶다면,
테이블 작성 시, FK에 ON DELETE CASCADE 키워드나 ON DELETE SET NULL 키워드를 사용하면 됩니다.
CREATE TABLE emp02 (
empno NUMBER(4) CONSTRAINT emp02_empno_pk PRIMARY KEY,
ename VARCHAR(15),
deptno NUMBER(2)
CONSTRAINT emp02_deptno_fk REFERENCES dept02(deptno) ON DELETE CASCADE
);
-- ON DELETE CASCADE --
-- 참조하는 부모 테이블의 로우가 삭제되면, 해당 로우를 참조하는 자식 테이블의 로우도 연쇄 삭제됨 --
CREATE TABLE emp03 (
empno NUMBER(4) CONSTRAINT emp02_empno_pk PRIMARY KEY,
ename VARCHAR(15),
deptno NUMBER(2)
CONSTRAINT emp03_deptno_fk REFERENCES dept02(deptno) ON DELETE SET NULL
);
-- ON DELETE SET NULL --
-- 참조하는 부모 테이블의 로우가 삭제되면, 해당 로우를 참조하는 자식 테이블의 필드값은 NULL로 바뀜--