SQL
SQL(Structured Query Language): 관계형 데이터베이스와 통신하기 위한 표준 언어. 데이터를 정의·조작·제어하는 명령어 집합이다.
왜 쓰는가?
DBMS마다 내부 구현이 다르지만, SQL이라는 표준 언어 덕분에 MySQL, PostgreSQL, Oracle 등 어떤 RDBMS든 같은 방식으로 데이터를 다룰 수 있다. 개발자가 DBMS 내부 파일 구조를 몰라도 선언적(무엇을 원하는지)으로 데이터를 요청할 수 있다.
특징
- 선언형 언어: "어떻게"가 아니라 "무엇을" 원하는지 기술한다. 실행 계획은 DBMS의 쿼리 옵티마이저가 결정한다.
- 집합 기반: 행 하나가 아니라 결과 집합(테이블) 단위로 동작한다.
- ANSI/ISO 표준: 표준이 있지만 DBMS마다 방언(Dialect)이 존재한다. (예: MySQL의
LIMITvs Oracle의ROWNUM)
SELECT 기본 구조
SELECT 컬럼1, 컬럼2 -- 3. 조회할 컬럼 선택
FROM 테이블명 -- 1. 대상 테이블
WHERE 조건 -- 2. 행 필터링
GROUP BY 그룹 기준 컬럼 -- 4. 그룹화
HAVING 그룹 조건 -- 5. 그룹 필터링
ORDER BY 정렬 기준 컬럼 -- 6. 정렬
LIMIT n; -- 7. 행 수 제한
언제 쓰는지
| 명령어 | 사용 시기 | 선택 기준 |
|---|---|---|
| SELECT | 데이터 조회 필요 | 모든 조회 작업 |
| INSERT | 새 데이터 추가 | 단일 또는 대량 INSERT |
| UPDATE | 기존 데이터 수정 | WHERE로 대상 명확히 |
| DELETE | 데이터 삭제 | 주의: WHERE 필수 |
| CREATE | 테이블·뷰 생성 | 스키마 설계 후 |
| ALTER | 스키마 변경 | 컬럼 추가/변경/삭제 |
| DROP | 객체 삭제 | 영구 삭제, 주의 필요 |
| TRUNCATE | 데이터 전체 삭제 | DELETE보다 빠름, 롤백 불가 |
장점
| 장점 | 설명 |
|---|---|
| 표준 언어 | DBMS 상관없이 동일 문법 (방언 제외) |
| 가독성 | 선언형으로 직관적 |
| 강력함 | 복잡한 쿼리도 한 번에 표현 |
| 성능 | 옵티마이저가 최적 실행 계획 선택 |
| 유지보수 | SQL은 데이터베이스 진입점으로 명확 |
단점
| 단점 | 설명 |
|---|---|
| 방언(Dialect) | DBMS마다 SQL 확장 문법 다름 (LIMIT vs ROWNUM) |
| 성능 예측 어려움 | 옵티마이저 동작이 쿼리에 따라 달라짐 |
| 복잡한 쿼리 | 매우 복잡한 로직은 쓰기 어려움 (프로시저 고려) |
| 실행 계획 이해 | 성능 튜닝 위해 쿼리 계획 분석 필요 |
SQL 실행 순서
SQL은 작성 순서와 실제 실행 순서가 다르다. 옵티마이저가 아래 순서로 처리한다.
| 실행 순서 | 절 | 역할 |
|---|---|---|
| 1 | FROM |
대상 테이블 결정 (JOIN 포함) |
| 2 | WHERE |
행 단위 필터링 (집계 전) |
| 3 | GROUP BY |
지정 컬럼 기준으로 그룹화 |
| 4 | HAVING |
그룹 단위 필터링 (집계 후) |
| 5 | SELECT |
출력할 컬럼·별칭 확정 |
| 6 | ORDER BY |
정렬 |
| 7 | LIMIT |
행 수 제한 |
SELECT 별칭(alias)은 WHERE·HAVING에서 쓸 수 없다 — SELECT price * 0.9 AS 할인가로 정의한 별칭은 WHERE 할인가 > 1000 에서 사용 불가. SELECT(5번)가 WHERE(2번)보다 늦게 실행되기 때문이다.
-- 잘못된 예 (MySQL에서 오류)
SELECT price * 0.9 AS 할인가 FROM product WHERE 할인가 > 1000; -- ❌
-- 올바른 예
SELECT price * 0.9 AS 할인가 FROM product WHERE price * 0.9 > 1000; -- ✅
단, ORDER BY는 예외적으로 SELECT 별칭 사용 가능 (MySQL 기준).
성능 포인트: WHERE이 GROUP BY 전에 실행되므로, 집계 전에 최대한 많은 행을 걸러낼수록 빠르다. HAVING 대신 WHERE로 필터링 가능한 조건은 WHERE에 두는 것이 좋다.
DDL · DML · DCL · TCL
SQL 명령어는 역할에 따라 4가지로 분류된다.
DDL (Data Definition Language) — 구조 정의
| 명령어 | 설명 |
|---|---|
CREATE |
테이블·뷰·인덱스 등 객체 생성 |
ALTER |
객체 구조 변경 (컬럼 추가·삭제·타입 변경) |
DROP |
객체 완전 삭제 |
TRUNCATE |
테이블의 모든 데이터 삭제 (구조는 유지) |
RENAME |
객체 이름 변경 |
CREATE TABLE member (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
age INT
);
ALTER TABLE member ADD COLUMN email VARCHAR(100);
DROP TABLE member;
TRUNCATE TABLE member; -- DELETE보다 빠르지만 롤백 불가 (MySQL 기준)
위험: DDL은 대부분 DBMS에서 자동 커밋(Auto-Commit) 된다. DROP, TRUNCATE 실행 후 ROLLBACK이 불가능한 경우가 많다. (PostgreSQL은 트랜잭션 내 DDL 롤백 가능)
DML (Data Manipulation Language) — 데이터 조작
| 명령어 | 설명 |
|---|---|
SELECT |
데이터 조회 |
INSERT |
데이터 삽입 |
UPDATE |
데이터 수정 |
DELETE |
데이터 삭제 |
INSERT INTO member (name, age) VALUES ('김철수', 27);
SELECT * FROM member WHERE age > 20 ORDER BY name;
UPDATE member SET age = 28 WHERE id = 1;
DELETE FROM member WHERE id = 1;
주의: UPDATE와 DELETE에서 WHERE 절을 빠뜨리면 전체 행이 영향을 받는다. 실행 전 반드시 SELECT로 대상 확인을 권장한다.
DCL (Data Control Language) — 권한 제어
| 명령어 | 설명 |
|---|---|
GRANT |
사용자에게 권한 부여 |
REVOKE |
사용자의 권한 회수 |
TCL (Transaction Control Language) — 트랜잭션 제어
| 명령어 | 설명 |
|---|---|
COMMIT |
트랜잭션 내 변경사항 영구 저장 |
ROLLBACK |
트랜잭션 내 변경사항 취소 |
SAVEPOINT |
트랜잭션 내 중간 저장 지점 설정 |