DELETE로 데이터 삭제하기
삭제는 그냥 기능이 아니라, 진짜 예술이야! 꼭 필요한 것만 지우고, 실수로 다른 걸 건드리지 않는 게 중요하지 (실수로 지운 데이터는 밤에 악몽으로 찾아올 수도 있어). 오늘은 이걸 깔끔하게, 제대로 배우자!
데이터 삭제는 테이블에서 더 이상 비즈니스 로직이나 시스템 요구사항에 맞지 않는 한 줄 또는 여러 줄을 빼는 과정이야. 예를 들어, 졸업한 학생이나, 음, 학교 규칙을 심하게 어긴 학생의 기록을 지워야 할 때. 아니면, 테이블에서 최신 정보만 남기려고 데이터를 정리할 수도 있지.
데이터 삭제는 이런 상황에서 써:
- 더 이상 활동하지 않는 사용자 데이터 삭제.
- 임시 기록을 테이블에서 정리.
- 중복된 데이터 삭제.
- 특정 비즈니스 로직에 따라 오래된 기록 삭제.
DELETE 명령어 문법
데이터를 삭제할 때는 DELETE 명령어를 써. 기본 문법은 이래:
DELETE FROM 테이블
WHERE 조건;
주요 구성요소:
DELETE FROM— 테이블에서 줄을 삭제하겠다는 키워드야.- 테이블 — 데이터를 삭제할 테이블 이름.
WHERE 조건— 어떤 줄을 삭제할지 필터링하는 조건. 여기서 비교 연산자, 논리 연산자(AND,OR,NOT), 심지어 서브쿼리도 쓸 수 있어.
예시: students 테이블이 있고, 거기서 ID가 5인 학생을 삭제하고 싶다고 해보자:
DELETE FROM students
WHERE id = 5;
이 쿼리는 students 테이블에서 학생 ID(id 컬럼)가 5인 줄을 삭제해.
중요: 만약 WHERE 조건을 빼먹으면, PostgreSQL이 테이블의 모든 줄을 삭제해버려. 이런 실수는 특히 프로덕션 시스템에서 진짜 재앙이 될 수 있어.
테이블의 모든 줄 삭제하기
테이블의 모든 줄을 삭제하고 싶으면, WHERE 조건 없이 쿼리를 쓰면 돼. 예를 들어:
DELETE FROM students;
이 쿼리는 모든 기록을 students 테이블에서 삭제해. 하지만 테이블 구조는 그대로 남아 — 그냥 비어있는 상태가 되는 거지.
대안: TRUNCATE
테이블의 모든 줄을 삭제할 때 TRUNCATE 명령어도 쓸 수 있어. 이건 DELETE보다 더 빨라, 왜냐면 각 줄 삭제를 트랜잭션 로그에 기록하지 않거든. 예시:
TRUNCATE TABLE students;
DELETE와 TRUNCATE의 차이점:
DELETE는 각 삭제를 트랜잭션 로그에 기록해서, 필요하면 롤백할 수 있어.TRUNCATE는 조건(WHERE)을 지원하지 않고, 한 번에 다 지워서 더 빠르지만 덜 유연해.
그냥 테이블을 비우고 싶으면 TRUNCATE가 좋아. 근데 일부 데이터만 지우거나, 롤백이 필요할 땐 DELETE가 더 나아.
복잡한 조건으로 데이터 삭제하기
DELETE에서 조건은 단순할 수도, 논리 연산자(AND, OR, NOT)나 서브쿼리까지 포함해서 복잡할 수도 있어. 예시를 보자.
예시 1: 여러 기록 삭제 30살 넘고 최근 3개월 동안 수업에 안 나온 학생을 다 삭제해보자:
DELETE FROM students
WHERE age > 30 AND last_attendance_date < (CURRENT_DATE - INTERVAL '3 months');
이 쿼리는 두 조건을 모두 만족하는 학생만 삭제해.
예시 2: 서브쿼리로 삭제하기
예를 들어, failed_students 테이블에 학업 부진으로 퇴출된 학생들의 ID가 저장돼 있다고 하자. 이 학생들을 메인 students 테이블에서 삭제해야 해:
DELETE FROM students
WHERE id IN (SELECT student_id FROM failed_students);
여기서 서브쿼리가 failed_students 테이블에서 학생 ID를 다 가져오고, DELETE가 그에 해당하는 줄을 students에서 삭제해.
추천
뭔가를 삭제하기 전에, 먼저 SELECT로 삭제할 데이터를 확인해봐. 그리고 나서 SELECT 부분만 DELETE로 바꾸면, 방금 봤던 줄만 삭제할 수 있어.
실전 예시
ID가 7인 학생이 학교를 옮기기로 했다고 해보자. 그 학생에 대한 모든 데이터를 테이블에서 삭제해보자:
DELETE FROM students
WHERE id = 7;
명령 실행 후, 진짜로 기록이 삭제됐는지 테이블을 확인해봐:
SELECT * FROM students WHERE id = 7;
ID가 7인 기록이 없으면, 삭제가 성공적으로 된 거야.
주의사항과 흔한 실수
WHERE 섹션을 빼먹음
DELETE 쓸 때 가장 흔한 실수 중 하나가 WHERE 섹션을 빼먹는 거야. 이러면 테이블의 모든 줄이 삭제돼서, 진짜 큰일 날 수 있어. 항상 쿼리 실행 전에 잘 확인하자.
이런 실수 예시:
DELETE FROM students;
-- 실수! 모든 학생이 삭제됨.
이런 실수를 피하려면, DELETE 명령 실행 전에 항상 WHERE 조건을 SELECT로 테스트해보는 게 좋아. 예를 들어:
SELECT * FROM students WHERE id = 5;
결과가 원하는 대로 나오면, 이제 DELETE를 실행해도 돼.
연관 데이터 삭제
테이블에 외래 키(FOREIGN KEY)가 있으면, 데이터 삭제할 때 에러가 날 수 있어. 삭제하려는 줄이 다른 기록과 연결돼 있으면 그렇지. 예를 들어, 학생이 enrollments 테이블에 수강 기록이 있으면, PostgreSQL이 students에서 그 학생을 삭제 못 하게 막아.
이럴 땐 이렇게 할 수 있어:
- 외래 키 만들 때
ON DELETE CASCADE옵션을 써서, 연관 데이터도 같이 삭제되게 한다. - 메인 테이블에서 삭제하기 전에, 연관된 기록을 직접 삭제한다.
연관 데이터 직접 삭제 예시:
-- 먼저 학생 5의 enrollments 데이터 삭제
DELETE FROM enrollments
WHERE student_id = 5;
-- 그리고 학생 5 자체 삭제
DELETE FROM students
WHERE id = 5;
트랜잭션과 함께 삭제하기
중요한 삭제 작업은 트랜잭션을 쓰는 게 좋아. 그래야 실수하면 변경사항을 롤백할 수 있어.
트랜잭션에서 삭제 예시:
BEGIN;
DELETE FROM students
WHERE id = 42;
-- 결과 확인
SELECT * FROM students WHERE id = 42;
-- 문제 없으면 커밋
COMMIT;
-- 아니면 롤백
-- ROLLBACK;
트랜잭션에 대한 자세한 내용은 다음 강의에서 더 다룰게 :P
GO TO FULL VERSION