Основы моделирования и базы данных

Базовые операции SQL. Часть 2

В лекции поэтапно разбираются базовые операции языка SQL для управления данными: INSERT, UPDATE, DELETE и SELECT. Материал излагается от простого к сложному: сначала демонстрируется синтаксис вставки, изменения и удаления отдельных строк с акцентом на важность фильтрации через WHERE, включая раскрытие внутреннего устройства UPDATE как комбинации DELETE и INSERT. Затем фокус смещается на оператор SELECT, где слушатель учится соединять несколько таблиц через условия в WHERE, чтобы заменять технические идентификаторы на читаемые текстовые названия, тем самым реализуя логику неявных JOIN-соединений для подготовки данных к анализу.

Основные мысли

В результате изучения лекции слушатель будет способен:
1. Воспроизвести базовый синтаксис команд INSERT, UPDATE и DELETE для управления строками данных.
2. Объяснить, почему операцию UPDATE можно представить как сочетание операций DELETE и INSERT.
3. Применять условие WHERE для фильтрации целевых строк при изменении или удалении данных, избегая массовых операций.
4. Демонстрировать написание простого запроса SELECT с явным перечислением полей для извлечения данных.
5. Аргументировать отказ от использования символа «*» (звездочка) в промышленных запросах, опираясь на принципы оптимизации.
6. Конструировать SELECT-запросы, связывающие две и более таблицы через условия в секции WHERE, используя внешние ключи.
7. Анализировать структуру связанных таблиц для подмены технических кодов (ID) на осмысленные текстовые значения из справочников.
Показывать лекцию целиком
Краткое изложение

Совет. Чтобы вывести таблицу SeatPlace для вставки таблицы с данными из Excel,  необходимо нажать правую кнопку мыши на таблице и далее изменить первые 200 строк.

Совет. Чтобы развернуть бэкапы, приложенные к лекции 9, нужно на папке базы данных правой кнопкой мыши, выбрать восстановить базу данных, и затем в новом окне выбрать раздел устройство и файл .bak. Демонстрация разворачивания бекапа имеется в лекции по моделированию.

Мы начинаем разбирать, как вносить изменения в уже существующие строки. Для этого используется команда UPDATE. Важно понимать, что на системном уровне UPDATE — это не атомарная операция обновления, а комбинация двух действий: DELETE и INSERT. Сначала текущая строка сохраняется во временную память, затем удаляется, и вместо нее вставляется новая строка, содержащая как старые значения полей, так и внесенные нами изменения.

Рассмотрим синтаксис. Мы указываем UPDATE, затем имя таблицы, например, Seat Category. Ключевое слово SET задает, какое поле меняется и на какое значение. Допустим, мы хотим изменить поле Description на «Обычное место». Если на этом остановиться, обновление затронет все строки таблицы. Чтобы точечно изменить лишь одну запись, мы добавляем WHERE — условие для фильтрации. Чаще всего оно строится по первичному ключу: WHERE ID = 1. После выполнения только одна строка получит новое описание.

Аналогично работает DELETE. Команда DELETE FROM Seat Category без условия удалит все записи. Чтобы убрать конкретную строку, мы снова используем условие с идентификатором: WHERE ID = 3. Исполняем запрос, и третья строка исчезает.

Внутри блока WHERE можно строить сложные логические конструкции, используя операторы AND и OR для комбинирования условий.

Зафиксируем базовый синтаксис:
INSERT: INSERT INTO ИмяТаблицы (Поле1, Поле2) VALUES (Значение1, Значение2). Если вставляются значения для всех столбцов, их перечисление в скобках перед VALUES можно опустить. Для вставки нескольких строк за один раз блоки значений перечисляются через запятую.
UPDATE: UPDATE ИмяТаблицы SET Столбец = НовоеЗначение WHERE Условие.
DELETE: DELETE FROM ИмяТаблицы WHERE Условие.

Мы заполнили несколько таблиц, в том числе Format и Seat Place. Для быстрой вставки множества строк удобно подготовить данные в Excel и скопировать их напрямую в таблицу в среде SQL Server Management Studio. Это быстрый способ для тестовых задач, хотя в промышленной разработке применяется специализированный парсинг файлов.

Когда таблица Seat Place заполнена, мы видим в ней только числовые коды. Эти коды неинформативны для человека. Чтобы отобразить данные в читаемом виде, необходимо заменить коды текстовыми описаниями из родительских таблиц. Для этого служит оператор SELECT.

