관계 데이터베이스에서 데이터를 다루려면 결국 사람이 타이핑할 수 있는 언어가 필요하다. 그 표준 언어가 SQL(Structured Query Language)이다.
SQL은 데이터베이스를 다루는 사람이라면 반드시 손에 익혀야 하는 도구다. 오늘은 SQL의 전체 지도(세 가지 분류)와 핵심 문장들을 정리했다.
여기서는 "SQL이 어떻게 구조화되어 있는가"라는 큰 틀에 집중한다. 실제 환경에서 함수·조인·서브쿼리를 손으로 다루는 실습은 범위를 벗어나므로 따로 다룬다.
1. SQL의 분류
모든 SQL 문장은 역할에 따라 셋 중 하나에 속한다.
| 분류 | 대표 명령 | 역할 | 대상 |
|---|---|---|---|
| DDL (Data Definition Language, 정의어) | CREATE, ALTER, DROP |
테이블·스키마 구조 정의 | 틀(스키마) |
| DML (Data Manipulation Language, 조작어) | SELECT, INSERT, UPDATE, DELETE |
데이터 검색·삽입·수정·삭제 | 내용(인스턴스) |
| DCL (Data Control Language, 제어어) | GRANT, REVOKE, COMMIT, ROLLBACK |
권한·트랜잭션 제어 | 권한·작업 단위 |
이 분류를 의식하고 명령어를 보니 "구조를 건드리는가, 데이터를 건드리는가, 권한·확정을 건드리는가"가 한눈에 정리됐다.
특히 DROP(DDL, 테이블 자체를 없앰)과 DELETE(DML, 테이블은 두고 행만 지움)는 혼동하기 쉬운데, 분류를 알면 자연히 구별된다.
2. DDL: 테이블 정의
테이블을 만들 때는 각 열의 데이터 타입과 제약조건을 함께 선언한다. 데이터 무결성을 지키는 규칙들이 여기서 실제 문법으로 등장한다.
CREATE TABLE 고객 (
고객아이디 VARCHAR(20) PRIMARY KEY, -- 기본키: NOT NULL + 유일 (개체 무결성)
고객이름 VARCHAR(10) NOT NULL, -- NULL 금지
나이 INT,
등급 VARCHAR(10) DEFAULT 'silver', -- 미입력 시 기본값
담당자 VARCHAR(20) REFERENCES 직원(아이디) -- 외래키 (참조 무결성)
);
ALTER TABLE 고객 ADD 적립금 INT; -- 열 추가 (구조 변경)
DROP TABLE 고객; -- 테이블 자체 삭제
위 선언의 의미를 짚어보면 다음과 같다.
PRIMARY KEY: 기본키. NULL이 될 수 없고 중복될 수 없다(개체 무결성).REFERENCES: 외래키. 참조 대상에 실재하는 값만 허용한다(참조 무결성).DEFAULT: 값을 입력하지 않으면 들어갈 기본값.
즉 무결성은 추상적 원칙이 아니라 CREATE TABLE 한 줄로 시스템에 등록되는 실물 규칙이었다. 한 번 걸어두면 이후 어떤 잘못된 INSERT도 DBMS가 거부한다.
3. DML: 데이터 조작
-- 삽입
INSERT INTO 고객(고객아이디, 고객이름, 나이) VALUES ('apple', '김연아', 30);
-- 검색
SELECT 고객이름, 나이 FROM 고객 WHERE 나이 >= 20 ORDER BY 나이 DESC;
-- 수정
UPDATE 고객 SET 등급 = 'gold' WHERE 나이 >= 30;
-- 삭제
DELETE FROM 고객 WHERE 고객아이디 = 'apple';
이 중 압도적으로 자주 쓰는 건 SELECT다. 그리고 SELECT의 절(clause)에는 정해진 작성 순서가 있다.
SELECT 속성 → FROM 테이블 → WHERE 행 조건 → GROUP BY 그룹화 → HAVING 그룹 조건 → ORDER BY 정렬
UPDATE와 DELETE에서 가장 새겨둔 건 WHERE 절을 빠뜨리지 말라는 것이다.
WHERE없는UPDATE 고객 SET 등급='gold'→ 모든 고객의 등급이 바뀐다.WHERE없는DELETE FROM 고객→ 전체 행이 지워진다.
한 줄 누락이 전 데이터를 날리는 사고로 직결된다. 그래서 실무에서는 SELECT로 대상을 먼저 확인한 뒤, 같은 조건으로 UPDATE/DELETE를 실행하는 습관을 들인다고 한다. 이건 직접 손에 익혀둬야 할 안전장치라 따로 적어뒀다.
집계 함수와 GROUP BY
COUNT, SUM, AVG, MAX, MIN은 여러 행을 하나의 값으로 요약하는 집계 함수다. GROUP BY와 함께 쓰면 "등급별 평균 나이", "부서별 인원 수"처럼 그룹 단위 통계를 낸다.
둘 다 조건을 거는 절이지만 대상과 시점이 다르다.
- WHERE: 그룹으로 묶기 전, 개별 행에 거는 조건.
- HAVING: 그룹으로 묶은 후, 그룹에 거는 조건. (예: "회원 수가 3명 이상인 등급만")
그래서 HAVING에는 집계 함수(COUNT(*) >= 3 등)를 쓸 수 있지만 WHERE에는 쓸 수 없다. 행이 아직 그룹으로 묶이지 않았으니 집계할 대상이 없기 때문이다.
작성 순서(WHERE → GROUP BY → HAVING)가 곧 "행 거르기 → 묶기 → 그룹 거르기"라는 처리 흐름을 그대로 반영한다.
오늘 느낀 점
- SQL 명령을 무작정 외우기보다 DDL·DML·DCL 세 분류로 먼저 나누니,
DROP과DELETE처럼 헷갈리던 명령이 자연히 구별됐다. - 무결성이 추상적 원칙이 아니라
CREATE TABLE의PRIMARY KEY·REFERENCES로 실제 등록되는 규칙이라는 걸 코드로 보니 와닿았다. - WHERE와 HAVING의 차이가 "묶기 전이냐 후냐"라는 처리 시점에서 나온다는 점에서, SQL 절의 순서가 그냥 문법이 아니라 처리 흐름이라는 게 보였다.
한 걸음 더
- SQL의 진짜 묘미는 작성 순서와 실제 처리(논리적 평가) 순서가 다르다는 데 있다. 우리는
SELECT를 맨 앞에 쓰지만, DBMS는FROM(테이블 확보) →WHERE(행 필터) →GROUP BY(묶기) →HAVING(그룹 필터) →SELECT(열 추출) →ORDER BY(정렬) 순으로 처리한다.SELECT에서 만든 열 별칭을WHERE에서 못 쓰는 이유가 여기 있다.WHERE가 평가될 때SELECT는 아직 실행되지 않았기 때문이다. - SQL이 선언적 언어라는 점은 문법에서 드러난다. 우리는 "나이 ≥ 20인 행을 한 줄씩 순회하라"고 절차를 쓰지 않고,
WHERE 나이 >= 20이라는 참이어야 할 조건만 선언한다. "어떻게 찾을지"는 DBMS의 최적화기에 맡긴다. 이 선언적 성격이 SQL이 수십 년간 살아남은 비결이다. - SQL에는 ANSI/ISO 표준이 있지만, 실제로는 DBMS마다 방언(dialect)이 있다. 오라클은
VARCHAR2와DUAL테이블·SYSDATE를, MySQL은LIMIT을, SQL Server는TOP을 쓰는 식이다. 표준을 먼저 익히고 각 DBMS의 방언을 더하는 순서가 길게 보면 이득이다.
'data > database' 카테고리의 다른 글
| [데이터베이스] 05. 관계 데이터 연산 (0) | 2026.08.25 |
|---|---|
| [데이터베이스] 04. 관계 데이터 모델 (0) | 2026.08.18 |
| [데이터베이스] 03. 데이터 모델링 (개체-관계 모델) (0) | 2026.07.09 |
| [데이터베이스] 02. DBMS 데이터베이스 시스템 (0) | 2026.06.25 |
| [데이터베이스] 01. 데이터베이스 기본 개념 (0) | 2026.06.24 |