SQL 按功能劃分為四類語言,理解其分類與特性是資料庫開發與管理的基礎。本文系統梳理命令、事務行為、JDBC 實戰範例。
| 類別 | 全稱 | 核心命令 | 事務行為 | 典型場景 |
|---|---|---|---|---|
| DDL | Data Definition Language | CREATE、ALTER、DROP、TRUNCATE、COMMENT、RENAME | 隱式提交(不可回滾) | 結構變更:建表、加欄位、建索引 |
| DML | Data Manipulation Language | INSERT、UPDATE、DELETE、CALL、EXPLAIN PLAN、LOCK TABLE | 需顯式 COMMIT/ROLLBACK | 資料增刪改、鎖表、執行計劃 |
| DCL | Data Control Language | GRANT、REVOKE | 隱式提交 | 權限管理、角色控制 |
| TCL | Transaction Control Language | COMMIT、SAVEPOINT、ROLLBACK、SET TRANSACTION | 事務控制本身 | 事務提交、回滾、保存點、隔離級別 |
💡 補充:SELECT 屬於 DQL (Data Query Language),常單獨歸類。
-- 建立資料庫
CREATE DATABASE test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 建表
CREATE TABLE city (
id INT PRIMARY KEY COMMENT '城市ID',
name VARCHAR(20) COMMENT '名稱',
state VARCHAR(20) COMMENT '狀態',
country VARCHAR(20)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 修改結構
ALTER TABLE city ADD birthday DATE COMMENT '生日';
ALTER TABLE city MODIFY name VARCHAR(50);
ALTER TABLE city DROP COLUMN state;
-- 刪除
DROP TABLE city;
DROP DATABASE test;
-- 清空表(高效、不可回滾、重置自增 ID)
TRUNCATE TABLE city;
⚠️ DDL 隱式提交:執行 DDL 前會自動 COMMIT 當前事務,DDL 本身不可回滾(除 8.0 Atomic DDL)。
-- 插入
INSERT INTO city (id, name, country) VALUES (1, 'Taipei', 'Taiwan');
INSERT INTO city (id, name, country) VALUES (2, 'Tokyo', 'Japan'), (3, 'Seoul', 'Korea');
-- 更新
UPDATE city SET country = 'China' WHERE id = 1;
-- 刪除
DELETE FROM city WHERE id = 2;
-- 鎖表
LOCK TABLES city WRITE;
UNLOCK TABLES;
-- 建立用戶並授權
CREATE USER 'app'@'%' IDENTIFIED BY 'Pass123!';
GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'app'@'%';
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION;
-- 回收權限
REVOKE DELETE ON app_db.* FROM 'app'@'%';
FLUSH PRIVILEGES;
-- 事務控制
START TRANSACTION;
SAVEPOINT sp1;
INSERT ...
UPDATE ...
ROLLBACK TO sp1; -- 回滾到保存點
COMMIT; -- 提交
ROLLBACK; -- 完全回滾
-- 設定隔離級別
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Connection conn = DriverManager.getConnection(URL, USER, PWD);
conn.setAutoCommit(false); // 關閉自動提交
conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
Statement stmt = conn.createStatement();
stmt.executeUpdate("INSERT INTO city VALUES (3, 'Taipei', 'Taiwan')");
stmt.executeUpdate("UPDATE city SET country='TAIWAN' WHERE id=4"); // 失敗:無 id=4
conn.commit(); // 不會執行到這裡
catch (Exception e) {
conn.rollback(); // 回滾 INSERT
}
Savepoint svpt = conn.setSavepoint(); // 設置保存點
stmt.executeUpdate("INSERT ..."); // 成功
stmt.executeUpdate("UPDATE ..."); // 失敗
conn.rollback(svpt); // 回滾到保存點,保留 INSERT
對應 TCL:SAVEPOINT、ROLLBACK TO SAVEPOINT。
| 誤區 | 正確認知 |
|---|---|
| TRUNCATE 可回滾 | TRUNCATE 是 DDL,隱式提交,不可回滾 |
| SELECT 不需事務 | 長查詢建議 READ ONLY 事務,確保一致性視圖 |
| 自動提交無影響 | 批次操作必須關閉自動提交,否則效能極差且無原子性 |
| DDL 可在事務中 | DDL 會強制提交前序事務,破壞原子性 |
DDL: CREATE/ALTER/DROP/TRUNCATE → 結構定義 → 隱式提交 DML: INSERT/UPDATE/DELETE → 資料操作 → 顯式提交 DCL: GRANT/REVOKE → 權限控制 → 隱式提交 TCL: COMMIT/ROLLBACK/SAVEPOINT → 事務控制 → 事務本身 DQL: SELECT → 資料查詢 → 可納入事務
掌握四大語言分類與事務邊界,是編寫正確、高效資料庫應用的前提。