What is SQL, and what do DDL, DML, DCL, and TCL stand for?
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
| Category | Full name | Example statements | What it affects |
|---|---|---|---|
| DDL | Data Definition Language | CREATE TABLE, ALTER TABLE, DROP TABLE, TRUNCATE | Schema/structure (tables, indexes, constraints) |
| DML | Data Manipulation Language | SELECT, INSERT, UPDATE, DELETE | Row-level data |
| DCL | Data Control Language | GRANT, REVOKE | Permissions and access control |
| TCL | Transaction Control Language | COMMIT, ROLLBACK, SAVEPOINT, SET TRANSACTION | Transaction 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).