[DB] 테이블 데이터를 지우고 싶어요

수민·2024년 7월 9일
0

데이터베이스

목록 보기
4/4
post-thumbnail

데이터베이스 특정 테이블의 값들을 지우고 싶어..
이미 오류가 많이 난 상태인데, DB의 값들을 읽어오면 내가 수정한 로직이 잘 동작하는지 알기 힘들어.
다시 처음부터 하고 싶어!
그럴 때 어떻게 하나요?
내 테이블 이름이 student_data라고 합시다.

DELETE * FROM student_data

= student_data이라는 테이블에서 모든 행을 다 삭제해줘!

INSERT, UPDATE, DELETE 밖에 몰랐던 저는 이렇게 사용했습니다.
모든 행을 다 지우면 되니까요.
그런데 50만행을 다 지우려니.. 시간이 꽤 걸리더라고요?
근데 DB차원에서는 그렇게 많은 양도 아닐겁니다. 백만개 천만개 몇억개의 데이터가 쌓이는게 DB죠…
지우는데만 한 삼십년 걸립니다…

근데 성능이 중요한 상황에서 테이블의 모든 내용을 지우고 싶다면요?
그래도 DELETE를 사용하고 무한정 기다리면.. 슬프겠죠?
테이블의 모든 데이터를 한꺼번에 삭제시켜주는 쿼리가 있습니다.

TURNCATE TABLE student_data

= student_data이라는 테이블의 모든 데이터를 다 삭제해줘!

인덱스까지 싹 다 지워줍니다.
갓 CREATE TABLE한 따끈따끈한 테이블의 상태로 만들어줍니다.
빠르죠…

근데 만약,, 테이블 자체를 그냥 없애버리고 싶다면요?
더이상 이 테이블이 필요가 없어지는 상황이 올 수 있죠.
당신을 위해 준비했어요

DROP TABLE student_data

= student_data이라는 테이블 자체를 삭제해줘!

테이블 자체를 삭제해줍니다. 테이블의 스키마와 데이터, 인덱스 전부가 사라집니다.
절대 복구할 수 없어요.
뭐 DROP의 경우는 테이블 자체를 삭제하는 경우니까 좀 다르긴 해요.

근데 DELETE와 TURNCATE는 뭔가 느낌상.. 비슷하게 느껴지지 않나요?
쿼리 실행 후 간단하게 보이는건 비슷하거든요…
당연히 다릅니다. 성능에서도 차이가 나고요.
뭐가 다른걸까요?

DELETE vs TURNCATE

이미지 출처

DELETE 연산은 행 단위로 테이블의 데이터를 삭제합니다.
내가 원하는 행만 삭제할 수 있죠.
모든 학생 데이터들 중에서 게임공학 전공인 학생들의 데이터만 싹 없애줄 수 있는겁니다.
테이블은 지워지더라도 테이블 용량은 줄어들지 않습니다.

음.. DELETE로 모든 테이블데이터를 지운다면 std::vector를 clear한 상태라고 보면 됩니다.
capacity는 줄어들지 않죠.

반면 TURNCATE 연산은 테이블의 모든 데이터를 한 번에 삭제시킵니다.
깔끔하게 싹 비워줘요.
테이블 용량도 다 지웁니다. 그냥 새것처럼 만들어줘요.
방금 생성한 std::vector와 현재 벡터를 교체한 상태라고 보면 됩니다.
capacity도 0이구요.

결과만 봐도 다르죠.
좀 더 자세히 들어가볼까요?

DELETE는 삭제할 때마다 트랜잭션 로그를 작성해서 롤백(Rollback)연산이 가능합니다.
Commit되기 전에 되돌릴 수 있습니다.
그러면 뭐다,,,? 좀 느리겠죠.

TURNCATE는 트랜잭션 로그도 작성하지 않고, Rollback도 불가능합니다.
그래서 빠릅니다.

별로 자세하지 않다구요,..?
제가 SQL을 배우고 있는 단계거든요…
더 자세히 알게되면 또 글 쓸게요 ㅎ.ㅎ

TURNCATE하지 않고 DELETE로 테이블 데이터를 비워서 생긴 문제

테이블에 자동 증가값이 설정되어 있는 상태입니다.
그 상태에서 DELETE로 모든 테이블값을 지우고 다시 데이터를 삽입했습니다.
근데 자동 증가값이 이전 값부터 이어서 늘어나는거에요!!
왜그럴까? 생각해봤는데, 당연한거였습니다.

간단히 상황 예시를 들어볼게요

class DB 
{
private:
	int id;
	
public:
	DB(int _id) : id(_id){}
	~DB(){}
}

std::vector<DB> vec;
int loop = 1;
while(vec.size() < 100)
	vec.emplace_back(loop++);
	
vec.clear();

while(vec.size() < 100)
	vec.emplace_back(loop++);

이 상황에서, vec 안에는 1~100까지의 id값을 가지는 DB 객체가 들어있습니다.

vec.clear() 를 호출하고 나면 어떻게될까요?
vec의 capacity는 100 이상인 상태이지만, size는 0이겠죠. loop도 100이구요.
그래서 이 상황과 동일하게 두 번째 삽입 시에 101번부터 들어가게 됩니다.

이게 DELETE를 수행한 상황과 유사하다고 볼 수 있습니다.
capacity의 개념, 내부 동작 등은 완전히 다르지만,, 진짜 개념만! 이해하기 쉽게 본다면 이런거죠.

틀렸다면 댓글 남겨주시면 매우 감사하겠습니다. 💕

그래서 하고 싶은 말이 뭔데

테이블 데이터를 지우고 싶더라도, 위 세 개의 경우는 모두 다른 경우잖아요?
내가 하고 싶은 일도 그렇겠죠.

게임공학과인 학생만 지우고 싶은데 TURNCATE TABLE student_data where major = 게임공학
이걸 백날 해봤자 안되거든요.
테이블 데이터만 지우고 싶은데 DROP TABLE해버리면 처음부터 테이블을 다시 생성해야 하고요.

그래서 내가 하고 싶은 행동에 대해서 정확히 판단하고,
그 상황에 맞는 적절한 쿼리를 선택해야 합니다.

복구할 가능성이 있거나, 삭제에 조건이 있다면 DELETE를,
복구할 가능성이 없고 모든 데이터를 삭제해야 하며 성능이 중요하다면 TURNCATE를 사용하면 되겠죠.

이외에도 자신에게 필요한 상황을 적절히 분석해서 사용하면 되겠습니다.


참고

https://wikidocs.net/4021

profile
우하하

0개의 댓글