Наш первый SELECT-запрос прост. Мы пишем SELECT, затем перечисляем поля из таблицы. Начинать рекомендую не по порядку, а сразу с SELECT ... FROM ИмяТаблицы, так как при появлении подсказок от редактора проще писать запрос. Хотя для получения всех полей можно написать SELECT * (звездочка), в реальных приложениях этого делать не стоит. При использовании звездочки сервер сначала выполняет дополнительный запрос к структуре таблицы, чтобы выяснить список столбцов, и только потом подставляет их в запрос. Главная же проблема в том, что SELECT * ломает оптимизацию хранимых процедур. Поэтому хорошей практикой является всегда явно перечислять нужные столбцы.

Чтобы заменить код категории (ID Category) на ее название (Category Name), мы должны соединить (join) две таблицы: Seat Place и Seat Category. Это делается с помощью условия в секции WHERE. Мы добавляем в запрос вторую таблицу Seat Category и прописываем правило связи:

sql
SELECT
Seat_Place.Row,
Seat_Place.Place,
Seat_Category.Category_Name
FROM
Seat_Place, Seat_Category
WHERE
Seat_Place.ID_Category = Seat_Category.ID

Это и есть неявное объединение (JOIN). Такой подход позволяет вместо кода ID Category увидеть текстовое название «VIP» или «Обычное место».

Далее мы можем склеивать (связывать) любое количество таблиц. Чтобы узнать не код зала, а его имя (Hall Name), мы добавляем в запрос таблицу Hall и прописываем еще одно условие связи: Seat_Place.ID_Hall = Hall.ID. Чтобы узнать, в каком кинотеатре находится зал, мы соединяем таблицы Hall и Cinema, проходя по цепочке внешних ключей (Hall.ID_Cinema = Cinema.ID). В итоге мы получаем один «плоский» набор данных, где все коды заменены на понятные человеку названия.

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

Синтаксис SELECT невероятно многообразен, но мы освоили его базовое и наиболее частое применение: извлечение данных из нескольких связанных таблиц с фильтрацией.

Краткие итоги
Освоение базовых операторов манипуляции данными (INSERT, UPDATE, DELETE) и запросов (SELECT) формирует фундаментальное понимание двух ключевых слоев работы с реляционными базами данных: транзакционного и аналитического. Принципиально важным является осознание дискретной природы изменения данных на примере UPDATE — комбинации удаления и вставки. Это знание помогает аналитику понимать, что любое изменение — это не «исправление» ячейки, а создание нового состояния записи, что напрямую связано с логикой аудита и историчности данных в корпоративных системах. Применение WHERE-фильтрации в UPDATE и DELETE как обязательного, а не опционального элемента защищает от катастрофической потери данных, что является первым правилом промышленной разработки. Переход к SELECT и отказ от SELECT * в пользу явного перечисления полей демонстрирует переход от учебных задач к практике оптимизации. За этим стоит не просто экономия ресурсов сервера, а обеспечение стабильности планов выполнения запросов и предотвращение скрытых ошибок при изменении схемы таблиц. Кульминацией становится техника соединения таблиц через условие WHERE — неявный JOIN. Это ключевой навык для бизнес-аналитика, позволяющий самостоятельно денормализовывать данные «на лету». Проходя по цепочке внешних ключей от места в зале до названия кинотеатра, мы на практике реализуем разделение ответственности: база данных хранит сущности в нормализованном виде для эффективных транзакций и защиты от аномалий, в то время как аналитический запрос «склеивает» справочники с фактами для получения человеко-читаемой витрины. Умение выстраивать такие цепочки связей означает способность извлекать произвольную бизнес-логику, превращая разрозненные идентификаторы в готовую основу для отчетности и управленческих решений.
Мы рассматриваем базовые операции языка SQL для управления данными в таблицах.

1. Изменение данных: команда UPDATE
Для изменения существующей строки используется UPDATE. На системном уровне это комбинация двух операций: строка удаляется (DELETE), и на ее место вставляется новая (INSERT) с измененными полями.

Синтаксис: UPDATE ИмяТаблицы SET Поле = 'Новое значение' WHERE Условие;
Критически важно: Всегда указывать WHERE. Если написать UPDATE Seat_Category SET Description = 'Обычное место' без условия, изменение затронет все строки таблицы.
Точечная правка: Для изменения одной записи в WHERE подставляют первичный ключ (WHERE ID = 1).
Массовая правка: В WHERE можно задавать условия, возвращающие несколько строк, используя операторы AND и OR.

2. Удаление данных: команда DELETE
Принцип аналогичен UPDATE. DELETE FROM Seat_Category удалит все записи. Для точечного удаления нужно указать WHERE с идентификатором: WHERE ID = 3.

