공통 SQL를 실무 흐름으로 이해하기
관계형 데이터베이스의 핵심인 SQL(Structured Query Language)의 공통 표준 문법과 성능 튜닝의 기초를 다룹니다. DDL, DML부터 조인(Join), 서브쿼리, 그룹화 및 인덱스를 활용한 조회 성능 개선까지 핵심 실무 지식을 학습합니다. 이 가이드는 개념을 나열하기보다, 실제 프로젝트에서 판단해야 하는 순서대로 내용을 따라갈 수 있게 구성했습니다.
관계형 데이터베이스의 핵심인 SQL(Structured Query Language)의 공통 표준 문법과 성능 튜닝의 기초를 다룹니다. DDL, DML부터 조인(Join), 서브쿼리, 그룹화 및 인덱스를 활용한 조회 성능 개선까지 핵심 실무 지식을 학습합니다.
관계형 데이터베이스의 핵심인 SQL(Structured Query Language)의 공통 표준 문법과 성능 튜닝의 기초를 다룹니다. DDL, DML부터 조인(Join), 서브쿼리, 그룹화 및 인덱스를 활용한 조회 성능 개선까지 핵심 실무 지식을 학습합니다. 이 가이드는 개념을 나열하기보다, 실제 프로젝트에서 판단해야 하는 순서대로 내용을 따라갈 수 있게 구성했습니다.
쿼리 문법과 함께 스키마 설계, 인덱스, 트랜잭션, 권한, 백업까지 운영 관점으로 봅니다.
글로 읽은 내용을 머릿속에 오래 남기려면 먼저 흐름을 그림으로 잡는 편이 좋습니다. 아래 두 그림은 공통 SQL를 학습할 때 계속 되돌아볼 수 있는 기준 지도입니다.
공통 SQL를 처음 펼칠 때는 세부 명령보다 큰 그림이 먼저입니다. 이 섹션에서는 앞으로 배울 개념들이 어떤 문제를 풀기 위해 등장했는지부터 잡아봅니다.
| SQL 분류 | 설명 | 대표 명령어 |
|---|---|---|
| DDL (Data Definition Language) | 데이터 구조(테이블, 인덱스 등)를 정의 및 변경 | CREATE, ALTER, DROP, TRUNCATE |
| DML (Data Manipulation Language) | 데이터를 삽입, 조회, 수정, 삭제 | SELECT, INSERT, UPDATE, DELETE |
| DCL (Data Control Language) | 데이터베이스 접근 권한 및 보안 설정 | GRANT, REVOKE |
| TCL (Transaction Control Language) | 트랜잭션의 제어와 일관성 보장 | COMMIT, ROLLBACK, SAVEPOINT |
여기서는 테이블 정의 & 제약조건 (DDL)을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.
-- 부서 테이블 생성
CREATE TABLE departments (
dept_id INT PRIMARY KEY,
dept_name VARCHAR(50) NOT NULL UNIQUE
);
-- 사원 테이블 생성
CREATE TABLE employees (
emp_id INT PRIMARY KEY,
emp_name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE,
salary DECIMAL(10, 2) CHECK (salary > 0),
dept_id INT,
hire_date DATE DEFAULT CURRENT_DATE,
CONSTRAINT fk_dept FOREIGN KEY (dept_id) REFERENCES departments(dept_id) ON DELETE SET NULL
);여기서는 데이터 조회 & 조작 (DML)을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.
-- 데이터 삽입
INSERT INTO departments (dept_id, dept_name) VALUES (10, 'Engineering');
INSERT INTO employees (emp_id, emp_name, salary, dept_id) VALUES (1, 'John Doe', 75000.00, 10);
-- 데이터 조회 (필터링 및 정렬)
SELECT emp_name, salary
FROM employees
WHERE salary >= 50000
ORDER BY salary DESC;
-- 데이터 수정 및 삭제
UPDATE employees SET salary = salary * 1.1 WHERE emp_id = 1;
DELETE FROM employees WHERE emp_id = 1;여기서는 다중 테이블 조인 (JOIN)을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.
-- INNER JOIN: 양쪽 테이블에 모두 일치하는 행만 조회
SELECT e.emp_name, d.dept_name
FROM employees e
INNER JOIN departments d ON e.dept_id = d.dept_id;
-- LEFT OUTER JOIN: 왼쪽 테이블 전체와 오른쪽의 일치하는 행 조회 (일치하지 않으면 NULL)
SELECT e.emp_name, d.dept_name
FROM employees e
LEFT OUTER JOIN departments d ON e.dept_id = d.dept_id;여기서는 그룹화 및 집계 (GROUP BY / HAVING)을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.
-- 부서별 사원 수와 평균 급여 조회 (평균 급여 60000 이상인 부서만)
SELECT dept_id, COUNT(*) AS emp_count, AVG(salary) AS avg_salary
FROM employees
GROUP BY dept_id
HAVING AVG(salary) >= 60000;여기서는 DCL 권한 관리 & 보안 (GRANT / REVOKE)을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.
-- 1. 사용자 생성 (공통 RDB 개념)
CREATE USER read_only_user IDENTIFIED BY 'secure_password';
-- 2. 오브젝트 권한 부여 (특정 테이블의 조회 권한만 허용)
GRANT SELECT ON employees TO read_only_user;
-- 3. 여러 권한을 묶은 롤(Role) 생성 및 부여
CREATE ROLE app_developer_role;
GRANT SELECT, INSERT, UPDATE ON employees TO app_developer_role;
GRANT SELECT, INSERT ON departments TO app_developer_role;
GRANT app_developer_role TO read_only_user;
-- 4. 권한 회수
REVOKE UPDATE ON employees FROM app_developer_role;여기서는 캐릭터셋과 인코딩 가이드을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.
-- ── 데이터베이스 캐릭터셋 확인용 공통 쿼리 ──
-- [MySQL / MariaDB]
SHOW VARIABLES LIKE 'character_set_database';
SHOW VARIABLES LIKE 'collation_database';
-- [Oracle]
SELECT * FROM NLS_DATABASE_PARAMETERS
WHERE PARAMETER IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');
-- [PostgreSQL]
SELECT datname, pg_encoding_to_char(encoding), datcollate, datctype
FROM pg_database
WHERE datname = current_database();| 캐릭터셋 | 인코딩 방식 | 영문 1자 | 한글 1자 | 이모지 지원 | 특징 및 권장 용도 |
|---|---|---|---|---|---|
| ASCII | Single-byte (7-bit) | 1 Byte | 지원 불가 | ❌ | 영문 및 특수기호만 지원, 초경량 저장소 |
| EUC-KR | Multi-byte 완성형 | 1 Byte | 2 Bytes | ❌ | 완성형 한글 전용, 레거시 시스템 및 스토리지 절감 필요 시 |
| MS949 | Multi-byte 확장완성형 | 1 Byte | 2 Bytes | ❌ | Windows 한국어 기본값, EUC-KR의 한글 미지원 확장 버전 |
| UTF-8 | Variable-byte (Unicode) | 1 Byte | 3 Bytes | ❌ (일부) | 전 세계 다국어 웹 표준, 대부분의 캐릭터 지원 |
| utf8mb4 (MySQL) | Variable-byte (Unicode) | 1 Byte | 3 Bytes | ⭐ (4 Bytes) | 글로벌 표준, 이모지(Emoji) 및 고대문자 완벽 지원 (MySQL 권장) |
| UTF-16 | Fixed/Variable (2~4 Bytes) | 2 Bytes | 2 Bytes | ⭐ (4 Bytes) | Java, Windows 내부 문자열 표현 표준, 동아시아 다국어 대량 저장 시 유리 |
여기서는 인덱스와 실행 계획 기초을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.
-- 인덱스 생성
CREATE INDEX idx_emp_salary ON employees(salary);
-- 실행 계획 확인 (DBMS 제품군에 따라 EXPLAIN 형식은 상이)
EXPLAIN
SELECT emp_name, salary
FROM employees
WHERE salary > 80000;공통 SQL 실무 설계은 선택지가 갈리는 지점입니다. 표를 기준으로 각 방법의 쓰임새와 운영상의 차이를 비교해두면 이후 판단이 훨씬 쉬워집니다.
| 결정 지점 | 확인 질문 | 실무 기준 |
|---|---|---|
| 경계 | 공통 SQL 코드에서 바뀌기 쉬운 부분은 어디인가? | 입출력, 설정, 외부 연동, 핵심 규칙을 분리합니다. |
| 상태 | 상태가 어디서 생성되고 어디서 사라지는가? | 상태 소유자와 수명 주기를 코드로 드러냅니다. |
| 장애 | 실패했을 때 호출자는 무엇을 받는가? | timeout, fallback, error contract를 먼저 정합니다. |
이 섹션은 공통 SQL 운영 기준을 실무 관점에서 정리합니다. 개념을 외우기보다, 어떤 상황에서 이 기준을 꺼내 쓸지에 초점을 맞춰보세요.
공통 SQL 검증 전략은 선택지가 갈리는 지점입니다. 표를 기준으로 각 방법의 쓰임새와 운영상의 차이를 비교해두면 이후 판단이 훨씬 쉬워집니다.
| 품질 축 | 검증 방법 | 완료 기준 |
|---|---|---|
| 정확성 | 정상/실패 케이스를 자동화합니다. | 핵심 시나리오가 재현 가능하게 통과합니다. |
| 회귀 방지 | 버그 수정 시 동일 케이스를 테스트로 남깁니다. | 같은 장애가 다시 배포되지 않습니다. |
| 운영성 | 로그, 메트릭, 알림을 확인합니다. | 문제가 생겼을 때 원인 추적 경로가 있습니다. |