What is SQL, and what do DDL, DML, DCL, and TCL stand for?

3 minbeginnersql-basicsddldmlterminology

Quick Answer

SQL (Structured Query Language) is the standard declarative language for defining and manipulating relational data. Its statements fall into four categories: **DDL** (Data Definition Language — `CREATE`, `ALTER`, `DROP`) changes schema structure; **DML** (Data Manipulation Language — `SELECT`, `INSERT`, `UPDATE`, `DELETE`) reads and writes rows; **DCL** (Data Control Language — `GRANT`, `REVOKE`) manages permissions; **TCL** (Transaction Control Language — `COMMIT`, `ROLLBACK`, `SAVEPOINT`) manages transaction boundaries.

Detailed Answer

SQL is split into sub-languages by what kind of change a statement makes, and that split matters in practice because it determines things like transaction behavior, required privileges, and whether an operation can be rolled back.

The four categories

CategoryFull nameExample statementsWhat it affects
DDLData Definition LanguageCREATE TABLE, ALTER TABLE, DROP TABLE, TRUNCATESchema/structure (tables, indexes, constraints)
DMLData Manipulation LanguageSELECT, INSERT, UPDATE, DELETERow-level data
DCLData Control LanguageGRANT, REVOKEPermissions and access control
TCLTransaction Control LanguageCOMMIT, ROLLBACK, SAVEPOINT, SET TRANSACTIONTransaction boundaries
-- DDL: defines structure
CREATE TABLE accounts (
    id SERIAL PRIMARY KEY,
    balance NUMERIC(12,2) NOT NULL DEFAULT 0
);

-- DML: manipulates rows
INSERT INTO accounts (balance) VALUES (100.00);
UPDATE accounts SET balance = balance - 50 WHERE id = 1;

-- DCL: controls access
GRANT SELECT, INSERT ON accounts TO app_user;

-- TCL: controls the transaction
BEGIN;
UPDATE accounts SET balance = balance - 50 WHERE id = 1;
UPDATE accounts SET balance = balance + 50 WHERE id = 2;
COMMIT;

Why the distinction matters

Most production databases auto-commit DDL (or even implicitly commit any open transaction before running it) — running ALTER TABLE mid-transaction in MySQL, for example, causes an implicit commit, so you can't roll a schema change back the way you can an UPDATE. PostgreSQL is a notable exception: it supports transactional DDL, so a CREATE TABLE inside a BEGIN...ROLLBACK block really does disappear.

DCL statements are also typically not transactional in the same sense — permission changes often take effect immediately and aren't undone by ROLLBACK in many engines. Knowing which bucket a statement falls into tells you whether you can safely wrap it in a transaction for an atomic migration, or whether you need a different rollback strategy (e.g., a paired "down" migration script).