3. Вставка данных: команда INSERT
Базовый синтаксис для вставки строки:
• Если заполняются все столбцы: INSERT INTO ИмяТаблицы VALUES (Значение1, Значение2);
• Если только часть столбцов: INSERT INTO ИмяТаблицы (Столбец1, Столбец2) VALUES (Значение1, Значение2);
• Для вставки нескольких строк за раз блоки VALUES перечисляются через запятую. Альтернативный быстрый способ тестового наполнения — скопировать подготовленные строки из Excel и вставить их в результат запроса в Management Studio. Это не промышленный подход, но удобен для прототипирования.

4. Извлечение и соединение данных: команда SELECT
После заполнения таблицы (например, местами Seat_Place) мы видим только коды (ID_Hall, ID_Category). Чтобы сделать данные читаемыми, нужно заменить коды текстовыми значениями из справочников. Для этого служит SELECT с неявным соединением (JOIN) таблиц.

Синтаксис и культура кода: Хотя SELECT * возвращает все поля, его нельзя использовать в промышленном коде. * заставляет сервер делать лишнюю работу по чтению схемы и, что важнее, блокирует оптимизацию хранимых процедур. Всегда нужно явно перечислять столбцы.
Механизм соединения: Мы пишем SELECT ... FROM Таблица1, Таблица2, а в секции WHERE прописываем условие связи, основанное на внешних ключах (FK).
Пример: Чтобы вместо ID_Category (цифра) увидеть Category_Name (текст «VIP»), мы делаем выборку из Seat_Place и Seat_Category, указав условие .WHERE Seat_Place.ID_Category = Seat_Category.ID
Соединение цепочек таблиц: Аналогично можно раскрыть любую связь. Чтобы узнать название кинотеатра для каждого места, мы последовательно соединяем четыре таблицы по цепочке внешних ключей: Seat_Place -> Hall (по ID_Hall = Hall.ID) -> Cinema (по Hall.ID_Cinema = Cinema.ID). В итоговой выборке вместо набора кодов мы получаем понятные названия залов и кинотеатров.

Практический смысл: База данных работает с кодами ради эффективности хранения и целостности (внешние ключи). SELECT-запросы с соединениями служат мостом между машинным представлением данных и потребностями человека в отчетах, где он видит только осмысленный текст.

Выводы

1. Оператор UPDATE изменяет данные путем неявного удаления старой и вставки новой строки.
2. Для точечных изменений и удаления записей необходимо всегда явно указывать условие WHERE.
3. Условие WHERE с первичным ключом позволяет гарантированно воздействовать только на одну целевую строку.
4. Для массового обновления записей используются составные логические условия с операторами AND и OR.
5. Прямое копирование данных из Excel в таблицу — быстрый способ для прототипирования, но не для промышленной эксплуатации.
6. Использование SELECT * не рекомендуется в продуктивной среде, так как блокирует оптимизацию хранимых процедур.
7. Для получения читаемых названий вместо кодов необходимо соединять таблицы через внешние ключи.
8. Условие связи таблиц задается в WHERE через равенство первичного ключа справочника и внешнего ключа в факт-таблице.
9. Последовательное соединение нескольких таблиц позволяет раскрыть всю цепочку зависимостей от места до кинотеатра.
10. Внешние ключи служат основой для объединения нормализованных таблиц в единую выгрузку для пользователя.
11. База данных работает с кодами для эффективности, а SELECT-запросы преобразуют их в текст для удобства человека.
12. Хорошим тоном при написании запросов является явное указание имени таблицы перед каждым полем для избежания неоднозначности.

Вопросы для самопроверки

1. Из комбинации каких двух операций состоит оператор UPDATE на системном уровне?
2. Что произойдет при выполнении команды DELETE FROM Seat_Place без блока WHERE?
3. Почему индустриальным стандартом является отказ от использования SELECT * в приложениях?
4. Какой блок в запросе SELECT отвечает за логику связывания двух таблиц при неявном соединении?
5. Опишите процесс замены числового идентификатора категории на ее текстовое название из другой таблицы в рамках одного запроса.
6. В чем заключается разница между хранением данных в базе и их отображением для конечного пользователя?
7. Как можно вставить несколько строк данных в таблицу, используя одну команду INSERT?
8. Для чего в запросе с несколькими таблицами рекомендуется явно указывать имя таблицы перед именем поля?
9. Каким образом внешние ключи обеспечивают возможность соединения таблиц в SELECT-запросах?
10. Какой способ быстрой загрузки тестовых данных из внешнего источника был продемонстрирован?
11. Можно ли в одном запросе UPDATE изменить значения в нескольких столбцах и как это сделать?
12. Что необходимо сделать, чтобы обновить записи только в тех строках, которые удовлетворяют двум разным условиям одновременно?
Вернуться к учебному плану