SQL
SQL 是面向关系数据的声明式语言,用来定义 schema、查询与修改数据、控制事务和权限;具体数据库实现共享核心关系语义,但存在大量方言和执行差异。
[!info] related notes
SQL
一句话定义
SQL 的核心不是“数据库命令集合”,而是:
用声明式方式描述希望数据库产生什么关系结果或状态变化,再由数据库 planner / executor 决定具体执行方式。
声明式是什么意思
命令式代码常写:
先遍历 users
→ 找符合条件的行
→ 再排序
→ 再取前 10 条
SQL 更像:
SELECT id, name
FROM users
WHERE status = 'active'
ORDER BY created_at DESC
LIMIT 10;
你表达的是:
- 要哪些列;
- 满足什么谓词;
- 结果如何排序;
而不是指定数据库必须使用哪种物理算法。
真正怎样执行由 optimizer 决定。
SQL 涵盖哪些职责
常见教学会把语句分成:
- DDL:CREATE / ALTER / DROP;
- DML:INSERT / UPDATE / DELETE;
- Query:SELECT;
- Transaction control:BEGIN / COMMIT / ROLLBACK;
- Access control:GRANT / REVOKE。
这些分类适合学习,但不要把 DDL/DML/DQL/TCL/DCL 当成所有 SQL 标准和数据库产品都严格采用的唯一官方分类体系。
关系语义
SQL 主要围绕:
- table / relation;
- row;
- column;
- predicate;
- join;
- grouping;
- ordering;
- set operation;
组织数据。
其中一个常见误区是把 SQL 当成“逐行处理脚本”。
更稳定的心智模型是:
先描述一组满足条件的数据,再让数据库选择执行计划。
Logical Query 与 Physical Plan
同一个 SQL:
SELECT *
FROM users
WHERE email = 'alice@example.com';
数据库可能选择:
- sequential/full table scan;
- index scan;
- index-only scan;
- 其他 access path。
SQL 本身描述逻辑意图,执行计划描述物理执行路径。
这也是为什么性能问题最终常要看 EXPLAIN。
NULL 与三值逻辑
SQL 中 NULL 通常表示未知/缺失语义,而不是普通值。
因此:
WHERE deleted_at = NULL
通常不是正确判断方式。
应使用:
WHERE deleted_at IS NULL
SQL predicate 中还会出现 TRUE / FALSE / UNKNOWN 三值逻辑,这会影响过滤、NOT、JOIN 等结果。
JOIN
JOIN 不是“把两张表拼起来”这么简单。
它表达的是两个 relation 按 predicate 组合:
- INNER JOIN;
- LEFT / RIGHT OUTER JOIN;
- FULL OUTER JOIN;
- CROSS JOIN。
具体物理执行可能是:
- nested loop;
- hash join;
- merge join;
由数据库优化器决定。
Transaction
SQL 还能控制 transaction boundary:
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
SQL 语句是否在同一 transaction 中执行,会直接影响一致性和并发行为。
SQL 标准 vs 方言
MySQL、PostgreSQL、SQLite、SQL Server 等共享大量 SQL 基础,但仍会在以下方面不同:
- data type;
- DDL;
- UPSERT;
- JSON;
- window/function;
- generated column;
- index;
- isolation / locking;
- procedural extension。
因此:
会 SQL ≠ 所有数据库语法完全可移植。
ORM 与 SQL
ORM 可以:
- 映射对象与表;
- 生成常见 CRUD;
- 管理 relation;
- 降低重复样板。
但 ORM 不会消除:
- join;
- index;
- transaction;
- query plan;
- N+1;
- locking;
- isolation;
这些数据库语义。
学习检查
- SQL 为什么叫声明式语言?
- 同一个 SELECT 为什么可以有多个物理执行计划?
- SQL 与某个具体数据库产品是什么关系?
- NULL 为什么不能简单当作普通空值比较?
- logical join 与 hash join / nested loop 有什么层次差异?
- ORM 为什么不能替代 SQL 知识?
- 给一个慢查询,说明 SQL 文本、索引、统计信息、执行计划分别属于哪一层。