1. Foreign Key
관계형 데이터베이스에서 foreign key(외래키)는 다중 테이블 간 관계를 형성할 때 사용한다.
foreign key 가 포함된 테이블은 하위 또는 자식 테이블이고 참조가 되는 key 컬럼을 가지고 있는 테이블은 상위 또는 부모 테이블이다.
결국 특정 컬럼을 기준으로 두 개 이상의 테이블을 연결하고 부모 테이블에 참조된 key에 delete나 update가 발생할 때 자식 테이블이 참조하고 있는 값이면 부모 테이블의 변경을 막거나 자식 테이블에 데이터 변경사항을 연동하는 게 목적이다.
이걸 RDBMS에서 constraint(제약) 이라고 부른다.
말로 들으면 좀 헷갈리는데 직접 쿼리를 날려보면 이해할 수 있다.
2. 구문
[CONSTRAINT fk_name]
FOREIGN KEY(fk_columns)
REFERENCES parent_table(parent_key_columns)
[ON DELETE delete_action]
[ON UPDATE update_action]
- fk_name : 제약으로 설정할 이름
- fk_columns : 테이블에서 foreign key로 설정할 컬럼명
- parent_key_columns : 부모 테이블의 primary key 컬럼명
- ON DELETE / UPDATE action은 부모 테이블 변경 발생 시 자식 테이블의 foreign key를 어떻게 처리할 것인지에 대한 규칙이다. 아래 예시에서 다룬다.
3. 예시
customers와 contacts 테이블을 생성한다.
두 테이블은 모두 customer_id 컬럼을 가지고 있다. customers는 customer_id가 pk다.
contacts에 있는 customer_id를 fk로 지정하고 custoemrs에 있는 customer_id를 참조하도록 해서 제약을 만들 수 있다.
데이터를 insert 한다.
INSERT INTO customers(customer_name)
VALUES('BlueBird Inc'),
('Dolphin LLC');
INSERT INTO contacts(customer_id, contact_name, phone, email)
VALUES(1,'John Doe','(408)-111-1234','john.doe@bluebird.dev'),
(1,'Jane Doe','(408)-111-1235','jane.doe@bluebird.dev'),
(2,'David Wright','(408)-222-1234','david.wright@dolphin.dev');
테이블을 조회해보면 두 테이블이 같은 customer_id 값을 가지고 있다.
이제 부모 테이블인 customers에서 customer_id가 1인 행을 지워본다.
DELETE FROM customers
WHERE customer_id = 1;
자식 테이블에 같은 customer_id가 참조되고 있기 때문에 delete에 실패한다.
ON DELETE /UPDATE action
위 예시처럼 삭제를 방지하는 게 가장 보편적인 형태이고 아무것도 지정하지 않으면
ON DELETE NO ACTION
ON UPDATE NO ACTION
값으로 설정된다.
이것 외에도 다른 설정을 줄 수 있다.
- ON DELETE SET NULL : 부모 테이블에 참조하고 있는 행을 delete하면 delete에 성공하고 자식 테이블의 fk를 null로 변경한다.
- ON DELETE CASCADE : 부모 테이블에 참조하고 있는 행을 delete하면 delete에 성공하고 자식 테이블의 fk를 가진 행을 함께 delete 한다.
참조 : https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-foreign-key/