[SQL] ์ธ๋ํค(Foreign Key)
์ธ๋ํค๋ ํ ์ด๋ธ์์ ๋ค๋ฅธ ํ ์ด๋ธ์ ๊ฐ์ ์ฐธ์กฐํ ๋, ์ด๋ฅผ ๊ฒ์ฆํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ๊ธฐ๋ฅ์ด๋ค.
์ฐ์ง ์์๋ ์ฐธ์กฐ๋ฅผ ํ๋ ๊ฒ ์์ฒด์๋ ๋ฌธ์ ๊ฐ ์์ง๋ง, ์ ํฉ์ฑ์ ๊ฐ์กฐํ ์ ์๊ณ , ์ฐธ์กฐ๋์๊ฐ์ด ๋ฐ๋๋ ๊ฒ์ ๋ํด์ ๋ฌด์ธ๊ฐ ํ์คํ ๋ณด์ฅ์ ํ ์ ์๋ค๋ ์ฅ์ ์ด ์๋ค.
์ฑ๋ฅ ๋๋ฌธ์ ์ด๊ฑธ ์จ์ผ ํ๋์ง์ ๋ํด ์ฌ๋๋ค๋ง๋ค ์ข ์๊ฒฌ์ด ๊ฐ๋ฆฌ๋ ๋ถ๋ถ์ด ์๋๋ฐ, ์ผ๋จ ๊ทธ๋ฐ๊ฑด ์ฐจ์นํ๊ณ ๊ธฐ๋ฅ์ ์ธ ๋ถ๋ถ๋ถํฐ ๋ค๋ค๋ณด๊ฒ ๋ค.
๊ฒ์ํ์ ๊ตฌํํ๊ธฐ ์ํด ์ฌ์ฉ์์ ํฌ์คํธ์ ๋ํ ํ
์ด๋ธ์ ์ค๊ณํ๋ค๊ณ ๊ฐ์ ํ๊ฒ ๋ค.
์ธ๋ํค๋ฅผ ๊ณ ๋ คํ์ง ์๊ณ ์ง ๋ค๋ฉด ๋์ถฉ ์๋์ ๊ฐ์ ๊ตฌ์กฐ๊ฐ ๋ ๊ฒ์ด๋ค.
-- ์ฌ์ฉ์ ํ
์ด๋ธ
create table tb_user
(
id serial,
name text,
primary key(id)
);
-- ์ฌ์ฉ์๊ฐ ์์ฑํ ํฌ์คํธ ํ
์ด๋ธ
create table tb_post
(
id serial,
title text,
content text,
writer_id int,
primary key(id)
);
์ฌ๊ธฐ์ tb_post์ writer_id ์ปฌ๋ผ์ด ๋ฐ๋ก tb_user์ id๋ฅผ ๊ฐ๋ฆฌํค๋ ์ฌ์ค์์ ์ธ๋ํค ์ปฌ๋ผ์ด๋ค.
๋ฐ๋ก ์ธ๋ํค ์ค์ ์ ํ์ง ์๊ณ ๊ทธ๋ฅ ๊ทธ๋๊ทธ๋ ์กฐ์ธํด์ ์จ๋ ์ฌ์ฉ์๋ ๋ฌธ์ ๊ฐ ์๋ค.
ํ์ง๋ง ์ค๊ฐ์ ๊ฐ๋ฆฌํค๊ณ ์๋ tb_user์ ๊ฐ์ด ๊ฐ์๊ธฐ ์ญ์ ๋๊ฑฐ๋ ๋ณ๊ฒฝ๋ผ๋ ์ง๊ด์ ์ผ๋ก ํ์
ํ๊ณ ๋์ํ ์ ์๋ค๋ ๋จ์ ์ด ์๋ค.
tb_user์ ๊ฐ์ ์ญ์ ํ ๋๋ง๋ค ์ง์ ์ด๊ฑธ ์ฐธ์กฐํ๋ tb_post ๋ฑ์ ํ
์ด๋ธ์์ writer_id ๊ฐ์ ์ด๋ป๊ฒ ํ ์ง ์๋์ผ๋ก ์ฒ๋ฆฌํด์ค์ผ ํ๋ ๊ฒ์ด๋ค.
๊ฒ๋ค๊ฐ ์ฐธ์กฐํค๊ฐ์ผ๋ก ์กด์ฌํ์ง๋ ์๋ ์ด์ํ ํค๊ฐ์ ๋ฃ๋ ๊ฒ๋ ๋ง์ ์๊ฐ ์๋ค.
์ธ๋ํค ๊ธฐ๋ฅ์ ์ด์ ๋ํ ํธ์๋ฅผ ์ ๊ณตํด์ค๋ค.
์ธ๋ํค์ ์ ์ธ์ ๋ค์๊ณผ ๊ฐ์ด ํ ์ ์๋ค.
**foreign key(ํ์ฌ ํ
์ด๋ธ ์ปฌ๋ผ) references tb_user(์ฐธ์กฐํ ํ
์ด๋ธ ์ปฌ๋ผ)**์ด๋ค.
-- ์ฌ์ฉ์ ํ
์ด๋ธ
create table tb_user
(
id serial,
name text,
primary key(id)
);
-- ์ฌ์ฉ์๊ฐ ์์ฑํ ํฌ์คํธ ํ
์ด๋ธ
create table tb_post
(
id serial,
title text,
content text,
writer_id int,
primary key(id),
foreign key(writer_id) references tb_user(id)
);
๊ทธ๋ผ ์ผ๋จ ์ฐธ์กฐ๊ด๊ณ๋ฅผ ํ์ ํ๊ธฐ๋ ์ง๊ด์ ์ด๊ณ , ์๋์ ๊ฐ์ ์ด์ํ ์ฐธ์กฐ๊ฐ ์ฝ์ ๋ ๋ง์ ์ ์๋ค.

