DELETE vs DROP vs TRUNCATE

Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.

Зачем это различать

На собесе уровня junior часто спрашивают: «в чём разница DELETE и DROP?». Junior путает — «всё удаляет». Middle знает: DELETE удаляет строки, DROP удаляет таблицу, TRUNCATE — очищает таблицу быстро.

На работе ошибка в выборе опасна. DROP TABLE на prod без WHERE → катастрофа. DELETE без WHERE → очистили таблицу, но структура и права остались. TRUNCATE — нельзя отменить в некоторых БД.

В статье:

  • Короткий ответ
  • DELETE — удаление строк
  • DROP — удаление таблицы
  • TRUNCATE — очистка таблицы
  • Сравнение с примерами
  • Как безопасно работать

Короткий ответ

  • DELETE — удаляет строки (можно с WHERE). Таблица остаётся.
  • DROP — удаляет таблицу целиком (структура + данные).
  • TRUNCATE — удаляет все строки (без WHERE). Таблица остаётся.

Сравнение

DELETE TRUNCATE DROP
Что удаляет строки все строки таблицу + данные
WHERE да нет нет
Скорость медленная быстрая очень быстрая
Триггеры срабатывают нет (обычно) не применимо
Индексы сохраняются сохраняются удаляются
Rollback да (в транзакции) да в Postgres нет (в MySQL)
Auto-increment сохраняется сбрасывается ничего не осталось
FK constraint проверяется блокирует удаляет FK

DELETE

Классическое удаление строк:

-- удалить одну
DELETE FROM users WHERE id = 42;

-- удалить по условию
DELETE FROM users WHERE last_login < '2020-01-01';

-- удалить всё (опасно!)
DELETE FROM users;

Особенности

  • Медленно на больших таблицах (по одной строке)
  • Триггеры срабатывают (audit, cascade)
  • FK проверяются (или CASCADE)
  • Можно отменить через ROLLBACK
  • Auto-increment counter не сбрасывается

TRUNCATE

Быстрая очистка:

TRUNCATE TABLE users;

Особенности

  • Быстрая (под capot не удаляет по строкам, а сбрасывает pages)
  • Триггеры не срабатывают (обычно)
  • Auto-increment сбрасывается в 1
  • FK constraint может блокировать (CASCADE в Postgres)
  • В MySQL нельзя отменить — всё, данные ушли
  • В Postgres в транзакции — можно ROLLBACK

DROP

Удаление всего объекта:

DROP TABLE users;        -- удаляет таблицу целиком
DROP DATABASE mydb;      -- удаляет базу
DROP INDEX idx_name;     -- удаляет индекс
DROP VIEW my_view;       -- удаляет view

Особенности

  • Таблица перестаёт существовать
  • Все данные + индексы + constraints + права — всё удаляется
  • Невозможно отменить (кроме транзакции в Postgres)
  • Связанные views / FK ломаются

Практические примеры

Когда DELETE

-- удалить старые записи
DELETE FROM sessions WHERE created_at < NOW() - INTERVAL '30 days';

-- удалить тестовые аккаунты
DELETE FROM users WHERE email LIKE '%@test.com';

Когда TRUNCATE

-- очистить staging-таблицу перед reload
TRUNCATE TABLE staging_orders;

-- очистить log-таблицу после backup
TRUNCATE TABLE app_logs;

Когда DROP

-- удалить временную таблицу после использования
DROP TABLE temp_import;

-- очистить экспериментальные таблицы
DROP TABLE IF EXISTS test_20250101;

IF EXISTS — защита от ошибки, если таблицы нет.

Безопасная работа

Перед DROP

-- 1. Убедиться, что ничего не зависит
SELECT * FROM information_schema.views
WHERE view_definition LIKE '%users%';

-- 2. Backup
CREATE TABLE users_backup AS SELECT * FROM users;

-- 3. Теперь можно
DROP TABLE users;

Перед DELETE

-- 1. Сначала SELECT
SELECT COUNT(*) FROM orders WHERE ...; -- сколько удалит

-- 2. BEGIN / ROLLBACK
BEGIN;
DELETE FROM orders WHERE ...;
SELECT COUNT(*) FROM orders;
-- если ok:
COMMIT;
-- если не ok:
ROLLBACK;

Перед TRUNCATE

-- быстрая проверка
SELECT COUNT(*) FROM staging_orders;

-- backup
CREATE TABLE staging_orders_backup AS SELECT * FROM staging_orders;

-- сбросить
TRUNCATE TABLE staging_orders;

FK constraint — подвох

DELETE с CASCADE

CREATE TABLE orders (
    ...
    user_id INT REFERENCES users(id) ON DELETE CASCADE
);

-- при DELETE from users — удалятся заказы
DELETE FROM users WHERE id = 42;

TRUNCATE + FK

В MySQL TRUNCATE при наличии FK часто blocks. В Postgres нужно явно CASCADE:

TRUNCATE TABLE users CASCADE;  -- очистит и связанные

DROP + FK

Связанные FK удаляются вместе.

На собесе

«Разница DELETE, TRUNCATE, DROP?» DELETE — строки (с WHERE). TRUNCATE — все строки. DROP — таблица.

«Что быстрее?» TRUNCATE > DELETE. DROP еще быстрее, но невозвратимо.

«Как откатить?» DELETE и TRUNCATE — ROLLBACK в транзакции (Postgres). DROP только в транзакции Postgres, в MySQL — невозможно.

«Когда triggers?» DELETE → да. TRUNCATE → нет. DROP → не применимо.

Частые ошибки

1. DELETE без WHERE

Удалит всё. Всегда WHERE. Транзакция для rollback.

2. DROP неверной таблицы

Несуществующие таблицы иногда перепутаны с похожими именами. IF EXISTS и осторожность.

3. Не видеть caskaды

ON DELETE CASCADE удаляет дочерние таблицы. Может быть неожидаемо.

4. TRUNCATE в production без backup

Данные исчезнут. Бэкап обязателен.

Связанные темы

FAQ

Можно ли отменить DROP?

В Postgres в транзакции — да. В MySQL — нет (автоcommit).

TRUNCATE быстрее DELETE даже с WHERE?

TRUNCATE без WHERE всегда. DELETE с WHERE может быть быстрым с хорошим индексом.

DROP CASCADE?

DROP TABLE users CASCADE — удалит users и все зависимые объекты (views, FK).

Что безопаснее для staging tables?

TRUNCATE — быстро и сохраняет структуру. DROP + CREATE — если схема меняется.


Тренируйте SQL — откройте тренажёр с 1500+ вопросами для собесов.