Чтение безопасно, изменение — нет. 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' — и все заказы в базе «оплачены». Синтаксически это корректный запрос; база выполнит его не моргнув.
Отсюда ритуал, который стоит довести до автоматизма:
- Сначала SELECT с тем же WHERE:
SELECT * FROM orders WHERE id = 102;— посмотрите, что именно попадёт под изменение. Одна строка? Та самая? - Только теперь UPDATE/DELETE — с тем же самым условием.
- После — контрольный 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.
- Не та база. Запрос идеален, стенд — нет. Проверка «куда я подключён» занимает две секунды и однажды спасёт карьеру.
Что учить дальше. Остался последний сюжет цикла: почему одни запросы летают, а другие висят минутами — индексы и медленные запросы.