Чтение безопасно, изменение — нет. UPDATE без WHERE перепишет всю таблицу, и волшебной кнопки «отменить» в базе не существует. Поэтому эта статья — наполовину про синтаксис, наполовину про технику безопасности. Обе половины обязательны.

Три команды

INSERT — добавить строку:

INSERT INTO customers (name, email) VALUES ('Григорий', 'grig@example.com');

Перечисляете столбцы и значения к ним. id обычно не указывают — база выдаёт его сама.

UPDATE — изменить существующие строки:

UPDATE orders SET status = 'paid' WHERE id = 102;

SET говорит, что менять, WHEREу каких строк. Менять можно несколько полей сразу: SET status = 'cancelled', cancelled_at = now().

DELETE — удалить строки:

DELETE FROM orders WHERE id = 103;

Правило номер один: WHERE — не опция

У UPDATE и DELETE есть общее свойство, из-за которого сломано больше данных, чем из-за всего остального вместе: без WHERE они применяются ко всем строкам таблицы. UPDATE orders SET status = 'paid' — и все заказы в базе «оплачены». Синтаксически это корректный запрос; база выполнит его не моргнув.

Отсюда ритуал, который стоит довести до автоматизма:

  1. Сначала SELECT с тем же WHERE: SELECT * FROM orders WHERE id = 102; — посмотрите, что именно попадёт под изменение. Одна строка? Та самая?
  2. Только теперь UPDATE/DELETE — с тем же самым условием.
  3. После — контрольный SELECT: изменилось то, что хотели.

И смотрите на ответ базы: она всегда сообщает, сколько строк затронуто. Ожидали «1 row», увидели «5000» — что-то пошло не так.

Транзакции: страховка с кнопкой «отмена»

Транзакция — способ выполнить несколько команд как одно целое: либо всё, либо ничего.

BEGIN;
UPDATE orders SET status = 'cancelled' WHERE id = 102;
-- проверяем: SELECT * FROM orders WHERE id = 102;
COMMIT;    -- всё верно — зафиксировать
-- или
ROLLBACK;  -- передумали — откатить, как будто ничего не было

Между BEGIN и COMMIT изменения видны только вам — остальные пользователи базы видят старые данные. ROLLBACK отменяет всё, сделанное после BEGIN. Это и есть та самая «кнопка отмены», которой нет у одиночного запроса: заворачивайте любое ручное изменение в транзакцию, проверяйте результат SELECT'ом и только потом фиксируйте. Пока не сказали COMMIT — пути назад открыты.

Транзакции придуманы не для подстраховки ручных правок, а для целостности: перевод денег — это «минус на одном счёте» и «плюс на другом», и выполниться они обязаны только вместе. Но для вас на первом этапе транзакция — именно страховочный трос.

Тестовый стенд и боевая база

Простое правило: руками данные меняют на тестовом стенде. Там это нормальная часть работы — подготовить данные для проверки, воспроизвести редкое состояние, откатить сценарий назад. На боевой базе ручная правка — чрезвычайное событие, которое согласуют, оформляют и делают с оглядкой (и не новичок). Прежде чем выполнить изменяющий запрос, убедитесь, к какой базе вы подключены, — вкладки в клиенте выглядят одинаково, а базы за ними разные.

Где это применяется

Умение аккуратно менять данные превращает вас из наблюдателя в хозяина стенда: создать клиента с нужными свойствами за секунды вместо прохода регистрации, перевести заказ в редкое состояние, чтобы проверить недоступный из интерфейса сценарий, вернуть данные в исходное после разрушительного теста. Подготовка данных запросами — один из самых заметных ускорителей работы.

Где спотыкаются начинающие:

  • UPDATE/DELETE без WHERE — классика с последствиями на всю таблицу. Ритуал «сначала SELECT» существует ровно поэтому.
  • Забытая транзакция без COMMIT. Сделали изменения, ушли на обед — а изменения никто не видит, и таблица может стоять заблокированной для коллег. Начали транзакцию — доведите до COMMIT или ROLLBACK.
  • Не та база. Запрос идеален, стенд — нет. Проверка «куда я подключён» занимает две секунды и однажды спасёт карьеру.

Что учить дальше. Остался последний сюжет цикла: почему одни запросы летают, а другие висят минутами — индексы и медленные запросы.