1. 데이터 조작하기 (DML)
개념앞에서는 데이터를 조회하고, 정렬하고, 묶어서 보는 방법을 배웠다.
이제는 한 단계 더 나아가서 테이블 안의 데이터를 직접 바꾸는 작업을 봐야 한다.
이 파트에서는 조회가 아니라, 이미 만들어진 테이블 안의 행 데이터를 실제로 바꾸는 문장에 집중한다.
즉, 새 데이터를 넣거나, 기존 데이터를 수정하거나, 필요 없는 데이터를 삭제하는 작업이 여기에 들어간다.INSERT,UPDATE,DELETE는 테이블의 행 데이터를 조작하는 대표적인 문장이고, 이런 변경 작업은 트랜잭션과 연결되어 논리적인 작업 단위로 다뤄진다.
여기서 가장 먼저 잡아야 할 것은 아주 단순하다.
INSERT는 새 행을 추가하는 문장UPDATE는 기존 행의 값을 바꾸는 문장DELETE는 기존 행을 지우는 문장즉, 이 파트의 핵심은
이미 들어 있는 데이터를 어떻게 안전하게 넣고, 바꾸고, 지울 것인가다.
예제에서는EMP테이블을 기준으로 본다.
EMP테이블은 기존 직원 데이터를 수정하거나 삭제하는 흐름을 보기 좋고, 새 직원을 추가하는INSERT예제까지 함께 확인할 수 있기 때문이다.
INSERT로 데이터 추가하기
INSERT는 테이블에 새로운 행을 추가할 때 사용하는 문장이다.
쉽게 말하면 빈 테이블에 첫 데이터를 넣거나, 기존 테이블에 새 데이터를 한 줄 더 추가하는 작업이다. 열 이름은 생략할 수 있지만, 그 경우VALUES뒤에 오는 값의 순서와 개수가 테이블 정의 순서와 정확히 맞아야 한다.
가장 기본적인 형태는 아래와 같다.insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (9900, 'JACKSON', 'SALESMAN', 7839, '1983-02-05', 900, 100, 10);이 문장은
EMP테이블에
직원번호가9900이고, 이름이JACKSON이며, 직무가SALESMAN인 새 직원 행 하나를 추가한다.
처음 보면 단순해 보이지만,INSERT에서 자주 헷갈리는 부분이 있다.
바로 열 이름을 생략할 수 있다는 점이다.
예를 들어 지금처럼insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (9900, 'JACKSON', 'SALESMAN', 7839, '1983-02-05', 900, 100, 10);이렇게 쓰면 어떤 열에 어떤 값이 들어가는지 더 분명하게 보인다.
반대로 열 이름을 생략하면, 테이블에 정의된 열 순서를 정확히 알고 있어야 한다.
그래서 처음에는 열 이름을 함께 쓰는 방식이 훨씬 덜 헷갈린다.
INSERT에서 꼭 알아야 하는 것
1) 열 이름을 생략하면 값 순서를 정확히 맞춰야 한다열 이름을 쓰지 않으면 편해 보일 수 있다.
하지만 그 대신VALUES안에 넣는 값 순서가 테이블의 열 순서와 정확히 같아야 한다.
예를 들어EMP처럼 컬럼이 많은 테이블은
값 순서를 하나만 잘못 넣어도 의미가 완전히 달라지거나 오류가 날 수 있다.
즉,INSERT는
값만 넣는 문장처럼 보여도, 실제로는 어떤 열에 들어가는 값인지 정확히 맞춰야 하는 문장이다.
2) INSERT는 기존 데이터를 바꾸는 문장이 아니라 새 행을 추가하는 문장이다
INSERT는 기존 직원의 급여를 고치는 문장이 아니다.
원래 없던 직원을 새로 추가하는 문장이다.
예를 들어JACKSON예제는
기존 데이터를 수정하는 것이 아니라EMP테이블에 새 직원 한 명을 추가하는 흐름으로 이해하면 된다.
예제: 새로운 직원 데이터 추가하기
INSERT는 새 행을 추가하는 문장이기 때문에,
실행 전에는 먼저 정말 없는 데이터인지 조회로 확인하고, 실행 후에는 정상적으로 들어갔는지 다시 조회로 확인하는 흐름으로 보는 것이 좋다.select * from emp where ename = 'JACKSON'; insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (9900, 'JACKSON', 'SALESMAN', 7839, '1983-02-05', 900, 100, 10); select * from emp where ename = 'JACKSON';
실행 전 실행 후 실행 전 조회에서는
JACKSON이라는 이름의 직원이 없으므로 결과가 나오지 않는다.
그다음INSERT를 실행하면,EMP테이블에 새 직원 한 명이 추가된다.
마지막 조회에서는 방금 넣은JACKSON행이 정상적으로 조회되는 것을 확인할 수 있다.
여기서 중요한 점은KING의 이름을 직접 넣는 것이 아니라,
관리자 번호 컬럼인mgr에7839를 넣는다는 점이다.
즉,INSERT를 볼 때는 단순히 값을 넣는 것보다 어떤 컬럼에 어떤 의미의 값이 들어가는지를 같이 보는 습관이 중요하다.
UPDATE로 기존 데이터 수정하기
UPDATE는 이미 들어 있는 행의 값을 수정할 때 사용하는 문장이다.
즉, 새 행을 추가하는 것이 아니라, 이미 있는 행의 내용 일부를 바꾸는 작업이다.UPDATE는 기존 값을 바꾸는 문장이고,WHERE를 생략하면 테이블의 전체 행 내용이 바뀔 수 있어 주의가 필요하다.
가장 기본적인 형태는 아래와 같다.update emp set sal = 5000 where empno = 7499;이 문장은
EMP테이블에서
직원번호가7499인 행을 찾아
그 행의sal값을5000으로 바꾼다.
즉,UPDATE는 크게 두 부분으로 보면 된다.
SET
→ 무엇을 어떻게 바꿀지
WHERE
→ 어떤 행을 바꿀지이 두 개가 같이 있어야
의도한 데이터만 정확하게 수정할 수 있다.
UPDATE에서 가장 중요한 것
UPDATE에서 가장 중요한 것은 사실SET보다WHERE다.
왜냐하면WHERE가 없으면
“어떤 행만 바꿀지”가 사라지기 때문이다.
예를 들어 아래 문장을 보자.update emp set sal = 5000;이 문장은 특정 직원 하나의 급여를 고치는 것이 아니다.
테이블에 있는 모든 행의 급여를 전부 5000으로 바꾸는 문장이 된다.
초보자가 가장 자주 하는 실수도 이 부분이다.
한 줄만 바꾼다고 생각하고 실행했는데, 실제로는 테이블 전체가 바뀌어 버리는 경우가 생긴다.
또WHERE가 있다고 해서 항상 한 행만 바뀌는 것도 아니다.
조건에 맞는 행이 여러 개면 그 행들이 모두 함께 수정된다.
즉,UPDATE는
무엇을 바꾸는지보다, 어느 행을 바꾸는지가 더 중요하다고 이해하면 된다.
예제: 특정 직원 급여 수정하기
한 직원의 값을 바꾸는 문제도
바로UPDATE부터 쓰기보다 수정 전 조회 → 수정 → 수정 후 조회 흐름으로 보면 더 이해가 쉽다.select empno as '직원번호', sal as '급여' from emp where empno = 7499; update emp set sal = 5000 where empno = 7499; select empno as '직원번호', sal as '급여' from emp where empno = 7499;
수정 전 수정 후 처음 조회에서는
7499번 직원의 기존 급여가 보인다.
그다음UPDATE를 실행하면 해당 직원의 급여가5000으로 변경된다.
마지막 조회에서는 정말로7499번 직원 한 명의 급여만 바뀌었는지 확인할 수 있다.
이 예제에서 핵심은
where empno = 7499가 들어 있어서
전체가 아니라 특정 조건에 맞는 행만 수정한다는 점이다.
즉,UPDATE를 볼 때는
먼저SET보다WHERE를 확인하는 습관이 중요하다.
예제: 여러 직원의 급여를 한 번에 수정하기
이번에는 한 사람만 바꾸는 것이 아니라,
조건에 맞는 여러 직원의 급여를 한 번에 바꾸는 흐름이다.select deptno as '부서번호', sal as '급여' from emp where deptno = 20; update emp set sal = sal * 1.1 where deptno = 20; select deptno as '부서번호', sal as '급여' from emp where deptno = 20;
수정 전 수정 후 처음 조회에서는
20번 부서 직원들의 현재 급여가 보인다.
그다음UPDATE를 실행하면 그 직원들의 급여가 각각 현재 급여 기준으로10%인상된다.
마지막 조회에서는20번 부서 직원들의 급여가 실제로 올라간 것을 확인할 수 있다.
이 예제에서 봐야 할 핵심은 두 가지다.
첫째, 고정값으로 바꾸는 것이 아니라 기존 값을 기준으로 계산해서 수정한다는 점이다.
둘째, 조건에 맞는 직원이 여러 명이면 여러 행이 함께 수정된다는 점이다.
DELETE로 기존 데이터 삭제하기
DELETE는 테이블에 들어 있는 행을 삭제할 때 사용하는 문장이다.
즉, 테이블 구조를 없애는 것이 아니라, 행 데이터만 지우는 작업이다.DELETE FROM은 행 단위 삭제이고,WHERE를 생략하면 전체 데이터가 삭제된다.
가장 기본적인 형태는 아래와 같다.delete from emp where deptno = 20;이 문장은
EMP테이블에서
부서번호가20인 행을 삭제한다.
즉,DELETE도UPDATE와 마찬가지로
WHERE가 매우 중요하다.
DELETE에서도 WHERE가 중요하다예를 들어 아래 문장을 보자.
delete from emp;이 문장은 특정 직원 하나를 지우는 문장이 아니다.
EMP테이블 안의 모든 행 데이터를 삭제한다.
즉, 테이블은 남아 있지만
그 안의 내용은 전부 비게 된다.
그래서DELETE를 볼 때도
항상 먼저WHERE가 있는지부터 확인해야 한다.
그리고WHERE가 있다고 해서 항상 한 행만 삭제되는 것도 아니다.
조건에 맞는 행이 여러 개면 그 행들이 모두 함께 삭제된다.
초보자 입장에서는
UPDATE와DELETE는 둘 다WHERE를 빼면 매우 위험한 문장이라고 기억하면 된다.
예제: 특정 조건의 직원 데이터 삭제하기
삭제 문제도 마찬가지로
실행 전에 어떤 행이 대상인지 먼저 조회하고, 삭제 후에는 정말 사라졌는지 다시 조회하는 흐름으로 확인하는 것이 좋다.select deptno as '부서번호', ename as '직원명' from emp where deptno = 20; delete from emp where deptno = 20; select deptno as '부서번호', ename as '직원명' from emp where deptno = 20;
삭제 전 삭제 후 처음 조회에서는
20번 부서에 속한 직원들이 보인다.
그다음DELETE를 실행하면20번 부서 직원들이 삭제된다.
마지막 조회에서는20번 부서 직원이 더 이상 조회되지 않는 것을 확인할 수 있다.
이 예제의 핵심도 같다.
행 일부만 지우고 싶은데WHERE가 빠지면 전체가 지워질 수 있다는 점이다.
예제: 급여 조건으로 여러 직원 삭제하기
이번에는 부서번호처럼 딱 정해진 값이 아니라,
급여 조건으로 삭제 대상을 찾는 흐름이다.select sal as '급여', ename as '직원' from emp where sal <= 1000; set sql_safe_updates = 0; delete from emp where sal <= 1000; set sql_safe_updates = 1; select sal as '급여', ename as '직원' from emp where sal <= 1000;
삭제 전 삭제 후 처음 조회에서는 급여가
1000이하인 직원들이 보인다.
그다음DELETE를 실행하면 그 직원들이 삭제된다.
마지막 조회에서는 해당 조건을 만족하는 직원이 더 이상 보이지 않는 것을 확인할 수 있다.
이 예제에서 봐야 할 포인트는
이름이나 사번처럼 특정 값 하나를 지정하는 방식이 아니라, 비교 조건으로 삭제 대상을 찾는 방식이라는 점이다.
또 실습 환경에 따라서는safe update설정 때문에 삭제가 바로 안 될 수 있어서, 위처럼 잠깐 설정을 조정하는 흐름이 함께 들어갈 수 있다.
DELETE,TRUNCATE,DROP은 어떻게 다른가`처음에는 셋 다 “지운다”는 느낌이라 섞이기 쉽다.
하지만 실제로는 지우는 대상이 다르다.
1) DELETE
DELETE는 행 데이터를 지운다.
테이블 구조는 그대로 남는다.
즉,
- 테이블은 계속 존재하고
- 그 안의 데이터만 지워진다
2) TRUNCATE
TRUNCATE는 테이블 구조는 남겨 두고, 안의 데이터 전체를 한 번에 비우는 문장이다.
즉,
- 테이블은 그대로 남고
- 들어 있던 행 데이터만 전체 삭제된다
그래서
TRUNCATE는 특정 행 몇 개를 지우는 문장이라기보다,
테이블 내용을 통째로 비우는 방식이라고 이해하면 된다.
3) DROP
DROP은 데이터만 지우는 것이 아니라
테이블 자체를 삭제하는 문장이다.
즉,
DELETE
→ 행 삭제
TRUNCATE
→ 데이터 전체 비우기
DROP
→ 테이블 자체 삭제이렇게 구분하면 된다.
처음에는 얼마나 빠른지보다, 무엇을 지우는 문장인지를 먼저 구분하는 것이 더 중요하다.
세 문장을 함께 보면 이렇게 정리된다이 파트는 문장이 세 개라서 많아 보이지만,
실제로는 역할이 아주 선명하게 갈린다.
INSERT
→ 새 행 넣기
UPDATE
→ 기존 행 값 바꾸기
DELETE
→ 기존 행 지우기즉, 셋 다 행 데이터를 다루는 문장이라는 공통점이 있다.
하지만 하는 일은 각각 다르다.
그리고 이 파트에서 초보자가 꼭 같이 잡아야 하는 것은 이것이다.
실수는 대부분WHERE를 빼먹을 때 난다.
UPDATE에서WHERE가 없으면 전체 수정DELETE에서WHERE가 없으면 전체 삭제또
WHERE가 있어도 조건에 맞는 행이 여러 개면
그 행들이 한꺼번에 바뀌거나 지워질 수 있다.
이 기준만 확실히 잡아도 훨씬 안전하게 읽을 수 있다.
헷갈리기 쉬운 부분첫째,
INSERT는 새 데이터를 추가하는 문장이다.
기존 데이터를 바꾸는 문장이 아니다.
둘째,UPDATE는 기존 값을 수정하는 문장이다.
이때WHERE가 없으면 전체 행이 바뀔 수 있다.
셋째,DELETE는 행 데이터를 지우는 문장이다.
테이블 구조 자체를 없애는 것은 아니다.
넷째,DELETE,TRUNCATE,DROP은 모두 지우는 느낌이 있지만 서로 다르다.
DELETE→ 행 삭제TRUNCATE→ 테이블 내용 전체 비우기DROP→ 테이블 자체 삭제
다섯째,
INSERT에서 열 이름을 생략하면
값의 순서와 개수를 정확히 맞춰야 한다.
여섯째,EMP처럼 컬럼이 많은 테이블은
처음부터 열 이름을 함께 쓰는 편이 훨씬 안전하다.
짧게 흐름으로 다시 보기
INSERT
→ 새 행 추가하기
UPDATE
→ 기존 행 값 수정하기
DELETE
→ 기존 행 삭제하기즉, 이 파트의 핵심은
이미 만들어진 테이블 안의 행 데이터를 직접 바꾸는 세 가지 방법을 구분해서 이해하는 것이다.
개념테이블을 만들기 전에 먼저 정해야 하는 것이 있다.
바로 각 컬럼에 어떤 종류의 값을 저장할 것인가다.
이때 정하는 것이데이터 형식이다.
같은 값처럼 보여도 어떤 형식으로 저장하느냐에 따라 저장 방식이 달라지고, 나중에 조회하거나 계산하거나 비교할 때의 동작도 달라진다.MySQL은 숫자, 문자, 날짜·시간, 기타 형식처럼 여러Data Type을 지원하고, 이를 이해해야 테이블을 효율적으로 만들고 데이터를 자연스럽게 다룰 수 있다.
예를 들어 이런 차이가 있다.
- 점수는 더하고 평균을 내야 하니까 숫자 형식
- 이름은 글자 자체가 중요하니까 문자 형식
- 가입일은 날짜 계산이 필요하니까 날짜 형식
즉,
데이터 형식은
값을 담는 그릇을 미리 정해 두는 것이라고 이해하면 된다.
데이터 형식을 왜 먼저 알아야 하는가처음에는 그냥 값을 넣으면 되는 것처럼 보일 수 있다.
하지만 실제로는 어떤 형식으로 저장하느냐가 이후 작업에 큰 영향을 준다.
예를 들어 숫자를 문자처럼 저장하면
합계를 구하거나 크기를 비교할 때 어색해질 수 있다.
반대로 이름이나 전화번호 같은 값을 숫자로 생각하면,
그 값의 내용보다 계산 쪽으로 잘못 이해될 수 있다.
날짜도 마찬가지다.
날짜를 날짜 형식으로 저장하면 연도, 월, 일을 쉽게 꺼낼 수 있고,
며칠 차이인지 계산하는 것도 자연스럽다.
그런데 날짜를 그냥 문자처럼 저장하면 이런 작업이 훨씬 불편해질 수 있다.
즉, 데이터 형식은 단순히 저장만을 위한 설정이 아니라
나중에 데이터를 제대로 다루기 위한 준비 작업이다.
MySQL 데이터 형식은 크게 이렇게 나눈다처음부터 형식 이름을 전부 외우려고 하면 부담스럽다.
그래서 먼저 큰 분류부터 잡는 것이 좋다.
MySQL데이터 형식은 크게 아래처럼 보면 된다.
- 숫자 데이터 형식
- 문자 데이터 형식
- 날짜와 시간 데이터 형식
- 기타 데이터 형식
즉, 처음에는
이 값이 숫자인가, 문자인가, 날짜인가
이 기준부터 잡으면 된다.MySQL데이터 형식은 자주 쓰는 형식을 중심으로 숫자, 문자, 날짜·시간, 기타 형식으로 나누어 이해하면 된다.
1. 숫자 데이터 형식숫자 데이터 형식은 숫자를 저장할 때 사용하는 형식이다.
예를 들어 나이, 수량, 점수, 가격, 재고 수 같은 값이 여기에 들어간다.
숫자 형식을 따로 두는 이유는 단순하다.
숫자는 나중에 더하기, 평균 구하기, 크기 비교하기, 정렬하기 같은 작업을 자주 하기 때문이다.
숫자 데이터 형식 표
데이터 형식 바이트 수 숫자 범위 설명 BIT(N)N/8- 1~64bit를 표현,b'0000'형식으로 표현TINYINT1-128 ~ 127정수 SMALLINT2-32,768 ~ 32,767정수 MEDIUMINT3-8,388,608 ~ 8,388,607정수 INT,INTEGER4약 -21억 ~ +21억정수 BIGINT8약 -900경 ~ +900경정수 FLOAT4-3.40E+38 ~ 1.17E-38소수점 아래 7자리까지 표현DOUBLE,REAL8-1.22E-308 ~ 1.79E+308소수점 아래 15자리까지 표현DECIMAL(m,d),NUMERIC(m,d)5~17-10^38+1 ~ +10^38-1전체 자릿수 m과 소수점 이하 자릿수d를 직접 지정하는 숫자형
숫자 형식은 이렇게 이해하면 된다
정수는 보통 INT부터 떠올리면 된다나이, 개수, 번호처럼 소수점이 필요 없는 값은
먼저INT를 떠올리면 된다.
예를 들어
- 학생 점수
- 게시글 번호
- 주문 개수
이런 값은 대부분 정수로 다루면 된다.
더 큰 숫자가 필요하면 BIGINT를 생각하면 된다보통은
INT로도 충분하지만,
아주 큰 번호나 아주 큰 범위의 값이 필요하면BIGINT를 쓸 수 있다.
즉, 정수 형식은 기본적으로
얼마나 큰 숫자까지 담아야 하는가의 차이로 보면 된다.
소수는 FLOAT, DOUBLE, DECIMAL을 떠올리면 된다소수점이 필요한 값은 정수 형식으로는 부족하다.
예를 들어
- 몸무게
- 별점 평균
- 금액 계산
- 할인율
같은 값은 소수점이 필요할 수 있다.
DECIMAL은 돈처럼 정확한 자릿수가 중요할 때 더 잘 어울린다소수라서 전부 비슷해 보일 수 있지만 차이가 있다.
예를 들어DECIMAL(5,2)는
전체 자릿수를5자리로 하고,
그중 소수점 아래를2자리로 하겠다는 뜻이다.
즉, 숫자 형식을 볼 때는 처음에 이렇게 생각하면 된다.
- 소수점이 없으면 정수
- 소수점이 있으면 실수
- 정확한 자릿수가 중요하면 DECIMAL
2. 문자 데이터 형식문자 데이터 형식은 글자나 문자열을 저장할 때 사용한다.
예를 들어 이름, 주소, 아이디, 상품명, 이메일, 전화번호 같은 값이 여기에 들어간다.
여기서 자주 헷갈리는 부분이 있다.
숫자처럼 생겼다고 해서 무조건 숫자 형식으로 저장하는 것은 아니라는 점이다.
예를 들어 전화번호를 보자.
01012345678
이 값은 숫자처럼 보이지만,
보통 더하거나 평균을 낼 값이 아니다.
즉, 계산 대상이 아니라 내용 자체가 중요한 값이다.
이런 값은 문자 형식으로 다루는 것이 훨씬 자연스럽다.
문자 데이터 형식 표
데이터 형식 바이트 수 설명 CHAR(n)1~255고정길이 문자열. n을1부터255까지 지정. 그냥CHAR만 쓰면CHAR(1)과 동일VARCHAR(n)1~65535가변길이 문자열. 길이가 달라질 수 있는 일반 문자열 저장에 가장 많이 사용 BINARY(n)1~255고정길이 이진 데이터 값 VARBINARY(n)1~255가변길이 이진 데이터 값 TINYTEXT1~255최대 255크기의TEXT데이터 값TEXT1~65535일반적인 긴 문자열 저장 MEDIUMTEXT1~16777215더 큰 TEXT데이터 값LONGTEXT1~4294967295최대 약 4GB크기의TEXT데이터 값TINYBLOB1~255최대 255크기의BLOB데이터 값BLOB1~65535일반적인 BLOB데이터 값MEDIUMBLOB1~16777215더 큰 BLOB데이터 값LONGBLOB1~4294967295최대 약 4GB크기의BLOB데이터 값ENUM(값들...)1 또는 2미리 정해 둔 값 중 하나를 저장. 최대 65535개의 열거형 데이터 값SET(값들...)1, 2, 3, 4, 8미리 정해 둔 값들 중 여러 개를 함께 저장 가능. 최대 64개의 서로 다른 데이터 값
문자 형식은 이렇게 이해하면 된다
CHAR는 길이가 고정된 문자열
CHAR는 길이를 미리 정해 두고 쓰는 형식이다.
항상 길이가 거의 같거나, 길이가 딱 정해져 있는 값에 더 잘 어울린다.
예를 들어 성별 코드처럼
항상 길이가 짧고 일정한 값은CHAR로 생각해 볼 수 있다.
VARCHAR는 길이가 달라질 수 있는 문자열
VARCHAR는 실제 문자열 길이에 따라 유연하게 쓰는 형식이다.
이름, 주소, 이메일처럼 길이가 사람마다 달라질 수 있는 값에 더 자연스럽다.
초보자 기준으로는
- 길이가 딱 정해진 느낌이면
CHAR- 길이가 달라질 수 있으면
VARCHAR이렇게 먼저 구분하면 된다.
TEXT는 긴 글을 저장할 때짧은 이름이나 주소가 아니라
소개글, 본문, 후기처럼 내용이 길어질 수 있는 경우에는TEXT계열을 생각하면 된다.
LONGTEXT는 아주 긴 글장문의 문서, 긴 본문처럼
텍스트 크기가 매우 큰 경우를 떠올리면 된다.
BLOB 계열은 파일 같은 바이너리 데이터표에는 함께 들어가 있지만,
BLOB계열은 글자를 저장하는 형식이 아니라
이미지, 파일, 영상 같은 바이너리 데이터를 저장하는 쪽에 더 가깝다.
즉,TEXT계열은 긴 글,
BLOB계열은 글자가 아닌 큰 파일 데이터라고 구분하면 된다.LONGTEXT,LONGBLOB은 큰 데이터를 저장하기 위한LOB형식이고,LONGTEXT는 큰 텍스트,LONGBLOB은 큰 바이너리 데이터 저장용으로 설명된다.
ENUM은 정해진 값 중 하나를 고를 때예를 들어
- 상태가
신청,진행중,완료- 등급이
A,B,C처럼 미리 정해진 값 중 하나만 들어가야 하는 경우에 어울린다.
SET은 여러 값을 함께 선택할 때
SET은 미리 정해 놓은 값들 중에서
하나만이 아니라 여러 개를 함께 저장할 수 있는 형식이다.
즉, 문자 형식은 단순히 글자를 저장하는 것뿐 아니라
값의 성격이 계산용인지, 내용용인지, 긴 글인지, 정해진 선택지인지까지 함께 생각해야 한다.
3. 날짜와 시간 데이터 형식날짜와 시간 데이터 형식은
말 그대로 날짜, 시간, 날짜+시간 값을 저장할 때 사용한다.
예를 들어
- 회원 가입일
- 주문 날짜
- 작성 시간
- 입사일
- 예약 시간
같은 값이 여기에 들어간다.
날짜와 시간 데이터 형식 표
데이터 형식 바이트 수 설명 DATE3날짜만 저장, 'YYYY-MM-DD'형식 사용TIME3시간만 저장, 'HH:MM:SS'형식 사용DATETIME8날짜와 시간을 함께 저장, 'YYYY-MM-DD HH:MM:SS'형식 사용TIMESTAMP4날짜와 시간을 저장하며 상황에 따라 시간대 설정과 함께 다뤄질 수 있음 YEAR1연도만 저장, 'YYYY'형식 사용
날짜와 시간 형식은 이렇게 이해하면 된다
DATE날짜만 저장할 때 사용한다.
예를 들어2026-04-01처럼
연-월-일만 필요할 때 어울린다.
TIME시간만 저장할 때 사용한다.
예를 들어12:35:29처럼
시-분-초만 필요할 때 쓴다.
DATETIME날짜와 시간을 함께 저장할 때 사용한다.
예를 들어 가입 시각, 결제 시각처럼
언제 발생했는지를 정확히 남기고 싶을 때 자연스럽다.
TIMESTAMP
TIMESTAMP도 날짜와 시간을 저장하는 형식이다.
처음에는DATETIME과 비슷하게 보이는데, 상황에 따라 시간대 설정과 함께 다뤄질 수 있다는 정도만 먼저 알고 있으면 된다.
즉, 초보자 기준에서는
DATETIME과 함께 날짜+시간 저장용 형식이라는 감각을 먼저 잡는 것이 중요하다.
YEAR연도만 따로 저장할 때 사용한다.
예를 들어 출생연도, 입학연도처럼
연도 정보만 중요할 때 쓸 수 있다.
즉, 날짜·시간 형식은 문자처럼 보이는 값을 저장하는 것이 아니라
나중에 날짜와 시간처럼 다루기 위해 저장하는 형식이라고 이해하면 된다.DATE,TIME,DATETIME,TIMESTAMP,YEAR은 날짜·시간 관련 데이터를 저장하기 위한 대표 형식이다.
4. 기타 데이터 형식기타 데이터 형식은 숫자, 문자, 날짜·시간 형식만으로는 다루기 어려운 값을 저장할 때 사용하는 형식이다.
즉, 기본적인 형식만으로는 부족할 때 등장하는
특수 목적용 형식이라고 보면 된다.
기타 데이터 형식 표
데이터 형식 바이트 수 설명 GEOMETRYN/A선, 점, 다각형 같은 공간 데이터를 저장하고 조작 JSON8JSON(JavaScript Object Notation)문서를 저장이 부분은 처음부터 깊게 들어갈 필요는 없다.
다만MySQL에는 일반 숫자, 문자, 날짜 말고도
이런 특수 목적용 형식이 있다는 정도는 알고 있으면 충분하다.GEOMETRY,JSON같은 형식은 일반적인 값 저장이 아니라 조금 더 특별한 목적을 가진 형식으로 보면 된다.
형 변환
개념값을 다루다 보면 원래 형식 그대로만 쓰는 것이 아니라,
다른 형식으로 바꾸어 사용해야 할 때가 있다.
이것이형 변환이다.
예를 들어 문자처럼 저장된 값을 숫자로 바꿔 계산하거나,
숫자를 문자로 바꿔서 이어 붙일 수도 있다.
즉,형 변환은
값의 종류를 상황에 맞게 바꾸어 사용하는 것이다.CAST()와CONVERT()는 대표적인 형 변환 함수이고, 함수 없이 자동으로 형이 바뀌는 경우는 암시적 형 변환으로 본다.
1. 명시적 형 변환직접 함수를 써서 형식을 바꾸는 것을
명시적 형 변환이라고 한다.
대표적인 문법은 아래와 같다.CAST(expression AS 데이터형식[(길이)]) CONVERT(expression, 데이터형식[(길이)])즉, 내가 직접
“이 값을 숫자로 바꿔라”,
“이 값을 문자로 바꿔라”
라고 지정하는 방식이다.
예를 들어 평균값을 구하면 결과가 소수로 나올 수 있다.
그런데 그 값을 정수처럼 보고 싶다면
CAST()나CONVERT()를 써서 형식을 바꿀 수 있다.
예제에서는
buytbl의 평균 구매 개수를 구한 뒤
그 결과를 정수형으로 바꾸는 흐름을 보여준다.CAST(),CONVERT()는 가장 일반적인 데이터 형 변환 함수이고, 평균 구매 개수 예제로도 설명된다.
핵심은
CAST()와CONVERT()가 형식을 직접 지정해서 바꾸는 함수라는 점이다.
2. 암시적 형 변환형 변환은 항상 직접 쓰는 것만 있는 것은 아니다.
경우에 따라서는MySQL이 상황에 맞게 자동으로 형을 바꾸어 처리하기도 한다.
이것을암시적 형 변환이라고 한다.
이 예제에서는
- 문자와 문자를 더할 때 숫자로 바뀌어 계산되기도 하고
- 문자열을 연결할 때는 문자처럼 처리되기도 하고
- 숫자와 문자를 비교할 때 자동으로 숫자처럼 해석되기도 한다
즉, 내가 직접 “바꿔라”라고 쓰지 않아도
MySQL이 문맥을 보고 알아서 형을 바꾸는 경우가 있는 것이다.CAST()나CONVERT()를 사용하지 않고 형이 변하는 것을 암시적 형 변환으로 이해하면 된다.
초보자 입장에서는 이걸 이렇게 기억하면 된다.
- 직접 바꾸면
명시적 형 변환- 자동으로 바뀌면
암시적 형 변환중요한 점은
이 자동 변환이 편리할 수도 있지만, 내가 생각한 방식과 다르게 동작할 수도 있다는 것이다.
그래서 형이 섞여 있는 값을 다룰 때는 결과가 어떻게 해석될지 한 번 더 확인하는 습관이 중요하다.
헷갈리기 쉬운 부분첫째, 숫자처럼 보인다고 해서 모두 숫자 형식으로 저장하는 것은 아니다.
전화번호, 학번, 우편번호처럼 계산 대상이 아닌 값은 문자 형식이 더 자연스러울 수 있다.
둘째, 날짜는 문자처럼 저장할 수도 있어 보이지만,
나중에 날짜 계산과 비교를 하려면 날짜 형식으로 저장하는 편이 훨씬 자연스럽다.
셋째, 데이터 형식은 저장만을 위한 설정이 아니다.
조회, 계산, 비교, 정렬에도 직접 영향을 준다.데이터 형식은 테이블 생성 시 열 이름과 함께 지정되고, 이후 데이터 활용 방식에도 직접 연결된다.
넷째,CAST()와CONVERT()는 직접 형을 바꾸는 함수다.
반대로 함수 없이 자동으로 바뀌는 것은암시적 형 변환이다.
다섯째, 처음부터 형식 이름을 전부 외우려 하지 말고
먼저 숫자인가, 문자인가, 날짜인가부터 구분하는 것이 더 중요하다.
짧게 흐름으로 다시 보기
숫자 데이터 형식
→ 계산하고 비교할 값 저장하기
문자 데이터 형식
→ 이름, 주소처럼 내용 자체가 중요한 값 저장하기
날짜와 시간 데이터 형식
→ 날짜 계산과 시간 처리가 필요한 값 저장하기
기타 데이터 형식
→ 특수 목적 데이터를 저장하기
형 변환
→ 필요할 때 값을 다른 형식으로 바꾸어 사용하기
즉, 이 파트의 핵심은
데이터를 어떤 종류의 값으로 저장할지 먼저 구분하고, 그에 맞는 형식을 선택하는 것이다.
3. 테이블 생성과 제약 조건
개념앞에서
MySQL의데이터 형식을 배웠다면, 이제는 그 형식을 실제 저장 구조에 붙여서 테이블을 만드는 단계로 넘어가게 된다.
이 구간의 핵심은 단순하다. 어떤 데이터를 저장할지 정하고, 그 데이터를 담을열을 만들고, 각 열에 어떤 형식과 규칙을 줄지 정하는 것이다.
즉,테이블 생성은 데이터를 넣기 전에 저장 틀을 먼저 설계하는 작업이다.
그리고 이때 같이 나오는 것이제약 조건이다.
제약 조건은 아무 값이나 들어오지 못하게 막는 규칙이다. 같은 아이디가 두 번 들어오지 못하게 하거나, 부모 테이블에 없는 값을 자식 테이블이 참조하지 못하게 하거나, 비정상적인 값이 들어오지 못하게 제한하는 역할을 한다.
결국 이 구간은 테이블의 구조를 만들고, 그 구조 안에 어떤 규칙을 걸지 정하는 파트라고 보면 된다.
먼저 흐름부터 잡기이 부분은 아래 순서로 이해하면 가장 덜 헷갈린다.
1.데이터베이스를 만든다.
2. 사용할데이터베이스를 선택한다.
3. 먼저 구조가 단순한 테이블을 하나 만들어 본다.
4. 그다음 필요하면 부모 테이블과 자식 테이블 구조를 본다.
5. 관계가 있는 경우 부모 테이블에 데이터를 먼저 넣는다.
6. 마지막으로 자식 테이블에 데이터를 넣는다.
즉, 처음에는book처럼 혼자서도 이해할 수 있는 단순한 테이블로 테이블 생성 자체를 익히고,
그다음외래 키가 붙는 관계형 구조는usertbl,buytbl처럼 부모-자식 관계가 있는 예제로 이해하면 훨씬 덜 헷갈린다.
1. 테이블 생성
개념테이블은 데이터를 표 형태로 저장하기 위한 구조다.
하지만 그냥 칸만 나누는 것이 아니다. 각 열마다 어떤 값이 들어올지, 그 값이 꼭 있어야 하는지, 중복이 가능한지까지 함께 정해야 한다.
그래서 테이블을 만들 때는 보통 아래 네 가지를 같이 본다.
열 이름데이터 형식NULL 허용 여부제약 조건즉, 테이블 생성은
이름만 붙이는 작업이 아니라 데이터가 들어올 규칙까지 함께 정하는 작업이다.
핵심 특징
1) 테이블을 먼저 만들어야 INSERT가 가능하다
INSERT,UPDATE,DELETE같은DML은 테이블의 행을 다루는 명령이다.
그래서 테이블이 아직 없는데 데이터를 넣을 수는 없다.
먼저CREATE DATABASE,CREATE TABLE같은DDL로 구조를 만든 다음에 데이터를 넣어야 한다.
2) 열 이름만 정하는 것이 아니라 데이터 형식도 같이 정한다예를 들어 도서명은 문자형, 가격은 숫자형, 도서 분류 코드는 짧은 문자형처럼 정한다.
이때 형식이 맞지 않으면 나중에 데이터를 넣을 때 오류가 나거나 의도와 다른 값이 들어간다.
그래서데이터 형식을 제대로 정하는 것이 테이블 설계의 출발점이다.
3) 열 목록을 생략한 INSERT는 순서가 정확히 맞아야 한다
INSERT INTO 테이블명 VALUES(...)처럼 열 이름을 생략하면, 괄호 안 값의 순서와 개수가 테이블 정의 순서와 정확히 같아야 한다.
이걸 모르면 값은 맞는데도 엉뚱한 열에 들어가거나 오류가 난다. 초보자일수록 이 부분을 자주 틀린다.
4) 자동 증가 열은 보통 직접 번호를 넣지 않는다
AUTO_INCREMENT가 걸린 열은INSERT할 때 직접 값을 넣지 않거나NULL을 넣으면 DB가 자동으로 1, 2, 3처럼 값을 채운다.
이 기능은 구매번호, 게시글번호처럼 각 행을 순서대로 구분해야 할 때 자주 사용한다.
AUTO_INCREMENT는 숫자형 열에 사용하고, 보통PRIMARY KEY또는UNIQUE와 함께 쓴다.
코드 예제예제:
데이터베이스 생성과 선택CREATE DATABASE edudb; USE edudb; -- 1. edudb라는 데이터베이스를 만든다. -- 2. 앞으로 작업할 기본 데이터베이스를 edudb로 선택한다. -- 출력결과 -- 데이터베이스 생성 -- 사용할 데이터베이스 변경이 코드는 가장 바깥 저장소를 먼저 준비하는 예제다.
테이블은 데이터베이스 안에 만들어지므로, 보통CREATE DATABASE와USE가 먼저 온다.
예제:
book 생성CREATE TABLE book ( id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(40), price INT, kind CHAR(3) ); DESC book; -- 1. book이라는 이름의 테이블을 만든다. -- 2. id는 각 행을 구분하는 식별값이므로 PRIMARY KEY를 준다. -- 3. id는 AUTO_INCREMENT를 설정해서 데이터가 들어갈 때 번호가 자동으로 증가하게 한다. -- 4. title은 도서명을 저장하는 열이므로 VARCHAR(40)으로 만든다. -- 5. price는 가격을 저장하는 숫자 열이므로 INT로 만든다. -- 6. kind는 도서 분류 코드를 저장하므로 CHAR(3)으로 만든다. -- 출력결과 -- book 생성 완료 -- book 테이블 구조 확인이 코드는 테이블을 만들 때
열 이름,데이터 형식,PRIMARY KEY,AUTO_INCREMENT가 실제로 어떻게 들어가는지 보여 주는 가장 기본적인 예제다.
특히id는 단순한 숫자 열이 아니라, 각 행을 구분하는 기준이면서 데이터가 추가될 때 자동으로 번호가 붙는 열이라는 점을 같이 봐야 한다.
위 이미지는
DESC book결과를 보여 주는 부분이다.
즉, 테이블을 만든 뒤에는 바로 구조를 확인하면서id,title,price,kind가 의도한 형식대로 생성되었는지 보는 흐름으로 이해하면 된다.
예제:
book 데이터 입력INSERT INTO book (title, price, kind) VALUES ('자바의 정석', 36000, 'b01'), ('모던 자바스크립트 핵심 가이드', 19800, 'b02'), ('그림과 실습으로 배우는 도커', 28000, 'b05'), ('MySQL로 배우는 데이터베이스 개론과 실습', 27000, 'b04'), ('이것이 스프링부트다', 36000, 'b02'); SELECT * FROM book; -- 1. id는 AUTO_INCREMENT 열이므로 직접 값을 넣지 않는다. -- 2. title, price, kind 열에 맞춰 도서 데이터를 저장한다. -- 3. INSERT가 끝난 뒤 SELECT로 실제 저장 결과를 확인한다. -- 출력결과 -- 도서 데이터 저장 -- book 테이블 조회이 예제에서는
AUTO_INCREMENT가 걸린id에 값을 직접 넣지 않는다는 점이 중요하다.
즉, 자동 번호 열이 있는 테이블은 보통 나머지 열만 지정해서 데이터를 넣는 방식으로 이해하면 된다.
위 이미지는
SELECT * FROM book결과를 보여 주는 부분이다.
즉, 데이터 입력이 끝난 뒤에는id가 자동으로1,2,3처럼 붙었는지, 그리고title,price,kind값이 정상적으로 저장되었는지 함께 확인하는 흐름으로 보면 된다.
2. 제약 조건
개념제약 조건은 데이터의 무결성을 지키기 위한 제한 규칙이다.
쉽게 말하면, 데이터가 틀어지지 않게 막아 주는 안전장치다.
예를 들어 아래 같은 상황을 막기 위해 제약 조건이 필요하다.
- 같은 회원 아이디가 두 번 저장되는 경우
- 부모 테이블에 없는 회원 아이디를 구매 테이블에 넣는 경우
- 키에 음수 값이 들어가는 경우
- 꼭 필요한 열이 비어 있는 경우
즉, 제약 조건은 귀찮은 문법이 아니라 데이터가 믿을 수 있는 상태를 유지하게 해 주는 장치다.
3. 주요 제약 조건
3-1. PRIMARY KEY
개념
PRIMARY KEY는 각 행을 구분하는 대표 열이다.
회원 테이블에서는 회원 아이디, 학생 테이블에서는 학번처럼 각 행을 유일하게 식별할 수 있는 값이 여기에 해당한다.
핵심 특징
- 중복되면 안 된다.
NULL이 들어가면 안 된다.- 각 행을 구분할 수 있어야 한다.
즉,
PRIMARY KEY는 중복 불가 + 빈 값 불가를 동시에 만족해야 한다.
3-2. FOREIGN KEY
개념
FOREIGN KEY는 두 테이블 사이의 관계를 연결하는 키다.
자식 테이블의 값이 부모 테이블의 값을 참조하도록 만들어서, 서로 관련 있는 데이터가 엉키지 않게 해 준다.
핵심 특징
- 자식 테이블이 부모 테이블의 값을 참조한다.
- 참조되는 부모 열은
PRIMARY KEY이거나UNIQUE여야 한다.- 부모에 없는 값은 자식에 넣을 수 없다.
- 부모가 먼저 있고, 자식이 나중에 따라와야 한다.
즉,
FOREIGN KEY는 값 복사가 아니라 관계 연결 규칙이다.buytbl이usertbl전체를 들고 있는 것이 아니라,usertbl의userID를 기준으로 누구의 구매인지 연결하는 것이다.
참고외래 키에는
ON DELETE CASCADE,ON UPDATE CASCADE같은 옵션도 줄 수 있다.
이 옵션은 부모 데이터가 바뀌거나 삭제될 때 자식 테이블에도 그 변경을 자동으로 반영하도록 하는 기능이다.
3-3. UNIQUE
개념
UNIQUE는 중복되지 않는 유일한 값을 요구하는 제약 조건이다.
대표적으로 이메일처럼, 들어오는 값은 중복되면 안 되지만 테이블의 대표 식별자로 쓰지는 않는 열에 어울린다.
핵심 특징
- 중복은 허용하지 않는다.
PRIMARY KEY와 비슷하지만NULL은 허용할 수 있다.NULL은 여러 개가 들어와도 상관없다.즉,
UNIQUE는 유일해야 하지만 대표 키까지는 아닌 값에 걸기 좋은 규칙이다.
3-4. CHECK
개념
CHECK는 입력되는 값이 특정 조건을 만족하는지 검사하는 제약 조건이다.
형식만 맞는다고 통과시키는 것이 아니라, 값의 내용이 조건에 맞는지도 확인한다.
예를 들어 키는 음수가 될 수 없고, 출생년도는 너무 비정상적인 값이면 안 되게 만들 수 있다.
MySQL에서는8.0.16부터 지원한다.
3-5. DEFAULT
개념
DEFAULT는 값을 따로 넣지 않았을 때 자동으로 들어갈 기본값이다.
매번 같은 값을 직접 입력하는 번거로움을 줄이고, 값이 비는 상황도 줄여 준다.
3-6. NULL 과 NOT NULL
개념
NULL은 공백 문자열''이나 숫자0과 다르다.
NULL은 아무 것도 없음, 즉 값이 존재하지 않는 상태를 뜻한다.
그래서 꼭 필요한 열이라면NOT NULL을 걸어서 비워 둘 수 없게 해야 한다.
PRIMARY KEY가 걸린 열은 자동으로NOT NULL성격을 가진다.
코드 예제예제:
여러 제약 조건을 함께 걸기CREATE TABLE membertbl ( userID CHAR(8) PRIMARY KEY, email VARCHAR(50) UNIQUE, birthYear INT CHECK (birthYear >= 1900), height SMALLINT CHECK (height >= 0), grade CHAR(1) DEFAULT 'B' ); -- 1. userID는 PRIMARY KEY라서 중복과 NULL을 허용하지 않는다. -- 2. email은 UNIQUE라서 같은 값이 두 번 들어오면 안 된다. -- 3. birthYear, height는 CHECK로 이상한 값이 들어오지 못하게 한다. -- 4. grade는 값을 생략하면 기본값으로 'B'가 들어간다. -- 출력결과 -- membertbl 생성 완료이 예제는
PRIMARY KEY,UNIQUE,CHECK,DEFAULT가 실제 테이블 정의 안에서 어떻게 보이는지 한 번에 보여준다.
즉, 제약 조건은 각각 따로 외우는 것이 아니라 열 뒤에 붙는 규칙으로 함께 읽어야 이해가 된다.
4. 틀리기 쉬운 예시
FOREIGN KEY는 단순한book예제로는 잘 안 보이므로, 여기부터는 관계형 예제로 설명한다예제:
PRIMARY KEY 중복INSERT INTO usertbl VALUES('KBS', '다른사람', 1990, '서울', '010', '9999999', 180, '2024-1-1'); -- 1. userID는 PRIMARY KEY다. -- 2. 이미 들어 있는 'KBS'를 다시 넣으려고 하면 중복이 된다. -- 출력결과 -- 오류 발생 -- 이유: PRIMARY KEY는 중복을 허용하지 않기 때문
예제:
없는 회원 아이디를 FOREIGN KEY로 넣기INSERT INTO buytbl VALUES(NULL, 'JYP', '모니터', '전자', 200, 1); -- 1. buytbl의 userID는 usertbl의 userID를 참조한다. -- 2. usertbl에 'JYP'가 없는데 buytbl에 넣으려고 하면 참조 기준이 없다. -- 출력결과 -- 오류 발생 -- 이유: FOREIGN KEY는 부모 테이블에 실제 존재하는 값만 참조할 수 있기 때문
예제:
PRIMARY KEY에 NULL 넣기INSERT INTO usertbl VALUES(NULL, '홍길동', 2000, '서울', '010', '1234567', 175, '2024-1-1'); -- 1. userID는 PRIMARY KEY다. -- 2. PRIMARY KEY는 NULL을 허용하지 않는다. -- 출력결과 -- 오류 발생 -- 이유: PRIMARY KEY는 각 행을 구분하는 값이어야 하므로 비어 있을 수 없기 때문이런 예시는 꼭 같이 봐야 한다.
되는 코드만 보면 이해한 것 같지만, 제약 조건은 결국 무엇을 막는 규칙인지까지 알아야 제대로 잡힌다.
헷갈리기 쉬운 부분
1. PRIMARY KEY와 UNIQUE는 비슷하지만 같지 않다둘 다 중복을 막는다는 점은 비슷하다.
하지만PRIMARY KEY는 각 행을 대표해서 구분하는 기준이고NULL도 허용하지 않는다.
반면UNIQUE는 중복만 막고NULL은 허용할 수 있다. 그래서 대표 식별자면PRIMARY KEY, 유일하기만 하면UNIQUE라고 구분해서 보면 된다.
2. NULL은 공백도 아니고 0도 아니다
NULL은 값이 없는 상태다.
공백 문자열은 문자열이 들어 있는 것이고,0은 숫자가 들어 있는 것이다.
셋은 비슷해 보여도 전혀 다르다.
3. 부모 테이블을 먼저 만들고 먼저 넣어야 한다자식 테이블은 부모 값을 참조해야 하므로 부모가 먼저 있어야 한다.
그래서usertbl을 먼저 만들고,buytbl을 나중에 만든다. 데이터도 회원 정보를 먼저 넣고 구매 정보를 나중에 넣는다. 이 순서가 틀리면 왜 오류가 나는지 이해하기 어렵다.
4. 부모 테이블을 먼저 삭제할 수 없는 이유도 같다외래 키가 걸려 있는 상태에서는 부모 테이블을 먼저 삭제할 수 없다.
구매 테이블이 회원 테이블을 참조하고 있는데 회원 테이블을 먼저 지워 버리면 참조 기준이 사라지기 때문이다.
그래서 보통은 자식 테이블을 먼저 정리하고 부모 테이블을 나중에 다룬다.
5. AUTO_INCREMENT 열에 들어간 NULL은 일반적인 NULL과 느낌이 다르다보통
NULL은 값이 없다는 뜻이지만,AUTO_INCREMENT열에 넣은NULL은 자동 번호를 생성하라는 의미로 동작한다.
그래서 문법만 외우지 말고, 어떤 열에 넣은 NULL인지까지 같이 봐야 한다.
4. 테이블 삭제와 ALTER TABLE
개념앞에서
테이블 생성과제약조건을 배웠다면, 이제는 이미 만들어 둔 테이블을 지우거나 수정하는 방법으로 넘어가게 된다.
테이블은 한 번 만들고 끝나는 것이 아니다. 필요 없어지면 삭제할 수도 있고, 중간에 열을 추가하거나 이름을 바꾸거나 제약조건을 수정해야 할 수도 있다.
이때 핵심이 되는 명령이DROP TABLE과ALTER TABLE이다.
DROP TABLE: 테이블 자체를 삭제ALTER TABLE: 테이블 구조를 수정
이 둘은 모두DDL에 속하므로 실행하면 바로 반영된다.
즉, 단순 조회가 아니라 테이블 구조 자체를 건드리는 명령이라는 점을 먼저 잡고 가야 한다.
먼저 흐름부터 잡기이 파트는 아래 차이만 정확히 구분하면 이해가 쉬워진다.
DELETE: 행 데이터를 삭제TRUNCATE: 테이블 구조는 남기고 전체 데이터를 비움DROP TABLE: 테이블 자체를 삭제ALTER TABLE: 테이블 구조를 수정즉,
데이터만 지우는지,
구조는 남기는지,
테이블까지 없애는지를 먼저 구분해야 한다.
1. 테이블 삭제
개념테이블 삭제는 데이터 몇 줄만 지우는 것이 아니라, 테이블 자체를 없애는 작업이다.
그래서 한 번 삭제하면 그 안에 있던 데이터, 열 구조, 제약조건도 함께 사라진다.
여기서 가장 먼저 구분해야 하는 것이DELETE와DROP TABLE의 차이다.
DELETE는 행 삭제DROP TABLE은 테이블 삭제즉,
DELETE는 테이블은 남기고 내용물만 지우는 것이고,
DROP TABLE은 테이블 자체를 없애는 것이다.
핵심 특징
1) 외래 키 관계가 있으면 아무 테이블이나 먼저 삭제할 수 없다
외래 키가 걸린 구조에서는 참조당하는 쪽이부모 테이블, 참조하는 쪽이자식 테이블이다.
이때 자식 테이블이 아직 부모 테이블을 참조하고 있으면, 부모 테이블을 먼저 삭제할 수 없다.
예를 들어buytbl이usertbl을 참조하고 있다면,usertbl을 먼저 삭제하면 안 된다.
반드시 자식 테이블을 먼저 정리한 뒤 부모 테이블을 나중에 삭제해야 한다.
2) 삭제 순서는 보통 자식 -> 부모다데이터를 넣을 때는 보통
부모 -> 자식순서로 간다.
반대로 삭제할 때는자식 -> 부모순서로 가는 경우가 많다.
이유는 자식이 부모를 참조하고 있기 때문이다.
자식이 남아 있는데 부모를 먼저 지우면 참조 관계가 깨진다.
3) 여러 테이블을 한 번에 삭제할 수도 있다여러 테이블을 한 번에 삭제하는 문법도 있다.
또IF EXISTS를 붙이면 해당 테이블이 있을 때만 삭제하도록 만들 수 있다.
다만 여러 테이블을 함께 지울 때도, 머릿속에서는 여전히 외래 키 관계와 삭제 순서를 먼저 떠올려야 한다.
즉, 문법은 한 줄이어도 생각은자식 -> 부모순서로 해야 한다.
4) DELETE, TRUNCATE, DROP TABLE은 의미가 다르다이 셋은 모두 “지운다”는 느낌이 있지만 실제로는 다르다.
DELETE는 조건에 맞는 행을 지우고,
TRUNCATE는 테이블 구조를 남긴 채 전체 데이터를 비우며,
DROP TABLE은 테이블 자체를 없앤다.
그래서 테이블은 계속 사용할 건데 데이터만 전부 비우고 싶다면TRUNCATE가 더 맞고,
테이블 자체가 더 이상 필요 없으면DROP TABLE이 맞다.
코드 예제예제:
테이블 자체 삭제DROP TABLE buytbl; -- 실행결과 -- 테이블 삭제 완료이 코드는
buytbl테이블 자체를 삭제하는 예제다.
데이터만 비우는 것이 아니라 테이블 구조까지 함께 사라진다.
예제:
존재할 때만 삭제DROP TABLE IF EXISTS buytbl; -- 실행결과 -- 테이블 삭제 완료 또는 그대로 넘어감같은 삭제 명령을 여러 번 실행할 때 유용하다.
이미 없는 테이블 때문에 에러가 나는 상황을 줄일 수 있다.
예제:
여러 테이블 삭제DROP TABLE IF EXISTS buytbl, usertbl; -- 실행결과 -- 여러 테이블 삭제 완료이 코드는 여러 테이블을 한 번에 삭제하는 형태다.
다만 실제로는buytbl처럼 자식 테이블을 먼저 생각하고,usertbl같은 부모 테이블을 나중에 생각하는 흐름으로 이해하는 것이 좋다.
2. ALTER TABLE
개념
ALTER TABLE은 이미 만들어져 있는 테이블의 구조를 수정할 때 사용하는 명령이다.
처음 설계를 완벽하게 끝내면 좋지만, 실제로는 중간에 열을 추가해야 하거나, 이름을 바꿔야 하거나, 제약조건을 수정해야 하는 일이 생긴다.
이럴 때 기존 테이블을 다시 만들지 않고 구조만 손보는 방식이ALTER TABLE이다.
즉,ALTER TABLE은 열을 추가하거나 삭제하고, 이름이나 자료형을 바꾸고, 제약조건을 수정할 때 사용하는 명령이라고 보면 된다.
즉,ALTER TABLE은
기존 테이블을 유지한 채 구조를 바꾸는 명령이라고 보면 된다.
핵심 특징
1) 열을 추가할 수 있다새로운 정보를 저장해야 하면 열을 추가한다.
열을 추가하면 기본적으로 가장 뒤에 붙는다.
즉, 원래 있던 열 순서는 그대로 두고 새 열이 맨 끝에 추가된다고 이해하면 된다.
2) 열을 삭제할 수 있다더 이상 필요 없는 열은 삭제할 수 있다.
하지만 그 열에 제약조건이 걸려 있으면 바로 삭제되지 않을 수 있다.
예를 들어 어떤 열이PRIMARY KEY,FOREIGN KEY,UNIQUE같은 제약조건과 연결되어 있으면,
먼저 관련 제약조건을 정리한 뒤 열을 삭제해야 한다.
3) 열 이름과 데이터 형식을 바꿀 수 있다이미 만든 열이라도 이름을 바꾸거나 자료형을 바꿀 수 있다.
이때는 단순히 이름만 바꾸는 것이 아니라, 앞으로 이 열을 어떤 구조로 쓸지 다시 정의한다는 느낌으로 보면 된다.
4) 제약조건도 추가/삭제할 수 있다
ALTER TABLE은 열만 수정하는 명령이 아니다.
PRIMARY KEY,FOREIGN KEY,CHECK,DEFAULT같은 제약조건도 수정할 수 있다.
즉,ALTER TABLE은
열 구조 수정 + 제약조건 수정을 함께 처리하는 명령이다.
코드 예제예제:
열 추가ALTER TABLE usertbl ADD homepage VARCHAR(50); -- 실행결과 -- 열 추가 완료이 코드는
usertbl에homepage열을 추가하는 예제다.
기존 테이블은 그대로 두고, 새 정보만 더 저장할 수 있게 구조를 바꾼 것이다.
예제:
열 삭제ALTER TABLE usertbl DROP COLUMN homepage; -- 실행결과 -- 열 삭제 완료이 코드는 더 이상 필요 없는 열을 삭제하는 예제다.
다만 실제로는 해당 열에 제약조건이 연결되어 있으면, 그 제약조건부터 먼저 정리해야 한다.
예제:
열 이름과 데이터 형식 변경ALTER TABLE usertbl CHANGE COLUMN name uName VARCHAR(20) NULL; -- 실행결과 -- 열 구조 변경 완료이 코드에서 꼭 봐야 할 점은 앞의
name이 원래 열 이름이고, 뒤의uName이 바뀔 열 이름이라는 점이다.
CHANGE COLUMN은 기존 열 이름을 먼저 쓰고, 그다음 새 열 이름을 쓴다.
초보자는 이 순서를 자주 반대로 이해하므로 같이 기억해야 한다.
예제:
기본 키 삭제가 바로 안 되는 경우ALTER TABLE usertbl DROP PRIMARY KEY; -- 실행결과 -- 오류 발생이 명령은 문법만 보면 기본 키를 삭제하는 코드다.
하지만usertbl.userID가buytbl의FOREIGN KEY기준으로 연결되어 있다면 바로 실행되지 않을 수 있다.
즉, 먼저 자식 테이블 쪽 FOREIGN KEY를 정리한 뒤 부모 테이블의 PRIMARY KEY를 삭제해야 한다.
이건 문법 문제가 아니라, 테이블 사이의 관계 때문에 생기는 문제다.
헷갈리기 쉬운 부분
1) DELETE와 DROP TABLE은 전혀 다르다둘 다 삭제 명령처럼 보여도 의미가 다르다.
DELETE: 행 삭제DROP TABLE: 테이블 삭제즉,
DELETE를 해도 테이블은 남아 있고 다시 데이터를 넣을 수 있다.
하지만DROP TABLE을 하면 테이블 이름 자체가 사라진다.
2) 부모 테이블을 먼저 삭제하면 안 되는 경우가 많다외래 키가 걸려 있으면 보통 삭제 순서는
자식 -> 부모다.
데이터를 넣을 때의 순서와 반대로 생각해야 한다.
그래서 삭제 명령을 보기 전에 먼저 테이블 관계부터 떠올리는 습관이 중요하다.
3) ALTER TABLE은 열만 수정하는 명령이 아니다초보자는
ALTER TABLE을 보면 “열 추가하는 명령” 정도로 생각하기 쉽다.
하지만 실제로는 열 추가, 열 삭제, 이름 변경, 형식 변경, 제약조건 수정까지 모두 포함한다.
즉, 기존 테이블 구조를 손보는 거의 모든 작업을 맡는다고 보면 된다.
4) 제약조건이 있으면 바로 삭제되지 않을 수 있다열을 지우거나 기본 키를 없애고 싶어도, 그 열이 다른 테이블과 연결되어 있으면 바로 안 된다.
이건 문법 문제가 아니라 관계 문제다.
특히 기본 키가 다른 테이블에서 외래 키로 참조되고 있으면,
먼저 참조 관계를 정리해야 한다는 점을 꼭 기억해야 한다.
개념
뷰는 자주 사용하는 조회 결과를 이름 붙여 만든 조회용 객체다.
사용할 때는 테이블처럼 조회할 수 있어서, 처음에는 테이블처럼 보이는 조회용 객체라고 이해하면 된다. 한 번 만들어 두면 원본 테이블을 매번 길게 조회하지 않고, 뷰 이름으로 같은 결과를 다시 사용할 수 있다.
쉽게 말하면,
원본 데이터를 새로 저장하는 것이 아니라 보고 싶은 결과를 편하게 다시 꺼내 보기 위해 만든 객체에 가깝다.
예를 들어 직원 정보와 부서 정보를 함께 보기 위해 매번 조인을 써야 한다면,
그 조회 결과를 뷰로 만들어 두고 나중에는 뷰 이름만 조회하면 된다.
왜 필요한가
뷰를 사용하는 이유는 크게 두 가지다.
첫째, 복잡한 조회를 단순하게 만들기 위해서다.
조인, 조건, 정렬이 들어간 긴SELECT문은 한 번 쓸 때도 번거롭고, 나중에 다시 보면 헷갈리기 쉽다.
이럴 때 그 조회 결과를 뷰로 만들어 두면, 이후에는 긴 SQL을 다시 쓰지 않고 뷰 이름만 조회하면 된다.
둘째, 필요한 정보만 보여주기 위해서다.
원본 테이블의 모든 열을 그대로 보여주지 않고, 꼭 필요한 열만 골라서 보이게 할 수 있다.
그래서 사용자에게 필요한 정보만 제한해서 보여주는 구조를 만들 때 유용하다.
핵심 특징
1. 테이블 대신 뷰 이름으로 조회할 수 있다
뷰를 한 번 만들어 두면 이후에는 일반 테이블을 조회하듯 사용할 수 있다.
그래서 복잡한 원본 구조를 몰라도 필요한 결과를 쉽게 확인할 수 있다.
2. 긴 SQL을 짧게 바꿔 준다
여러 테이블을 조인하고 조건을 붙여야 하는 조회문도,
뷰로 만들어 두면 다음부터는 짧은 형태로 다시 사용할 수 있다.
3. 필요한 열만 따로 보여줄 수 있다
원본 테이블에는 정보가 많이 들어 있어도,
뷰에는 필요한 열만 골라 담을 수 있다.
그래서 꼭 필요한 정보만 보여주는 데 적합하다.
4. 데이터베이스 안에 만들어 두는 객체다
뷰는 잠깐 쓰고 끝나는 문장이 아니라,
이름을 붙여 만들어 두고 계속 사용할 수 있는 데이터베이스 객체다.
그래서 생성하고, 필요 없으면 삭제하면서 관리한다.
이해 흐름
뷰는 아래 순서로 이해하면 쉽다.
1. 먼저 원본 테이블이 있다.
2. 그중에서 자주 보는 결과를SELECT문으로 만든다.
3. 그 조회 결과에 이름을 붙인다.
4. 이후에는 긴 SQL 대신 그 이름을 조회해서 사용한다.이 흐름으로 보면, 뷰는 자주 쓰는 조회 결과를 다시 쓰기 쉽게 정리해 둔 객체라고 이해할 수 있다.
코드 예제
예제: 직원 이름과 부서명을 쉽게 조회하는 뷰 만들기
CREATE VIEW v_emp_dept AS SELECT e.ename, d.dname FROM emp e JOIN dept d ON e.deptno = d.deptno; SELECT * FROM v_emp_dept; -- 출력결과 예시 -- ename dname -- SMITH RESEARCH -- ALLEN SALES -- WARD SALES이 코드는 직원 이름과 부서명을 매번 직접 조인해서 조회하지 않도록,
자주 쓰는 결과를v_emp_dept라는 이름의 뷰로 만든 예제다.
핵심은CREATE VIEW뒤에 뷰 이름을 쓰고,
그 뒤에 저장해 둘 조회문을 붙인다는 점이다.
이렇게 한 번 만들어 두면 이후에는 다음처럼 더 짧게 사용할 수 있다.SELECT * FROM v_emp_dept WHERE dname = 'SALES'; -- 출력결과 예시 -- ename dname -- ALLEN SALES -- WARD SALES원래라면
emp와dept를 다시 조인해야 하지만,
뷰를 만들고 나면 그 과정을 반복하지 않아도 된다.
이 점이 뷰의 가장 큰 장점이다.
헷갈리기 쉬운 부분
1. 뷰는 테이블처럼 보이지만, 테이블 자체와 똑같다고 생각하면 헷갈린다
조회할 때는 테이블처럼 사용할 수 있다.
하지만 처음 배울 때는 원본 테이블을 대신해서 결과를 보여 주는 조회용 객체라고 이해하는 편이 가장 쉽다.
2. 새로운 데이터를 따로 저장하는 테이블이라고 생각하면 헷갈리기 쉽다
뷰를 보면 새로운 테이블이 하나 더 생긴 것처럼 느껴질 수 있다.
하지만 초보자 기준에서는, 데이터를 새로 저장하는 용도라기보다 자주 쓰는 조회문을 편하게 다시 사용하기 위한 객체라고 이해하는 편이 쉽다.
3. 뷰의 핵심은 조회를 단순하게 만드는 데 있다
뷰는 단순히 모양만 바꾸는 기능이 아니다.
복잡한 SQL을 짧게 만들고, 필요한 정보만 보이게 해서 조회를 더 쉽게 만드는 데 의미가 있다.
한 줄로 잡기
뷰는 자주 사용하는 조회 결과를 이름 붙여 만들어 두고, 나중에 테이블처럼 다시 사용할 수 있게 한 조회용 객체다.