Урок 55 из 84 · Базы данных
Вставка и модификация данных
Содержание урока
Со структурой закончили, теперь добавим данные. За манипуляцию данными в SQL отвечает подмножество DML (Data Manipulation Language), включающее в себя INSERT, UPDATE и DELETE запросы.
Добавление (вставка) данных в таблицу
INSERT INTO courses (name, slug, lessons_count, body)
VALUES ('basics of programming', 'basics', 10, 'this is theory');
В левой части этого запроса указывается таблица и после пробела в круглых скобках, список полей, которые нужно вставить. А справа от ключевого слова VALUES, значения этих полей, указанные в том же порядке. INSERT не является идемпотентным запросом: его повторное выполнение всегда приводит к попытке вставить ещё одну запись, даже если значения остались те же.
Если мы хотим оставить какие-то поля пустыми, то достаточно пропустить их при вставке в обеих частях запроса.
INSERT INTO courses (name, slug) VALUES ('Bash', 'bash');
INSERT позволяет вставить сразу несколько записей в рамках одного запроса:
INSERT INTO courses (name, slug) VALUES
('Bash', 'bash'), ('Python', 'python'), ('Ruby', 'ruby');
Для этого достаточно перечислить все необходимые значения в круглых скобках через запятую после ключевого слова VALUES.
Ну и последний вариант выполнения этой команды без перечисления полей. Если они не указаны, то это равносильно их полному перечислению:
INSERT INTO courses VALUES ('linux', 'linux', 3, 'something about linux');
Обратите внимание на то, как записаны значения: числовое значение указано как есть, строковые взяты в одинарные кавычки (двойные использовать для этой цели нельзя).
На текущий момент в нашей таблице три записи. Для их извлечения предназначен SELECT запрос, который не является частью DML. Подробнее поговорим о нём позже, а сейчас воспользуемся его базовой формой, которая позволяет извлечь всю таблицу и посмотреть её содержимое:
itacademy=# SELECT * FROM courses;
name | slug | lessons_count | body
-----------------------+--------+---------------+-----------------------
basics of programming | basics | 10 | this is theory
Bash | bash | |
Bash | bash | |
Python | python | |
Ruby | ruby | |
linux | linux | 3 | something about linux
(6 rows)
Обновление (изменение) данных
Обновление записей в таблице выполняется UPDATE запросом:
UPDATE courses SET body = 'updated!' WHERE slug = 'bash';
Обычно UPDATE запрос состоит из двух частей. В первой (там, где SET) описывается какое значение установить в какое поле. Во второй (той, что идёт после WHERE) указывается ограничение на то, к каким строкам применить обновление.
Обратите внимание на то, что = в WHERE части это не присваивание, а проверка на совпадение, хотя в SET равно уже используется как обычное присваивание.
Поскольку в нашей таблице только одна запись удовлетворяет условию slug = 'bash', то и обновится одна запись. Если бы их было больше, то обновились бы все соответствующие записи. UPDATE может быть как идемпотентным запросом, так и нет: всё зависит от того, как он написан. Конкретно в нашем случае он идемпотентен, то есть его повторные выполнения всегда приведут к одному и тому же результату.
За одну операцию можно обновить несколько полей. Для этого достаточно перечислить каждое присваивание через запятую в части SET. Порядок, в котором изменяются поля, не важен:
UPDATE courses SET body = 'updated!', name = 'Bash' WHERE slug = 'bash';
Самое интересное происходит в части WHERE. Для начала стоит знать, что её можно не указывать:
UPDATE courses SET body = 'oops';
Этот запрос обновит ВСЕ записи. Это довольно распространённая и страшная ошибка. Если записей в таблице много и они важны, то такой запрос может повлечь за собой серьёзные последствия. Случаи, когда действительно нужно обновить сразу все записи таблицы, очень редки.
С другой стороны, не всегда достаточно простого сравнения по одному полю. Запросы с WHERE нередко требуют других операций, например, сравнения. SQL без проблем позволяет всё это делать, более того, он позволяет использовать логические выражения. Рассмотрим несколько примеров:
- Операции сравнения
UPDATE courses SET name = 'new name' WHERE lessons_count > 3;
UPDATE courses SET name = 'another new name' WHERE lessons_count < 2;
- Логические операции
-- И
UPDATE courses SET name = 'new name'
WHERE slug = 'bash' AND lessons_count > 3;
-- ИЛИ
UPDATE courses SET name = 'another new name'
WHERE lessons_count < 2 OR lessons_count > 8;
Для логических операций используются ключевые слова AND и OR. Их можно добавлять и комбинировать в любых количествах. Как и в случае с обычными языками программирования, в составных выражениях полезно использовать явное задание приоритета за счёт круглых скобок.
UPDATE courses SET name = 'another new name'
WHERE (lessons_count < 2 AND lessons_count > 8) OR slug = 'linux';
Удаление данных
Последний запрос из DML — DELETE:
DELETE FROM courses WHERE slug = 'bash';
Этот запрос практически идентичен тому, как работает UPDATE. Разница лишь в том, что здесь ничего не надо указывать после DELETE. Его так же опасно выполнять (ещё опаснее!) и он отработает даже, если не указана секция WHERE. Секция WHERE в разных видах запросов работает идентично, поэтому всё, что описывалось выше для UPDATE, справедливо и для DELETE.
В базах данных есть ещё один способ удалять данные в таблице — TRUNCATE. Он не является частью стандарта, но реализован большинством баз данных. У него две особенности:
- Он предназначен для полной очистки таблиц.
- В отличие от DELETE, он выполняется очень эффективно, так как у TRUNCATE нет возможности задавать условия, а значит СУБД не нужно ничего дополнительно анализировать. Она сразу очищает место на диске минуя все промежуточные этапы.
TRUNCATE courses;