Урок 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. Он не является частью стандарта, но реализован большинством баз данных. У него две особенности:

  1. Он предназначен для полной очистки таблиц.
  2. В отличие от DELETE, он выполняется очень эффективно, так как у TRUNCATE нет возможности задавать условия, а значит СУБД не нужно ничего дополнительно анализировать. Она сразу очищает место на диске минуя все промежуточные этапы.
TRUNCATE courses;

Дополнительные материалы

Отзыв