우리 코스의 핵심 강의 중 하나에 온 걸 환영해! 오늘은 PostgreSQL에서 외래 키를 어떻게 만드는지 얘기할 거야. 이 주제는 데이터베이스 설계에서 진짜 중요해, 왜냐면 외래 키가 테이블 사이의 관계를 만들어주거든. 만약 네가 곧 "SQL-도시"에서 길을 잃을 것 같다면, 외래 키를 서로 다른 구역을 연결하는 다리라고 생각해봐.
쉽게 말해서, 외래 키는 한 테이블의 컬럼(혹은 컬럼들 집합)이 다른 테이블의 컬럼(보통 primary key)을 참조하는 거야.
예를 들어, students (학생들)랑 courses (강의) 두 테이블이 있다고 해보자. 그러면 courses 테이블의 외래 키가 어떤 학생이 그 강의에 등록됐는지 "가리킬" 수 있어. 이렇게 해서 두 테이블이 연결되는 거지.
왜 이게 중요할까?
- 외래 키는 데이터 무결성을 보장해줘: 다른 테이블에 없는 값을 이 테이블에 넣을 수 없어.
- 데이터 다루기가 쉬워져. 예를 들어, 한 테이블에서 레코드를 삭제할 때, 관련된 다른 테이블의 레코드도 자동으로 삭제되게 할 수 있어.
외래 키 생성 문법
PostgreSQL에서 외래 키 만드는 건 진짜 쉬워 — 약간의 SQL 마법만 있으면 돼. 기본 문법은 이래:
CREATE TABLE jaesok_table (
column_foreign_id DATA_TYPE REFERENCES bumon_table(column_id)
);
이제 좀 더 깊게 들어가서 예시 몇 개를 같이 보자.
예시 1: students와 courses 테이블
학생과 강의 사이에 관계를 만들고 싶다고 해보자. 각 강의는 어떤 학생과 연결되어야 해. 그러려면 아래 쿼리만 실행하면 돼:
CREATE TABLE students (
student_id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
student_id INT REFERENCES students(student_id)
);
여기서:
students테이블에서PRIMARY KEY로 각 학생을 식별할 수 있게 했어.courses테이블의student_id컬럼은FOREIGN KEY로,students테이블의student_id를 참조해.
students 테이블
| student_id | name |
|---|---|
| 1 | Alice |
| 2 | Bob |
| 3 | Charlie |
courses 테이블
| course_id | title | student_id - FOREIGN KEY |
|---|---|---|
| 1 | SQL Basics | 1 |
| 2 | Algorithms | 1 |
| 3 | Data Structures | 2 |
| 4 | Intro to Python | 3 |
중요한 참고사항
외래 키를 추가하면, PostgreSQL이 자동으로 규칙을 만들어서 외래 키 값이 지정된 테이블의 값과 일치하는지 체크해. 잘못된 값을 넣으려고 하면 데이터베이스가 에러를 내.
실전 예시: students, courses, enrollments 모델
조금 더 복잡한 "다대다" 관계 예시를 보자. 같은 학생이 여러 강의에 등록할 수 있고, 한 강의에 여러 학생이 있을 수 있어. 이런 관계를 만들려면 중간 테이블이 필요해.
CREATE TABLE students (
student_id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY,
title TEXT NOT NULL
);
CREATE TABLE enrollments (
enrollment_id SERIAL PRIMARY KEY,
student_id INT REFERENCES students(student_id), -- 외래 키
course_id INT REFERENCES courses(course_id) -- 외래 키
);
여기서 enrollments 테이블이 students와 courses를 외래 키 student_id와 course_id로 연결해줘.
데이터 삽입
-- 학생 추가
INSERT INTO students (name) VALUES ('Ivan Ivanov'), ('Maria Smirnova');
-- 강의 추가
INSERT INTO courses (title) VALUES ('Matematika'), ('Fizika');
-- 학생을 강의에 등록
INSERT INTO enrollments (student_id, course_id) VALUES (1, 1), (1, 2), (2, 1);
데이터 조회
이제 쿼리로 어떤 학생이 어떤 강의를 듣는지, 혹은 어떤 강의에 누가 등록했는지 쉽게 알 수 있어:
-- Ivan Ivanov가 등록한 강의
SELECT c.title
FROM enrollments e
JOIN courses c ON e.course_id = c.course_id
WHERE e.student_id = 1;
-- "Matematika" 강의에 등록한 학생들
SELECT s.name
FROM enrollments e
JOIN students s ON e.student_id = s.student_id
WHERE e.course_id = 1;
고급 기능: ON DELETE와 ON UPDATE
외래 키는 부모 테이블에서 레코드를 수정하거나 삭제할 때 자식 테이블의 동작도 관리해야 해. 이럴 때 ON DELETE와 ON UPDATE 옵션을 써. 주요 옵션은 이래:
- CASCADE: 부모 테이블에서 변경이나 삭제가 일어나면 자식 레코드에도 자동으로 적용돼.
- SET NULL: 자식 테이블의 외래 키 값을
NULL로 바꿔. - RESTRICT: 이미 자식 테이블에서 사용 중이면 삭제나 변경을 막아.
- NO ACTION: 사실상
RESTRICT랑 비슷한데, 체크가 나중에 일어나.
예시 2: ON DELETE CASCADE 사용
만약 students 테이블에서 학생을 삭제하면, 그 학생의 모든 강의도 courses 테이블에서 자동으로 삭제되게 하고 싶다고 해보자. 이렇게 하면 돼:
CREATE TABLE students (
student_id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
student_id INT REFERENCES students(student_id) ON DELETE CASCADE
);
이제 students 테이블에서 학생을 삭제하면, 그 학생과 연결된 courses 테이블의 모든 레코드도 같이 삭제돼. 예를 들어:
INSERT INTO students (name) VALUES ('Ivan Ivanov');
INSERT INTO courses (title, student_id) VALUES ('Matematika', 1), ('Fizika', 1);
-- Ivanov 학생 삭제
DELETE FROM students WHERE student_id = 1;
-- courses 테이블은 이제 비어 있음, Ivanov와 연결된 강의가 모두 삭제됨
이 주제는 다음 강의에서 더 자세히 다룰 거야.
외래 키 사용 시 데이터 검증 프로세스
외래 키를 만들면, PostgreSQL이 엄격한 문지기처럼 새 레코드를 다 검사해. 예를 들어:
- 존재하지 않는 외래 키 값으로 레코드를 넣으려고 하면 에러가 나.
- 부모 테이블에서 다른 테이블과 연결된 레코드를 삭제하면(
ON DELETE CASCADE없이) 데이터 무결성 위반이 발생해.
예시: 잘못된 데이터 삽입 시도
-- 존재하지 않는 학생에게 강의 등록 시도
INSERT INTO enrollments (student_id, course_id) VALUES (3, 1);
-- 에러: 외래 키 제약 조건 위반
외래 키 만들 때 흔한 실수
- 외래 키에 인덱스가 없음. PostgreSQL은 primary key에 자동으로 인덱스를 만드는데, 외래 키에는 안 만들어줘.
WHERE조건에서 외래 키를 자주 쓸 거면 직접 인덱스를 만들어야 해. - 테이블 생성 순서가 잘못됨. 아직 없는 테이블을 참조하는 외래 키는 만들 수 없어.
ON DELETE나ON UPDATE옵션을 빼먹음. 이러면 데이터 수정할 때 예상치 못한 일이 생길 수 있어.
이제 외래 키 만드는 법을 알았으니, 구조적이고 일관성 있는 데이터베이스를 만드는 강력한 무기를 얻은 거야. 다음 강의에서는 ON DELETE CASCADE와 ON UPDATE RESTRICT로 연결된 데이터 관리하는 법을 더 깊게 다룰 거야.
GO TO FULL VERSION