SQL DDL·DML·DCL의 역할과 데이터베이스 운영 흐름
SQL의 DDL, DML, DCL이 담당하는 스키마·데이터·권한 관리 역할과 트랜잭션 처리 흐름을 정리합니다.
2026-08-14 · 최초 발행 2025-08-10
구조를 바꾸는 명령과 데이터를 바꾸는 명령은 다르다
관계형 데이터베이스에서 SQL은 데이터를 조회하는 언어에만 머물지 않는다. 테이블과 인덱스를 정의하고, 저장된 값을 변경하며, 사용자 권한과 트랜잭션까지 통제한다. 이 역할을 구분하는 기준이 DDL, DML, DCL이다.
DDL은 데이터베이스의 형태를 다루고, DML은 그 안의 데이터를 다룬다. DCL은 누가 무엇을 할 수 있는지와 변경 결과를 확정하거나 되돌리는 흐름을 맡는다.
DDL로 스키마와 객체를 정의한다
DDL(Data Definition Language)은 데이터베이스 스키마를 만들거나 바꾸는 명령어 집합이다. 테이블, 뷰, 인덱스, 프로시저 같은 객체의 구조를 대상으로 한다.
CREATE는 객체를 새로 만들 때 사용한다.
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(100),
hire_date DATE,
salary DECIMAL(10,2)
);
기존 객체에 열을 추가하는 작업은 ALTER로 처리한다.
ALTER TABLE employees ADD COLUMN department VARCHAR(50);
객체를 제거하거나 테이블의 데이터만 모두 비울 때는 각각 DROP, TRUNCATE를 사용한다.
DROP TABLE employees;
TRUNCATE TABLE employees;
객체 이름 변경은 RENAME으로 수행한다.
RENAME TABLE employees TO staff;
DDL은 실행과 함께 자동 커밋이 발생하는 경우가 많고, 롤백할 수 없는 경우도 많다. 데이터베이스 구조에 직접 영향을 주므로 DBA가 주로 다루며, 시스템 자원 사용량을 고려해 사용량이 적은 시간대에 계획적으로 수행할 필요가 있다.
DML은 저장된 데이터를 조회하고 변경한다
DML(Data Manipulation Language)은 테이블 안의 데이터를 검색, 삽입, 수정, 삭제하는 명령어다. 애플리케이션이 일상적으로 수행하는 데이터 처리는 대체로 DML에 속한다.
부서가 IT인 직원의 이름과 급여를 조회하는 예시는 다음과 같다.
SELECT name, salary FROM employees WHERE department = 'IT';
새 데이터를 넣는 명령은 INSERT다.
INSERT INTO employees (id, name, hire_date, salary)
VALUES (101, 'John Doe', '2023-01-15', 75000.00);
값 변경에는 UPDATE, 조건에 맞는 행 삭제에는 DELETE를 쓴다.
UPDATE employees SET salary = salary * 1.1 WHERE department = 'Sales';
DELETE FROM employees WHERE hire_date < '2020-01-01';
DML은 트랜잭션 안에서 실행되며 COMMIT 또는 ROLLBACK으로 마무리된다. 실제 데이터 값에 영향을 주지만, 권한이 있으면 일반 사용자도 실행할 수 있다. 트랜잭션이 확정되기 전이라면 변경 결과를 롤백할 수 있다.
권한과 트랜잭션 경계를 다루는 DCL
DCL(Data Control Language)은 데이터베이스 접근 권한과 트랜잭션을 제어한다. 보안과 데이터 무결성을 함께 고려해야 하는 영역이다.
사용자에게 조회와 삽입 권한을 주거나, 부여했던 삽입 권한을 회수할 수 있다.
GRANT SELECT, INSERT ON employees TO user_name;
REVOKE INSERT ON employees FROM user_name;
변경 사항을 영구 반영하려면 COMMIT을, 이전 상태로 되돌리려면 ROLLBACK을 사용한다.
COMMIT;
ROLLBACK;
트랜잭션 중간에 되돌아갈 지점을 남기려면 SAVEPOINT를 둔다.
SAVEPOINT save1;
-- 이후 ROLLBACK TO save1; 명령으로 해당 지점까지만 롤백 가능
DCL은 사용자별 권한 관리와 데이터 일관성 유지에 쓰인다. 권한은 필요한 최소한만 부여하는 최소 권한 원칙으로 설계하는 것이 보안 관리의 기준이 된다.
설계부터 운영까지 이어지는 SQL의 역할
데이터베이스 구현은 요구사항 분석과 설계에서 시작해 스키마 정의, 권한 설정, 초기 데이터 입력, 애플리케이션 운영으로 이어진다. 이때 DDL, DCL, DML은 서로 다른 시점과 책임을 가진다.
업무 요청 하나가 여러 DML 문장으로 구성될 때는 트랜잭션 경계가 중요하다. 정상 처리 시에는 변경을 확정하고, 오류가 발생하면 이전 상태로 복원한다.
온라인 쇼핑몰에서의 적용 모습
온라인 쇼핑몰에서는 고객, 상품, 주문, 주문 상세를 먼저 스키마로 정의한다. 상품 재고 변동을 위한 인덱스도 이 단계에서 추가한다.
-- 고객 테이블 생성
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100) UNIQUE,
registration_date DATE
);
-- 상품 테이블 생성
CREATE TABLE products (
product_id INT PRIMARY KEY,
name VARCHAR(200),
price DECIMAL(10,2),
stock_quantity INT
);
-- 주문 테이블 생성
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
order_date DATETIME,
total_amount DECIMAL(12,2),
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
-- 주문 상세 테이블 생성
CREATE TABLE order_items (
item_id INT PRIMARY KEY,
order_id INT,
product_id INT,
quantity INT,
price DECIMAL(10,2),
FOREIGN KEY (order_id) REFERENCES orders(order_id),
FOREIGN KEY (product_id) REFERENCES products(product_id)
);
-- 상품 재고 변동 트리거를 위한 인덱스 추가
ALTER TABLE products ADD INDEX idx_product_stock (stock_quantity);
주문이 들어오면 주문과 주문 상세를 기록하고, 상품 재고를 변경한 뒤 트랜잭션을 완료한다. 이후 주문 데이터를 바탕으로 인기 상품을 조회할 수 있다.
-- 상품 데이터 입력
INSERT INTO products (product_id, name, price, stock_quantity)
VALUES (1001, '스마트폰 케이스', 15000.00, 100),
(1002, '블루투스 이어폰', 89000.00, 50),
(1003, '노트북 파우치', 35000.00, 75);
-- 고객이 주문할 때
BEGIN; -- 트랜잭션 시작
-- 주문 생성
INSERT INTO orders (order_id, customer_id, order_date, total_amount)
VALUES (5001, 101, NOW(), 119000.00);
-- 주문 상세 정보 입력
INSERT INTO order_items (item_id, order_id, product_id, quantity, price)
VALUES (10001, 5001, 1001, 2, 15000.00),
(10002, 5001, 1002, 1, 89000.00);
-- 재고 수량 업데이트
UPDATE products SET stock_quantity = stock_quantity - 2 WHERE product_id = 1001;
UPDATE products SET stock_quantity = stock_quantity - 1 WHERE product_id = 1002;
COMMIT; -- 트랜잭션 완료
-- 상품 조회 (인기 상품)
SELECT p.name, p.price, COUNT(oi.product_id) as order_count
FROM products p
JOIN order_items oi ON p.product_id = oi.product_id
GROUP BY p.product_id
ORDER BY order_count DESC
LIMIT 10;
역할에 맞는 권한을 설정하고, 결제 실패처럼 부분 취소가 필요한 상황에는 저장 지점을 기준으로 롤백할 수 있다.
-- 마케팅 부서 사용자에게 고객 정보 조회 권한 부여
GRANT SELECT ON customers TO marketing_user;
-- 재고 관리자에게 상품 재고 관리 권한 부여
GRANT SELECT, UPDATE ON products TO inventory_manager;
-- 판매 담당자에게 주문 관련 권한 부여
GRANT SELECT, INSERT ON orders TO sales_staff;
GRANT SELECT, INSERT ON order_items TO sales_staff;
-- 결제 실패 시 주문 취소 처리
SAVEPOINT before_payment;
-- 결제 처리 로직...
-- 결제 실패 시
ROLLBACK TO before_payment;
개발 수명주기에서 바뀌는 대상
스키마 변경은 DDL로, 초기 데이터와 운영 중 데이터 수정은 DML로, 권한 변경은 DCL로 되돌아간다. 데이터베이스 객체와 데이터, 권한을 분리해 관리하면 역할과 책임도 분명해진다. 트랜잭션 관리는 원자성(Atomicity), 일관성(Consistency), 격리성(Isolation), 지속성(Durability)의 ACID 속성을 보장하고 장애 발생 시 데이터 복구를 쉽게 한다.
DDL, DML, DCL의 경계를 이해하면 구조 변경의 영향, 쿼리 성능, 접근 권한, 복구 절차를 각각의 책임 범위에서 판단할 수 있다. 특히 대규모 시스템에서는 각 명령어가 데이터 무결성, 시스템 성능, 보안에 미치는 영향을 고려해 신중하게 사용해야 한다.