ZYH 开发教程
学习中心/数据库
数据库

SQL 重点速查(以 PostgreSQL 为例)

PostgreSQL 建表、CRUD、连接、事务、参数化查询与索引速查。

工具资料 · 不计入主线进度

建表#

sql
CREATE TABLE users (
  id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  email VARCHAR(255) NOT NULL UNIQUE,
  password_hash TEXT NOT NULL,
  role VARCHAR(20) NOT NULL DEFAULT 'user'
    CHECK (role IN ('user', 'admin')),
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE tasks (
  id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  user_id BIGINT NOT NULL REFERENCES users(id),
  title VARCHAR(200) NOT NULL,
  completed BOOLEAN NOT NULL DEFAULT FALSE,
  due_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CRUD#

sql
INSERT INTO tasks (user_id, title) VALUES (1, '学习 JOIN')
RETURNING *;

SELECT id, title, completed
FROM tasks
WHERE user_id = 1 AND completed = FALSE
ORDER BY created_at DESC
LIMIT 20 OFFSET 0;

UPDATE tasks SET completed = TRUE WHERE id = 1 AND user_id = 1
RETURNING *;

DELETE FROM tasks WHERE id = 1 AND user_id = 1
RETURNING id;

连接与聚合#

sql
SELECT u.id, u.email, COUNT(t.id) AS task_count
FROM users AS u
LEFT JOIN tasks AS t ON t.user_id = u.id
GROUP BY u.id, u.email
HAVING COUNT(t.id) >= 3
ORDER BY task_count DESC;

事务#

sql
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
-- 任何一步失败时执行 ROLLBACK;应用代码也必须正确捕获错误。

参数化查询#

js
// 正确:数据和值分开传递
await pool.query(
  'SELECT id, email FROM users WHERE email = $1',
  [email]
);

// 错误:用户输入被拼入 SQL,存在注入风险
// await pool.query(`SELECT * FROM users WHERE email = '${email}'`);

索引判断#

sql
CREATE INDEX idx_tasks_user_created
ON tasks (user_id, created_at DESC);

EXPLAIN ANALYZE
SELECT * FROM tasks
WHERE user_id = 1
ORDER BY created_at DESC
LIMIT 20;

优先为外键、经常过滤/连接/排序的列考虑索引。低选择性单列(如只有真假两值)通常不适合单独建立普通索引。复合索引是否有效与查询条件、列顺序有关,应使用执行计划验证。

可搜索标题、说明和正文Esc 关闭
从一个简单词开始试试“HTML”“数据库”“登录”或“部署”
在线练习修改代码并查看结果
运行结果