ON DELETE ์์ฑ
์ด๊ฑด ์ธ๋ํค๋ก ์ญ์ ์ ๋ํ ์ ์ฝ์ด๋ ํธ๋ฆฌ๊ฑฐ๋ฅผ ๊ฑธ์ด์ฃผ๋ ๊ธฐ๋ฅ์ด๋ค.
์์ ํ ์ด๋ธ์ ๊ฒฝ์ฐ๋ฅผ ๋ค๋ฉด, tb_user ๊ฐ์ deleteํ ๋, ํด๋น ๊ฐ์ ์ฐธ์กฐํ๋ tb_post๊ฐ ์์ ๋ ์ด๋ป๊ฒ ๋ฐ์ํ ์ง๋ฅผ ์ ์ํ๋ ๊ฒ์ด๋ค.
Cascade, Set null, Set default, Restrict, No Action์ ๋ค์ฏ๊ฐ์ง ์ต์ ์ ์ ๊ณตํ๊ณ , ๊ธฐ๋ณธ๊ฐ์ No Action์ด๋ค.
cascade๋ tb_user๊ฐ ์ญ์ ๋๋ฉด ์ฐธ์กฐํ๋ tb_post๋ ์ ๋ถ ์ญ์ ํ๋ ๊ฒ์ด๊ณ ,
set null์ writer_id๋ฅผ null๋ก ์ค์ ํ๋ ๊ฒ,
set detault๋ writer_id๋ฅผ ๋ํดํธ๊ฐ์ผ๋ก ์ค์ ํ๋ ๊ฒ,
restrict๋ ๊ทธ๋ญ tb_user์ ์ญ์ ๋ฅผ ๋ง๋ ๊ฒ์ด๋ค.
restrict์ ๊ฒฝ์ฐ์๋ง ํ๋ฒ ํ
์คํธ๋ฅผ ํด๋ณด๊ฒ ๋ค.
์ฐ์ on delete๋ฅผ ์ ์ฉํด์ค๋ค.

๋ง์ฝ ์ด๋ ๊ฒ ๊ฐ์ด ์๊ณ

์ฐธ์กฐ๋๊ณ ์๋ tb_user 1์ ์ญ์ ํ๋ ค๊ณ ํ๋ค๋ฉด
์์ฒ ์ฐจ๋จํด๋ฒ๋ฆฐ๋ค.
ON UPDATE ์์ฑ
์ด๊ฒ๋ ON DELETE์ ๋งฅ๋ฝ์ด ๊ฐ๊ณ , ์ ๊ณต๋๋ ์์ฑ๋ Cascade, Set null, Set default, Restrict, No Action ๋ค์ฏ๊ฐ๋ก ๋์ผํ๋ค. ๊ธฐ๋ณธ๊ฐ์ No Action์ด๋ค.
์ด๊ฑด ์ฐธ์กฐํ๊ณ ์๋ ์ปฌ๋ผ๊ฐ์ด ๋ฐ๋ ๊ฒฝ์ฐ์. ๊ทธ๋ฌ๋๊น ์ด ๊ฒฝ์ฐ์ tb_user์ id๊ฐ์ด ๋ฐ๋ ๊ฒฝ์ฐ์ tb_post์ writer_id๊ฐ์ ์ด๋ป๊ฒ ํ ์ง๋ฅผ ์ง์ ํด์ฃผ๋ ๊ธฐ๋ฅ์ด๋ค.
cascade๋ ๊ทธ๋ฅ ๋ฐ๊พผ ๊ฐ์ผ๋ก tb_post์์๋ ๋ค์ ๋๊ฐ์ด ๋ฐ๊ฟ์ฃผ๊ณ ,
set null์ writer_id๋ฅผ null๋ก ์ค์ ํ๋ ๊ฒ,
set detault๋ writer_id๋ฅผ ๋ํดํธ๊ฐ์ผ๋ก ์ค์ ํ๋ ๊ฒ,
restrict๋ ๊ทธ๋ญ ๋ณ๊ฒฝ์ ๋ง๋ ๊ฒ์ด๋ค.
์ด๋ฒ์ cascade๋ก ํ๋ฒ ๋๋ ค๋ณด๊ฒ ๋ค.

๋ฐ์ดํฐ๋ ์ด์ ๊ณผ ๋์ผํ๊ฒ ๋ค์ด์๋ค.

๋ง์ฝ 1์ ๊ฐ์ 11111๋ก ๋ฐ๊พผ๋ค๋ฉด

์ฐธ์กฐํ๊ณ ์๋ tb_post์์๋ ๋ฐ๋ ๊ฒ์ด๋ค.

๋์ถฉ ๊ทธ๋๊ทธ๋ ์ ์ฐ๋ฉด ๋๋ค.
์ฐธ์กฐ
https://bamdule.tistory.com/45
https://stackoverflow.com/questions/39388912/does-adding-a-foreign-key-to-an-indexed-column-boost-performance
https://www.postgresql.org/docs/9.4/performance-tips.html