CodeGym /행동 /SQL SELF /테이블 생성 시 외래 키 만들기

테이블 생성 시 외래 키 만들기

SQL SELF
레벨 19, 레슨 1
사용 가능

우리 코스의 핵심 강의 중 하나에 온 걸 환영해! 오늘은 PostgreSQL에서 외래 키를 어떻게 만드는지 얘기할 거야. 이 주제는 데이터베이스 설계에서 진짜 중요해, 왜냐면 외래 키가 테이블 사이의 관계를 만들어주거든. 만약 네가 곧 "SQL-도시"에서 길을 잃을 것 같다면, 외래 키를 서로 다른 구역을 연결하는 다리라고 생각해봐.

쉽게 말해서, 외래 키는 한 테이블의 컬럼(혹은 컬럼들 집합)이 다른 테이블의 컬럼(보통 primary key)을 참조하는 거야.

예를 들어, students (학생들)랑 courses (강의) 두 테이블이 있다고 해보자. 그러면 courses 테이블의 외래 키가 어떤 학생이 그 강의에 등록됐는지 "가리킬" 수 있어. 이렇게 해서 두 테이블이 연결되는 거지.

왜 이게 중요할까?

  1. 외래 키는 데이터 무결성을 보장해줘: 다른 테이블에 없는 값을 이 테이블에 넣을 수 없어.
  2. 데이터 다루기가 쉬워져. 예를 들어, 한 테이블에서 레코드를 삭제할 때, 관련된 다른 테이블의 레코드도 자동으로 삭제되게 할 수 있어.

외래 키 생성 문법

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);
-- 에러: 외래 키 제약 조건 위반

외래 키 만들 때 흔한 실수

  1. 외래 키에 인덱스가 없음. PostgreSQL은 primary key에 자동으로 인덱스를 만드는데, 외래 키에는 안 만들어줘. WHERE 조건에서 외래 키를 자주 쓸 거면 직접 인덱스를 만들어야 해.
  2. 테이블 생성 순서가 잘못됨. 아직 없는 테이블을 참조하는 외래 키는 만들 수 없어.
  3. ON DELETE나 ON UPDATE 옵션을 빼먹음. 이러면 데이터 수정할 때 예상치 못한 일이 생길 수 있어.

이제 외래 키 만드는 법을 알았으니, 구조적이고 일관성 있는 데이터베이스를 만드는 강력한 무기를 얻은 거야. 다음 강의에서는 ON DELETE CASCADE와 ON UPDATE RESTRICT로 연결된 데이터 관리하는 법을 더 깊게 다룰 거야.

2
과제
SQL SELF, 레벨 19, 레슨 1
잠금
간단한 "일대다" 관계 만들기
간단한 "일대다" 관계 만들기
2
과제
SQL SELF, 레벨 19, 레슨 1
잠금
ON DELETE CASCADE 동작이 있는 테이블 생성
ON DELETE CASCADE 동작이 있는 테이블 생성
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION