0Pricing
SQL Academy · 课时

使用 USING 的 DELETE 与安全模式

使用 DELETE ... USING 删除与其他表连接的行,并先通过事务 + SELECT 进行验证,再执行破坏性操作。

使用 USING 的 DELETE 与安全模式 是 CoddyKit 上的免费 SQL Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 SQL Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 SQL Academy 课程共包含 4 节课。

基本 DELETE

删除匹配的行:

DELETE FROM users WHERE id = 1;

始终先使用 SELECT 进行测试

执行任何 DELETE 之前,使用 SELECT 配合相同的 WHERE,以确认行数:

SELECT COUNT(*) FROM orders
WHERE status = 'cancelled' AND created_at < NOW() - INTERVAL '1 year';

在事务中执行 DELETE

将具有破坏性的操作放入事务中,这样您就可以执行 ROLLBACK:

BEGIN;
DELETE FROM orders WHERE status = 'cancelled' AND ...;
SELECT COUNT(*) FROM orders;       -- sanity check
-- COMMIT;  or ROLLBACK;

没有 WHERE 的 DELETE 将造成灾难

DELETE FROM users; 会清空整个表。没有撤销按钮。请保持谨慎;多花一秒输入 WHERE,就是廉价的保险。

DELETE … USING(PostgreSQL JOIN 删除)

根据另一个表删除一个表中的行:

DELETE FROM orders o
USING users u
WHERE u.id = o.user_id
  AND u.is_banned = true;

使用子查询的 DELETE

标准替代写法:

DELETE FROM orders
WHERE user_id IN (SELECT id FROM users WHERE is_banned);

外键级联

如果 orders.user_id 设置了 ON DELETE CASCADE,删除用户时会自动删除其订单。这很方便,但也很危险——请谨慎使用。

ALTER TABLE orders
  ADD CONSTRAINT orders_user_fk
  FOREIGN KEY (user_id) REFERENCES users(id)
  ON DELETE CASCADE;

软删除

许多应用不会真正删除行,而是设置一个 deleted_at 时间戳:

UPDATE users SET deleted_at = NOW() WHERE id = $1;

-- Every query then has:
WHERE deleted_at IS NULL

清理旧数据

定期清理大型表时,请分批删除,以避免长时间运行的事务:

DELETE FROM events
WHERE id IN (
  SELECT id FROM events
  WHERE created_at < NOW() - INTERVAL '90 days'
  LIMIT 10000
);
-- run this in a loop until it returns 0 rows

TRUNCATE:速度至关重要时的选择

如果您确实要清空一个表,TRUNCATE 比 DELETE 更快,因为它不会扫描行。但它不会触发 ROW 触发器,并且在某些配置中无法回滚:

TRUNCATE TABLE staging_orders;
TRUNCATE TABLE staging_orders RESTART IDENTITY CASCADE;

从 DELETE 返回数据

返回已删除的行——这对归档很有用:

WITH deleted AS (
  DELETE FROM orders WHERE status = 'archived' RETURNING *
)
INSERT INTO orders_archive SELECT * FROM deleted;

回顾

DELETE 是最危险的语句。防御性做法:

  • 先执行 SELECT
  • 使用 BEGIN; ... ; ROLLBACK 进行试运行
  • 将大量删除操作分批执行
  • 对于用户可见的数据,优先使用软删除
  • 只在暂存表上使用 TRUNCATE

快速检查

您在没有 WHERE 的情况下运行了 DELETE FROM users;。应该怎么做?

常见问题解答

「使用 USING 的 DELETE 与安全模式」课时是免费的吗?

是的 — 「使用 USING 的 DELETE 与安全模式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 SQL Academy 课程的其余内容,请升级到 CoddyKit PRO。 SQL Academy 课程共包含 4 节课。

「使用 USING 的 DELETE 与安全模式」这节课中我会学到什么?

使用 DELETE ... USING 删除与其他表连接的行,并先通过事务 + SELECT 进行验证,再执行破坏性操作。 你通过在浏览器中直接运行的动手代码来练习 SQL Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 SQL Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 SQL Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「使用 USING 的 DELETE 与安全模式」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 SQL Academy 课中编写并运行代码吗?

能。每节 SQL Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 使用多行 INSERT
  2. UPSERT:ON CONFLICT DO UPDATE(PostgreSQL)
  3. 使用 FROM 的 UPDATE 与连接式更新
  4. 使用 USING 的 DELETE 与安全模式
← 返回 SQL Academy