바꾸고 지우기 전에
무엇이 남는지 먼저 봅니다
지난 강의에서 CREATE TABLE 로 새 테이블의 구조를 만들었습니다. 테이블을 쓰다 보면 컬럼을 추가하거나 규칙을 바꾸고, 필요 없는 구조나 데이터를 지워야 할 때도 옵니다. 이번에도 문법을 외울 필요는 없어요 — 각 명령을 실행했을 때 무엇이 바뀌고 무엇이 남는지를 아는 게 훨씬 중요합니다.
이번 섹션의 여정
완료 ✓
완료 ✓
지금 여기
섹션 3 마무리
오늘도 문법을 외우는 시간이 아닙니다
CREATE TABLE, ALTER TABLE, DROP TABLE — 이름은 조금씩 다르지만 판단 기준은 하나입니다. 실행하고 나면 무엇이 남는가. 오늘은 이 질문 하나로 네 개의 명령을 정리하겠습니다.
ALTER TABLE — 이미 만든 구조를 바꾸는 명령
이미 만들어진 테이블의 구조를 바꿀 때는 ALTER TABLE 을 사용합니다. 테이블을 지우고 다시 만드는 게 아니라, 지금 있는 테이블의 설계를 수정하는 명령이에요.
| 하는 일 | 테이블에서 달라지는 것 |
|---|---|
| 새 컬럼 추가 | 모든 행에 칸이 하나 늘어난다 |
| 컬럼의 데이터 타입 변경 | 그 컬럼에 담을 수 있는 값의 종류가 달라진다 |
| 컬럼의 규칙 변경 | NOT NULL · DEFAULT 같은 약속이 바뀐다 |
| 컬럼 삭제 | 칸이 사라진다 — 그 안의 값도 함께 |
| 제약조건 추가 · 제거 | 기본키 · 외래키 같은 규칙이 붙거나 떨어진다 |
3-4 에서 배운 기본키와 3-5 에서 배운 외래키도 여기서 다룹니다. 나중에 관계를 추가하고 싶으면 ALTER TABLE 로 외래키를 붙일 수 있고, 반대로 떼어낼 수도 있어요.
구조를 바꾸면 저장된 데이터도 함께 움직입니다
여기가 이 강의에서 가장 중요한 지점입니다. 구조 변경은 이미 저장된 데이터에 영향을 줍니다.
먼저 문자열의 최대 길이를 줄이는 경우를 보겠습니다. 우리 products 테이블의 product_name 은 VARCHAR(100) 이죠. 이걸 VARCHAR(6) 으로 줄이면 어떻게 될까요?
| 실제 저장된 상품명 | 글자 수 | 새 길이에 맞는가 |
|---|---|---|
| 립스틱 | 3 | 맞음 |
| 패딩 점퍼 | 5 | 맞음 |
| 무선 이어폰 | 6 | 맞음 — 딱 6글자 |
| 프리미엄 그래놀라 | 9 | 맞지 않음 |
| USB-C 케이블 | 9 | 맞지 않음 |
새 길이에 맞지 않는 값이 생기면 데이터베이스는 그 명령을 거부하거나, 값을 잘라서 저장할 수 있습니다. 어느 쪽이든 미리 확인하지 않으면 곤란해집니다. 상품명이 조용히 프리미엄 그로 잘려 있는 걸 몇 주 뒤에 발견하는 상황은 아무도 원하지 않죠.
실제 shop 스키마의 product_name 은 VARCHAR(100) 그대로입니다. 길이를
줄이는 이 예시는 구조 변경이 기존 데이터에 어떻게 닿는지 보여주기 위한 가정일
뿐이에요.
컬럼 삭제는 더 분명합니다. 컬럼을 지우면 칸만 없어지는 게 아니라 그 안에 저장된 값도 함께 사라집니다.
members 에서 gender 컬럼을 삭제한다면
사라지는 것컬럼 정의 한 줄
데이터어딘가 보관돼 있겠지
되돌리기컬럼을 다시 추가하면 되겠지
사라지는 것컬럼 정의 + 회원 20명의 M · F 값 전부
데이터테이블 안에는 남지 않는다
되돌리기컬럼을 다시 만들어도 값은 빈 칸이다
컬럼 삭제 = 구조 삭제 + 그 컬럼에 담긴 모든 값 삭제.
그래서 구조 변경은 AI 에게 시키든 DBeaver 화면에서 클릭하든, 영향을 받는 데이터부터 확인하는 게 먼저입니다.
삭제는 이름이 아니라 사라지는 범위로 구분합니다
삭제 명령은 세 개입니다. 이름을 외우려고 하면 헷갈리는데, 사라지는 범위로 놓고 보면 아주 단순해집니다.
| 명령 | 사라지는 것 | 실행 뒤 남는 것 |
|---|---|---|
| DELETE | 조건에 맞는 행 (조건이 없으면 모든 행) | 테이블 구조 — 컬럼 · 타입 · 제약조건 |
| TRUNCATE | 모든 행 (일부만 고를 수 없음) | 테이블 구조 — 컬럼 · 타입 · 제약조건 |
| DROP | 테이블 자체 — 데이터 + 컬럼 + 제약조건 | 없음 — 테이블이 사라진다 |
DELETE 는 테이블의 행을 지웁니다. 조건을 붙이면 원하는 행만 골라서 지울 수 있고, 실행한 뒤에도 컬럼과 규칙은 그대로 남아요.
TRUNCATE 는 테이블의 모든 행을 한 번에 비웁니다. 일부만 고를 수는 없지만, 이것도 실행 뒤에 테이블 구조는 남습니다.
DROP 은 데이터만 지우는 명령이 아닙니다. 테이블 안의 데이터와 컬럼, 제약조건을 포함해 테이블 자체를 삭제합니다. 실행하고 나면 그 이름의 테이블은 더 이상 존재하지 않아요.
TRUNCATE 의 내부 처리 방식과 되돌리기 가능 여부는 데이터베이스에 따라 달라질
수 있습니다. “TRUNCATE 는 되돌릴 수 없다” 같은 말을 모든 데이터베이스에
공통인 사실처럼 외우지 마세요. 지금 확실히 기억할 것은 하나 — 모든 행이
사라지고 테이블 구조는 남는다.
같은 테이블에 세 명령을 실행하면
말로만 보면 비슷해 보이니, 회원 20명이 들어 있는 테이블 하나에 각각 실행했다고 가정하고 결과를 나란히 놓아보겠습니다.
| 실행한 명령 | 남은 행 | 테이블 구조 |
|---|---|---|
| DELETE — 조건으로 3명만 삭제 | 17행 | 그대로 남음 |
| DELETE — 조건 없이 실행 | 0행 | 그대로 남음 |
| TRUNCATE | 0행 | 그대로 남음 |
| DROP | 테이블이 없음 | 함께 사라짐 |
DELETE 를 조건 없이 실행한 결과와 TRUNCATE 의 결과는 겉보기에 같습니다. 둘 다 행이 0개인 테이블이 남죠. 반면 DROP 뒤에는 데이터를 넣을 그릇조차 없습니다.
삭제 명령을 고를 때는 이름이 아니라 — 실행 뒤에 무엇이 남는지를 먼저 생각합니다.
연결된 테이블은 마음대로 지워지지 않습니다
3-5 에서 외래키를 배웠죠. 외래키는 없는 부모를 가리키는 자식이 생기지 않도록 막아주는 규칙이었습니다. 이 규칙은 삭제할 때도 그대로 작동합니다.
우리 shop DB 에서 orders 는 members 를, order_items 는 orders 와 products 를 참조하고 있어요. 그래서 부모 쪽을 지우려고 하면 이렇게 됩니다.
| 시도 | 결과 |
|---|---|
| 김철수(member_id 1) 행을 DELETE | 차단 — orders 에 1 · 6 · 14 · 20 · 27 · 34 주문이 남아 있다 |
| 백서윤(member_id 20) 행을 DELETE | 가능 — 주문이 하나도 없는 회원이다 |
| DROP TABLE members | 차단 — orders 가 members 를 참조하는 중이다 |
이건 불편한 제약이 아니라 안전장치입니다. 회원 한 명이 조용히 사라지고 그 사람의 주문 6건이 주인 없는 데이터로 남는 상황을, 데이터베이스가 미리 막아준 거예요.
외래키가 막아주는 건 참조 관계가 걸린 경우뿐입니다. 참조하는 자식이 없는 테이블이나 관계가 설정되지 않은 테이블은 — 아무 경고 없이 그대로 사라집니다.
실행 전에 확인할 세 가지
구조를 바꾸거나 데이터를 삭제하기 전에는 세 가지만 확인하세요.
①번이 의외로 자주 문제가 됩니다. 개발용 DB 를 지운다고 생각했는데 실제 접속된 곳이 운영 DB 인 경우, 명령 자체는 완벽히 옳아도 결과는 최악이 됩니다.
②번은 실행 전에 눈으로 확인할 수 있습니다. 지울 행이 몇 건인지 SELECT 로 먼저 세어보고, 컬럼을 지우기 전에는 그 컬럼에 어떤 값이 들어 있는지 봅니다.
③번에서 중요한 건 “백업이 있다”가 아니라 “복구가 된다”입니다. 백업 파일이 어딘가 있다는 것과, 그 파일로 실제 데이터를 되살릴 수 있다는 것은 다른 이야기예요. 특히 DROP 은 백업이 없다면 복구가 어렵거나 불가능합니다.
AI가 만든 명령도 사람이 다시 확인합니다
AI 에게 SQL 을 부탁하면 명령은 순식간에 나옵니다. 문제는 AI 가 내 데이터베이스에 지금 무엇이 들어 있는지는 모른다는 점이에요.
참고로 이 명령은 실제 shop 에서는 실행되지 않습니다. 앞 절에서 본 대로 order_items 가 orders 를 참조하고 있어서 데이터베이스가 막아주거든요. 하지만 그건 운이 좋았을 뿐입니다 — 참조하는 자식이 없는 테이블이었다면 아무 경고 없이 그대로 사라졌을 테니까요.
AI 가 잘못한 게 아닙니다. “정리해줘” 라는 요청의 범위가 모호했을 뿐이에요. 그래서 대상과 사라지는 범위는 사람이 다시 확인해야 합니다. 명령을 읽을 때 딱 두 가지만 보세요 — 어느 테이블인가, 그리고 실행 뒤에 무엇이 남는가.
혹시 실습하다가 shop 데이터를 망가뜨렸다면 걱정하지 마세요. 2-3 에서 사용한
init.sql 을 다시 실행하면 원래 상태로 복구됩니다. — 이게 바로 “백업이 있고
복구가 된다” 는 상태예요.
한눈에 정리
| 명령 | 무엇을 하는가 | 실행 뒤에 남는 것 |
|---|---|---|
| ALTER TABLE | 이미 있는 테이블의 구조를 바꾼다 | 바뀐 구조 — 기존 값이 영향받을 수 있다 |
| DELETE | 행을 지운다 (조건으로 일부만 가능) | 테이블 구조 그대로 |
| TRUNCATE | 모든 행을 한 번에 비운다 | 테이블 구조 그대로 |
| DROP | 테이블 자체를 지운다 | 아무것도 — 테이블이 없어진다 |
오늘의 핵심은 간단합니다. ALTER TABLE 은 구조를 바꾸고, DELETE 와 TRUNCATE 는 행을 지우며, DROP 은 테이블 자체를 없앱니다. 명령을 실행하기 전에 실행 뒤 무엇이 남는지를 먼저 생각하는 습관 — 그거면 충분해요.
이제 섹션 3 에서 배운 것들이 모두 모였습니다. 테이블·행·열·값, 컬럼의 약속, 데이터 타입, 기본키, 외래키, CREATE TABLE, 그리고 구조 변경과 삭제까지. 다음 강의에서는 이 조각들을 하나로 묶어 테이블 구조를 읽는 법을 정리합니다.