Навигация по курсу
На телефоне широкие таблицы и схемы прокручивайте влево и вправо.
| Дата | День | Время | Тип | Тема | Открыть |
|---|---|---|---|---|---|
| 08.09 | Вт | 16:00–17:35 | Лекция | Л.1. Основные понятия баз данных и СУБД |
| Дата | День | Время | Тип | Тема | Открыть |
|---|---|---|---|---|---|
| 15.09 | Вт | 12:30–14:05 | Лаб. | ЛР №1. SSMS: системные и учебные БД | |
| 16.09 | Ср | 14:15–15:50 | Лекция | Л.2. Реляционная модель. Функциональные зависимости | |
| 16.09 | Ср | 16:00–17:35 | Лаб. | ЛР №2. Таблицы и первый SELECT |
| Дата | День | Время | Тип | Тема | Открыть |
|---|---|---|---|---|---|
| 22.09 | Вт | 14:15–15:50 | Лекция | Л.3. Нормализация. Аномалии обновления | |
| 22.09 | Вт | 16:00–17:35 | Лаб. | ЛР №3. DDL: CREATE, типы, ограничения | |
| 23.09 | Ср | 12:30–14:05 | Лаб. | ЛР №4. FK, ALTER TABLE, GO |
| Дата | День | Время | Тип | Тема | Открыть |
|---|---|---|---|---|---|
| 29.09 | Вт | 12:30–14:05 | Лекция | Л.4. Многопользовательские и распределённые БД | |
| 29.09 | Вт | 14:15–15:50 | Лаб. | ЛР №5. INSERT, SELECT, WHERE | |
| 30.09 | Ср | 12:30–14:05 | Лаб. | ЛР №6. UPDATE, DELETE, ORDER BY |
| Дата | День | Время | Тип | Тема | Открыть |
|---|---|---|---|---|---|
| 06.10 | Вт | 12:30–14:05 | Лекция | Л.5. Транзакции. Свойства ACID | |
| 06.10 | Вт | 14:15–15:50 | Лаб. | ЛР №7. Агрегатные функции | |
| 06.10 | Вт | 16:00–17:35 | Лаб. | ЛР №8. GROUP BY, HAVING, ROLLUP |
| Дата | День | Время | Тип | Тема | Открыть |
|---|---|---|---|---|---|
| 13.10 | Вт | 12:30–14:05 | Лекция | Л.6. Аномалии параллельного доступа | |
| 13.10 | Вт | 14:15–15:50 | Лаб. | ЛР №9. Вложенные подзапросы | |
| 14.10 | Ср | 12:30–14:05 | Лаб. | ЛР №10. Коррелированные подзапросы и EXISTS |
| Дата | День | Время | Тип | Тема | Открыть |
|---|---|---|---|---|---|
| 20.10 | Вт | 12:30–14:05 | Лекция | Л.7. Уровни изоляции транзакций | |
| 20.10 | Вт | 14:15–15:50 | Лаб. | ЛР №11. INNER и OUTER JOIN | |
| 21.10 | Ср | 12:30–14:05 | Лаб. | ЛР №12. UNION, EXCEPT, INTERSECT |
| Дата | День | Время | Тип | Тема | Открыть |
|---|---|---|---|---|---|
| 27.10 | Вт | 12:30–14:05 | Лекция | Л.8. Блокировки, тупики, репликация | |
| 27.10 | Вт | 14:15–15:50 | Лаб. | ЛР №13. Функции строк, чисел, дат | |
| 28.10 | Ср | 12:30–14:05 | Лаб. | ЛР №14. CASE, ISNULL, COALESCE |
| Дата | День | Время | Тип | Тема | Открыть |
|---|---|---|---|---|---|
| 03.11 | Вт | 12:30–14:05 | Лекция | Л.9. Структурированные и неструктурированные данные | |
| 03.11 | Вт | 14:15–15:50 | Лаб. | ЛР №15. Переменные и IF | |
| 04.11 | Ср | 12:30–14:05 | Лаб. | ЛР №16. Циклы WHILE и TRY/CATCH |
| Дата | День | Время | Тип | Тема | Открыть |
|---|---|---|---|---|---|
| 10.11 | Вт | 12:30–14:05 | Лекция | Л.10. Язык XML | |
| 10.11 | Вт | 14:15–15:50 | Лаб. | ЛР №17. XML в SQL Server | |
| 11.11 | Ср | 12:30–14:05 | Лаб. | ЛР №18. Иерархические данные |
| Дата | День | Время | Тип | Тема | Открыть |
|---|---|---|---|---|---|
| 17.11 | Вт | 12:30–14:05 | Лекция | Л.11. Администрирование и мониторинг СУБД | |
| 17.11 | Вт | 14:15–15:50 | Лаб. | ЛР №19. MongoDB — документная БД | |
| 18.11 | Ср | 12:30–14:05 | Лаб. | ЛР №20. Представления VIEW |
| Дата | День | Время | Тип | Тема | Открыть |
|---|---|---|---|---|---|
| 24.11 | Вт | 12:30–14:05 | Лекция | Л.12. Программирование в БД: процедуры, триггеры | |
| 24.11 | Вт | 14:15–15:50 | Лаб. | ЛР №21. Хранимые процедуры | |
| 01.12 | Вт | 12:30–14:05 | Лаб. | ЛР №22. Триггеры DML и INSTEAD OF |
| Дата | День | Время | Тип | Тема | Открыть |
|---|---|---|---|---|---|
| 01.12 | Вт | 14:15–15:50 | Лекция | Л.13. Резервное копирование | |
| 02.12 | Ср | 12:30–14:05 | Лаб. | ЛР №23. GRANT, REVOKE, роли |
| Дата | День | Время | Тип | Тема | Открыть |
|---|---|---|---|---|---|
| 08.12 | Вт | 12:30–14:05 | Лекция | Л.14. Восстановление данных и защита | |
| 08.12 | Вт | 14:15–15:50 | Лаб. | ЛР №24. Восстановление данных и итоговый практикум |
| Дата | День | Время | Тип | Тема | Открыть |
|---|---|---|---|---|---|
| 15.12 | Вт | 12:30–14:05 | Лекция | Л.15. Распределённые БД и двухфазная фиксация |
| Дата | День | Время | Тип | Тема | Открыть |
|---|---|---|---|---|---|
| 15.12 | Вт | 14:15–15:50 | Лекция | Л.16. Хранилища данных и подготовка к экзамену |
Дата: 08.09.2026, вт, 16:00–17:35, ауд. 210
О чём эта лекция. Перед SQL и таблицами — базовые слова: данные, база данных, СУБД, клиент. Без этого на лабораторных легко превратиться в «копировальщика кода».
Главная мысль одной фразой: база — это упорядоченные связанные данные; СУБД — программа, которая ими управляет; SSMS — окно, через которое вы отправляете запросы на сервер.
После прочтения вы сможете:
UniversityDB.| Тема |
|---|
| Организация курса |
| Данные, база данных, СУБД — на примерах |
| От данных к информации (пирамида DIKW) |
| Почему не хватает Excel и Word |
| Три «этажа» одной базы (ANSI/SPARC) — коротко |
| Демо SQL Server Management Studio (SSMS) и подготовка к ЛР №1 |
Данные — это то, что уже записано: число, слово, дата. Сами по себе они часто мало о чём говорят.
| Ситуация | Что видим | Это данные? |
|---|---|---|
| На термометре | 38.5 | Да — просто число |
| В списке группы | Иванов | Да — просто фамилия |
| В календаре | 08.09.2026 | Да — просто дата |
| В SMS банка | -500 | Да — пока неясно, списание это или пополнение |
Чтобы число стало понятным, нужен контекст: кто, что, когда, в каких единицах. Об этом — в разделе про пирамиду.
База данных (БД) — это большой упорядоченный набор связанных данных по одной теме. Не одна таблица на листочке, а система хранения.
Пример из вуза: в одной базе UniversityDB лежат студенты, вузы, предметы, оценки — и они связаны: у каждого студента есть вуз, у каждой оценки — студент и предмет.
Пример из жизни: каталог интернет-магазина — товары, цены, заказы, покупатели. Это тоже база, только тема другая.
Аналогия: база данных — как картотека в библиотеке: не одна книга, а весь фонд с правилами, где что лежит.
СУБД — программа, которая хранит базу, принимает запросы, следит, чтобы данные не потерялись и не испортились.
Примеры СУБД в курсе:
.db.Аналогия: если база — картотека, то СУБД — библиотекарь и правила работы с картотекой: выдаёт книги, не даёт двум людям одновременно испортить одну карточку, следит за порядком.
| Название | Что это на самом деле | Пример |
|---|---|---|
| База данных | Данные + структура (таблицы, связи) | UniversityDB |
| СУБД | Программа, которая базой управляет | SQL Server, SQLite |
| Клиент | Окно, через которое мы пишем SQL | SQL Server Management Studio (SSMS), DB Browser for SQLite |
| Файл Excel | Файл с таблицей, но это не полноценная СУБД | группа31.xlsx |
Рисунок 1. Вы работаете в клиенте. Клиент обращается к СУБД. СУБД хранит базу.
Спросите группу:
Мы уже выучили три слова: данные, база, СУБД. Теперь логичный вопрос: зачем всё это нужно, если можно записать оценки в тетрадь? Организации хотят не просто цифры, а понимание и решения — для этого данные проходят несколько шагов. Их часто рисуют пирамидой DIKW.
Рисунок 2. Снизу вверх: от «голых» цифр к решению. СУБД помогает на нижних двух уровнях.
Разберём три разные ситуации — так проще запомнить, чем одной длинной таблицей.
| Пример | Уровень | Как это звучит |
|---|---|---|
| 1. Оценка в вузе | Данные | 5 |
| Информация | Иванов получил 5 по информатике 15.01.2026 | |
| Знания | Средний балл Иванова 4.5 — стипендию, скорее всего, сохранит | |
| Мудрость | Деканат решает: предложить пересдачу или оставить как есть | |
| 2. Погода | Данные | −5 |
| Информация | Сегодня в Воронеже −5 °C | |
| Знания | Такая температура опасна для длительной прогулки без перчаток | |
| Мудрость | Лучше перенести outdoor-мероприятие в помещение | |
| 3. Банк | Данные | 1500 |
| Информация | На счёте осталось 1500 ₽ после оплаты общежития | |
| Знания | До зарплаты 10 дней — денег может не хватить | |
| Мудрость | Отложить крупную покупку или взять часть из резерва |
Где здесь СУБД?
Если данные — это фундамент, то Excel часто даёт «кривой фундамент»: удобно на первый день, больно через месяц. Представьте: староста ведёт список группы, кафедра — оценки, методист — нагрузку. В каждом файле есть Иванов и телефон деканата.
База данных решает это так:
Рисунок 3. Вместо разрозненных файлов — одна база с правилами.
Это не пирамида DIKW из раздела 3. Здесь другая мысль: одни и те же данные в СУБД можно описать на трёх этажах — от «что видит человек» до «как всё записано на диске». Это трёхуровневая архитектура ANSI/SPARC — три взгляда на одну базу.
Рисунок 4. Один запрос студента «проходит» через схему таблиц; СУБД сама обращается к файлам на диске.
| Этаж | Что это | Пример |
|---|---|---|
| 1. Внешний | Каждому пользователю показывают свою часть данных | Студент видит только свои оценки; деканат — всю группу |
| 2. Концептуальный | Общая схема базы: таблицы, столбцы, связи — здесь пишете SQL | STUDENT, UNIVERSITY, EXAM_MARKS |
| 3. Внутренний | Физическое хранение на диске сервера — настраивает администратор | Файлы базы, индексы, журнал транзакций |
VIEW и права GRANT на ЛР №17 и №23).Зачем это знать? Чтобы не путать «таблицу в Object Explorer» и «файл на диске». Таблица STUDENT для вас — логическая. Если администратор добавит индекс для ускорения, столбцы таблицы не меняются — меняется только устройство на 3-м этаже.
Кратко — «карта» на весь семестр, без деталей.
Кто работает с базой:
(local), .\SQLEXPRESS или имя учебного сервера).master, model, msdb, tempdb — их не трогаем, только смотрим.UniversityDB, OK.CREATE DATABASE UniversityDB;UniversityDB, выполнить:Проверьте для себя: вы в клиенте SSMS; запрос выполняется на сервере SQL Server; база UniversityDB создана или открыта для работы.
Шаг 1. Подключение: Connect to Server, тип Database Engine.
Шаг 2. После подключения — Object Explorer с базами сервера.
Шаг 3. Узел System Databases (master, model, msdb, tempdb).
Шаг 4. Создание UniversityDB (или команда CREATE DATABASE).
Рисунок 5. Основные окна SSMS на ЛР №1. Иллюстрации: скриншоты с сайта metanit.com.
STUDENT_ID.UNIVERSITY_ID у студента.Итог лекции:
Дата: 15.09.2026, вт, 17:45–19:20, ауд. 102
О чём эта лекция. На ЛР №1 вы создали базу UniversityDB. Сейчас важно понять не «как нажать кнопки в SSMS», а почему данные хранят в нескольких таблицах и откуда берутся столбцы STUDENT_ID, UNIVERSITY_ID, ограничения PRIMARY KEY и FOREIGN KEY.
Главная мысль одной фразой: в реляционной модели мы формулируем правила между столбцами: «зная значение одного столбца (или пары столбцов), однозначно определяется значение другого». Пример: по STUDENT_ID однозначно известна SURNAME — по номеру студента всегда одна и та же фамилия. Такое правило называется функциональной зависимостью. Из неё следуют ключи и нормализация (лекция 3).
После прочтения вы сможете:
STUDENT и UNIVERSITY;STUDENT_ID определяет SURNAME» и привести свой пример;| Тема |
|---|
| Зачем не одна большая таблица |
| Таблица = отношение: строка, столбец, правила |
| Первичный и внешний ключ |
| Функциональная зависимость |
| Замыкание X⁺ — проверка ключа |
| Связь с ЛР №2 и лекцией 3 |
Успеваемость группы часто ведут в Excel: файл Университет.xlsx, лист Группа. В столбце A — фамилии (со 2-й строки), в первой строке начиная с B — названия предметов, в ячейках — оценки. У каждого студента одна строка, фамилия не повторяется — для журнала это удобно и логично.
База данных решает другие задачи: связать студентов с вузами, преподавателями, множеством предметов и оценок; отвечать на запросы без переделки листа; не дублировать справочную информацию. Поэтому сравнение «Excel vs SQL» — не «фамилия три раза на листе», а ограничения такой схемы при росте данных.
| Ситуация | Что не так (или чем неудобно) |
|---|---|
| Новый предмет в семестре | Нужен новый столбец; меняются формулы, сводные таблицы, шаблон отчёта |
| К журналу добавили «Название вуза» и «Город вуза» | Оба поля копируются в каждой строке студента — переименовали вуз, правите весь лист |
| Другой формат: каждая оценка — отдельная строка (студент + предмет + балл) | Фамилия и курс повторяются в каждой строке с оценкой |
| Несколько групп, курсов, преподавателей | Много листов или файлов; сводный отчёт по кафедре собирается вручную |
| Запрос «все пятёрки по «Базам данных» по всем группам» | Поиск по разным столбцам и листам; в SQL — один SELECT по таблице оценок |
Решение в UniversityDB: разделить данные по смыслу и связать таблицы числовыми ключами:
UNIVERSITY — справочник вузов (название и город хранятся один раз);STUDENT — кто учится (ссылка UNIVERSITY_ID на вуз, без повторения названия);EXAM_MARKS — оценки (отдельная строка на каждую пару «студент + предмет»).Рисунок 1. Слева — привычный журнал (фамилия в строке, предметы в столбцах). Справа — как те же смыслы разложены в UniversityDB.
В учебниках таблицу называют отношением, строку — кортежем, столбец — атрибутом. В SSMS вы по-прежнему видите обычную таблицу — термины нужны для экзамена и курсовой, когда описываете модель.
ORDER BY — отдельная команда). Столбцы тоже можно переставить в SELECT, смысл данных не меняется.| STUDENT_ID | SURNAME | KURS | UNIVERSITY_ID |
|---|---|---|---|
| 1 | Иванов | 2 | 10 |
| 2 | Петров | 3 | 10 |
| 19 | Сидоров | 1 | 12 |
Здесь одна строка — один студент. Номер STUDENT_ID не повторяется. По UNIVERSITY_ID видно, что Иванов и Петров из одного вуза (10), но это не ключ студента: у одного вуза много студентов.
Ключ — это столбец или набор столбцов, по которым строку можно однозначно найти или связать с другой таблицей.
У каждой строки свой уникальный идентификатор. В STUDENT это STUDENT_ID.
STUDENT_ID.Столбец в одной таблице ссылается на первичный ключ другой. STUDENT.UNIVERSITY_ID ссылается на UNIVERSITY.UNIVERSITY_ID.
Смысл: «студент ссылается на существующий вуз». Если в справочнике нет вуза с номером 999, вставить студента с UNIVERSITY_ID = 999 нельзя — СУБД вернёт ошибку. Так сохраняется целостность данных.
Рисунок 2. PK — «имя строки внутри таблицы». FK — «ссылка на строку другой таблицы».
Правило: STUDENT_ID определяет SURNAME. Оно читается так: если в двух строках таблицы совпадает номер студента, совпадает и фамилия. Ещё проще: по номеру студента фамилия определяется однозначно — не «может быть Иванов, а может Петров».
Если правило задают два столбца сразу: «STUDENT_ID и SUBJECT_ID вместе определяют MARK» — у одного студента по одному предмету одна оценка.
Когда зависимости нет: по UNIVERSITY_ID нельзя однозначно узнать фамилию студента — в одном вузе учатся и Иванов, и Петров. Правила «UNIVERSITY_ID определяет SURNAME» для таблицы STUDENT нет.
Рисунок 3. Номер студента определяет фамилию (в рамках нашей базы).
| Запись | Смысл | Где живёт |
|---|---|---|
STUDENT_ID определяет SURNAME, KURS, UNIVERSITY_ID | По номеру студента известны фамилия, курс и вуз | Таблица STUDENT |
UNIVERSITY_ID определяет UNIVERSITY_NAME, CITY | По номеру вуза известны название и город | Таблица UNIVERSITY |
STUDENT_ID и SUBJ_ID вместе определяют MARK | Одна оценка студента по предмету (составной ключ) | Таблица EXAM_MARKS |
Если добавить в STUDENT столбец UNIVERSITY_NAME «для удобства», возникает зависимость UNIVERSITY_ID определяет UNIVERSITY_NAME, но название вуза будет копироваться у каждого студента.
| STUDENT_ID | SURNAME | UNIVERSITY_ID | UNIVERSITY_NAME | |
|---|---|---|---|---|
| Плохо | 1 | Иванов | 10 | МГУ |
| Плохо | 2 | Петров | 10 | МГУ |
Переименовали вуз — нужно обновить все строки студентов. Правильно: имя вуза только в UNIVERSITY, у студента — только UNIVERSITY_ID.
Важно: функциональная зависимость — это правило предметной области («один человек — одна фамилия»), а не команда SQL. Сначала формулируем правила, потом создаём таблицы на ЛР.
Иногда ключ составной (из нескольких столбцов). Чтобы проверить, может ли один столбец (или набор столбцов) быть ключом всей таблицы, строят замыкание — список всех столбцов, которые из него однозначно следуют по вашим правилам зависимостей.
На экзамене задачу часто дают в «абстрактном» виде — столбцы A, B, C, D и зависимости A определяет B. Это то же самое, что STUDENT_ID определяет SURNAME, только без имён из базы. Ниже — такой учебный пример; в работе с UniversityDB мысленно подставляйте свои столбцы.
STUDENT_ID или, в абстрактной задаче, только {A}).Таблица с столбцами A, B, C, D (без привязки к предметной области — типичная учебная задача на замыкание). Зависимости:
Шаг 1. Старт: {A}.
Шаг 2. Из правила «A определяет B»: добавляем B — получаем {A, B}.
Шаг 3. Из правила «B определяет C»: добавляем C — получаем {A, B, C}.
Шаг 4. Из правила «A определяет D»: добавляем D — получаем {A, B, C, D} — все столбцы таблицы.
Вывод: A — ключ (суперключ) этой таблицы.
Рисунок 4. Каждый шаг — применение одного правила «столбец определяет столбец».
Формальные правила вывода (аксиомы Армстронга) в программе экзамена упоминаются; для практики достаточно уметь пройти один пример, как выше, и понимать смысл «X определяет Y».
На ЛР №2 вы создаёте таблицы UNIVERSITY, STUDENT, SUBJECT и другие: команды SQL берутся из приложения, раздел «Сборка базы по шагам». Затем выполняете первые SELECT.
Вопросы для самопроверки:
STUDENT_ID, если есть фамилия?UNIVERSITY_ID, если можно хранить название вуза текстом в строке студента?UNIVERSITY_ID, которого нет в UNIVERSITY?STUDENT_ID определяет SURNAME?Краткие ответы:
Итог. Реляционная модель — это язык правил между столбцами. Ключи находят строки и связывают таблицы. Функциональные зависимости описывают, кто из кого следует. Без этого SQL превращается в набор скриптов «по образцу», а на курсовой и экзамене нужно объяснять почему схема устроена так.
Дата: 22.09.2026, вт, 19:30–21:05, ауд. 307
О чём эта лекция. На ЛР №2 вы собрали UniversityDB из нескольких таблиц. Здесь — зачем так делают: что ломается в одной «широкой» таблице и как формальные нормальные формы помогают проектировать схему без лишних дублей.
Главная мысль одной фразой: каждый факт хранится в одном месте; если одно и то же имя вуза или старосты повторяется в десятках строк, обновление превращается в риск ошибки.
После прочтения вы сможете:
UniversityDB.| Тема |
|---|
| Три аномалии: обновления, вставки, удаления |
| От сущностей к таблицам |
| 1НФ, 2НФ, 3НФ и НФБК — кратко |
| Декомпозиция: плохая и хорошая схема |
| Разбор на примере и мини-задача |
Представьте одну таблицу ОЦЕНКИ со столбцами: студент, группа, староста группы, предмет, преподаватель, оценка. На первый взгляд всё на виду — как в Excel. Но при изменении данных возникают проблемы:
| Аномалия | Что происходит | Пример |
|---|---|---|
| Обновления | Один факт записан во многих строках — править приходится везде | Сменили старосту — нужно обновить все строки группы |
| Вставки | Нельзя добавить справочные данные без «лишней» строки | Новый предмет не завести, пока никто его не сдал |
| Удаления | Удаляя последнюю строку, теряем сопутствующий факт | Ушёл последний студент группы — пропало имя старосты |
Из жизни: если адрес магазина продублирован в каждой строке заказа, переезд магазина — это массовое редактирование и риск, что в одной строке адрес останется старым.
Рисунок 1. Слева — дублирование «старосты» в каждой строке. Справа — те же смыслы в отдельных таблицах.
При проектировании сначала выделяют сущности (Студент, Вуз, Предмет) и связи между ними. Связь «многие ко многим» (студент сдаёт много предметов, предмет сдают многие студенты) обычно даёт отдельную таблицу — у вас это EXAM_MARKS.
UniversityDB после ЛР №2 — уже нормализованный пример: вузы в UNIVERSITY, студенты в STUDENT, оценки отдельно, название вуза не копируется в каждую строку студента.
Нормальные формы — чек-лист при проектировании. Не нужно заучивать определения наизусть; важно понимать идею каждого шага.
В каждой ячейке одно значение, нет «списков через запятую» и повторяющихся столбцов «предмет1, предмет2, предмет3». Таблицы в SQL Server после CREATE TABLE обычно уже в 1НФ.
1НФ + каждый неключевой столбец зависит от всего первичного ключа, а не от его части. Важно, когда ключ составной — например, пара (студент, предмет) в таблице оценок: оценка зависит от обоих столбцов сразу, а не только от студента.
2НФ + нет транзитивных зависимостей: неключевой столбец не должен зависеть от другого неключевого. Пример нарушения: в таблице студента хранить и UNIVERSITY_ID, и UNIVERSITY_NAME — имя вуза уже определяется номером вуза (это разбирали на лекции 2).
НФБК строже 3НФ: в каждой нетривиальной записи «X определяет Y» набор X должен быть суперключом. Для учебной схемы достаточно понимать идею; UniversityDB спроектирована близко к 3НФ/НФБК.
Декомпозиция — разбиение одной таблицы на несколько так, чтобы по ключам можно было собрать те же данные через JOIN.
| Плохо | Хорошо |
|---|---|
STUDENT_BAD(STUDENT_ID, SURNAME, UNIVERSITY_ID, UNIVERSITY_NAME) | STUDENT(STUDENT_ID, SURNAME, UNIVERSITY_ID) и UNIVERSITY(UNIVERSITY_ID, UNIVERSITY_NAME) |
Здесь UNIVERSITY_ID определяет UNIVERSITY_NAME — имя вуза хранится один раз. Цена нормализации — в запросах чаще нужен JOIN; выигрыш — при переименовании вуза правится одна строка в UNIVERSITY.
Интернет-магазин в одной таблице: (order_id, customer_name, customer_city, product_name, price, qty).
Ожидаемый ответ: CUSTOMER, PRODUCT, ORDERS (шапка заказа), ORDER_ITEM (строки заказа: товар, количество, цена на момент покупки).
EXAM_MARKS в UniversityDB — отдельная таблица, а не столбцы «математика», «физика» в STUDENT?Итог. Нормализация убирает лишние повторы и аномалии при INSERT, UPDATE и DELETE. UniversityDB — пример разумного разбиения; на ЛР №3 вы спроектируете отдельную схему «Библиотека» с ограничениями PK, FK, UNIQUE и CHECK.
Дата: 23.09.2026, ср, 16:00–17:35, ауд. 307
О чём эта лекция. До сих пор вы работали с базой в одиночку. В реальности к одному SQL Server подключаются десятки пользователей, а данные крупных организаций могут лежать на нескольких серверах. Разберём, чем отличается многопользовательский режим от «одного файла на диске» и что такое распределённая база данных.
Главная мысль одной фразой: многопользовательская СУБД — это общий сервер с отдельными сеансами; распределённая БД — логически одна база на нескольких узлах, где приложение не должно знать физическое размещение каждой строки.
После прочтения вы сможете:
| Тема |
|---|
| Многопользовательский режим, клиент–сервер, файлы базы |
| Распределённая БД, фрагментация, сравнение с «двумя Excel» |
| Конфликты одновременного доступа — введение |
| Мини-задачи, частые ошибки в понимании |
| Самопроверка, связь с ЛР №4 и лекцией 5 |
На ЛР №1–2 вы, скорее всего, работали с UniversityDB в одиночку. В учебном классе к одному экземпляру SQL Server одновременно подключены десятки окон SSMS — у каждого студента свой сеанс (session): свой текст запроса, свой результат, свои права.
Тот же принцип в вузе: деканат, бухгалтерия, электронная библиотека могут обращаться к одной серверной базе через разные программы — не через ваш SSMS, а через учётные системы. SQL Server изначально рассчитан на такой режим.
| Ситуация | Многопользовательский сервер (SQL Server) | Файл SQLite |
|---|---|---|
| Кто хранит данные | Служба SQL Server на диске сервера | Один файл .db на диске |
| Кто подключается | Много клиентов по сети | Обычно одно приложение рядом с файлом |
| Запись одновременно | СУБД координирует блокировки и транзакции | Часто один писатель, остальные ждут |
| Наш курс | Основной стенд в классе | Упоминаем как «база в одном файле» для сравнения |
Аналогия: банк — не один кассир с тетрадкой, а общая система учёта, к которой обращаются многие операторы; SQLite ближе к личной записной книжке на одном столе.
Вы пишете запрос в SQL Server Management Studio — это клиент. Сервер SQL Server принимает текст T-SQL, выполняет его и возвращает таблицу результата или сообщение об ошибке. Каждое окно подключения — отдельный сеанс с номером session_id.
Важно: данные UniversityDB физически лежат на диске сервера в паре файлов:
.mdf — основной файл данных (таблицы, индексы);.ldf — журнал транзакций (запись изменений до фиксации).Окно SSMS — не «контейнер базы», а окно отправки команд. Закрыли SSMS — база на сервере осталась.
Рисунок 1. Два окна SSMS — два сеанса; данные — в файлах на диске сервера.
Object Explorer: база видна в списке, но физически хранится в файлах сервера (см. свойства базы).
Свойства базы: путь к .mdf и .ldf. SSMS — не «файл Excel с базой внутри».
Откройте SSMS (если есть доступ к серверу) и выполните:
Запишите свой my_session_id. Откройте второе окно запроса к той же базе — номер сеанса будет другим. Оба сеанса видят одни и те же 19 студентов в STUDENT.
Распределённая БД — логически одна база для приложения, физически данные на нескольких узлах (серверах, городах, дата-центрах). Идеал — прозрачность размещения: разработчик пишет обычный SELECT * FROM STUDENT, а система сама обращается к нужному узлу.
| Ситуация | Это распределённая БД? | Почему |
|---|---|---|
| Деканат — Excel, кафедра — Access, без связи | Нет | Нет общих FK, нет единой транзакции, дубли и расхождения |
Две копии UniversityDB на разных флешках | Нет | Это две независимые базы, не один каталог |
| Студенты Воронежа на сервере A, Москвы — на B, запрос «как к одной STUDENT» | Да (идея) | Единая схема, согласованность, общий SQL |
Горизонтальная — строки таблицы делят по правилу. Пример для UniversityDB: студенты с CITY = N'Воронеж' на узле 1, остальные — на узле 2. Для пользователя запрос SELECT COUNT(*) FROM STUDENT может прозрачно собрать сумму с обоих узлов.
Вертикальная — редкие или «тяжёлые» столбцы выносят на отдельный узел. Пример: в STUDENT оставить STUDENT_ID, SURNAME, KURS на основном сервере, а BIRTHDAY — на узле архива. На курсе вертикальную фрагментацию достаточно понимать на уровне идеи.
Рисунок 2. Одна таблица «логически», физически — части на разных серверах.
Когда два сеанса меняют одни и те же строки, без правил координации возможны сбои. На лекциях 5–7 разберём транзакции, ACID и уровни изоляции; здесь — только картина целиком.
Студенту STUDENT_ID = 1 стипендия 150. Сеанс A и сеанс B одновременно делают разные изменения:
| Шаг | Сеанс A | Сеанс B | STIPEND в базе (если нет блокировок) |
|---|---|---|---|
| 1 | Читает 150 | Читает 150 | 150 |
| 2 | Пишет 150 + 50 = 200 | — | 200 |
| 3 | — | Пишет 150 + 30 = 180 (от старого 150!) | 180 |
Оба изменения «имели право» быть учтёнными (+50 и +30), но в базе осталось 180 — приращение A потерялось. Это потерянное обновление (лекция 6). Решение — транзакции и блокировки.
STUDENT_ID.Но FK не мешает двум корректным UPDATE «перезаписать» друг друга — для этого нужны транзакции.
UniversityDB.mdf на диске сервера» — хранилище данных.DROP DATABASE, если есть права (на учебном сервере так не делаем).Ответы: (2) нет единой схемы и транзакций между JSON и SQL; (3) сосед работает с тем же сервером, но не «внутри» вашего окна — права ограничивает администратор.
| Ошибка | Как правильно |
|---|---|
| «База хранится в SSMS» | SSMS только отправляет SQL; файлы — на сервере |
| «SQLite и SQL Server — одно и то же для курса» | Идеи SQL общие; многопользовательская модель — на SQL Server |
| «Распределённая = две копии на флешках» | Нужна согласованность и единый логический каталог |
| «FK защищает от всех конфликтов двух пользователей» | FK про ссылки между таблицами; параллельные UPDATE — про транзакции |
UniversityDB — в окне SSMS или на диске сервера?STUDENT.session) и почему у соседа по парте другой @@SPID?ALTER TABLE?Итог. Многопользовательский режим — норма: один SQL Server, много сеансов, данные в .mdf/.ldf. Распределённая БД — один логический каталог на нескольких узлах; это не два несвязанных файла. Конфликты при одновременной записи решают транзакции (лекция 5). На ЛР №4 — ALTER TABLE, индексы, пакеты GO.
Дата: 06.10.2026, вт, 12:30–14:05, ауд. 107
О чём эта лекция. Когда несколько пользователей меняют одни таблицы, операции нельзя выполнять «как попало»: перевод стипендии — это два UPDATE, и оба должны сохраниться вместе или отмениться вместе. Такие группы операций называются транзакциями.
Главная мысль одной фразой: транзакция с свойствами ACID — договор между приложением и СУБД: после COMMIT изменения надёжны и согласованы с ограничениями, после ROLLBACK — как будто их не было.
После прочтения вы сможете:
UniversityDB;BEGIN TRAN … COMMIT / ROLLBACK;SAVE TRAN для частичного отката.| Тема |
|---|
| Зачем транзакция; пример перевода стипендии |
| ACID на примерах UniversityDB |
| BEGIN, COMMIT, ROLLBACK, SAVE TRAN — разбор в SSMS |
| Мини-задачи, что СУБД не гарантирует |
| Самопроверка, связь с ЛР №6 |
На лекции 4 вы видели потерянное обновление: два сеанса читают одну стипендию и пишут разные суммы — одно изменение пропадает. Транзакция — способ сказать серверу: «эти команды — одно целое».
Транзакция — группа операций, которые выполняются как одно целое: либо все изменения сохраняются (COMMIT), либо ни одно (ROLLBACK).
Перевод 1000 рублей стипендии от студента STUDENT_ID = 1 студенту STUDENT_ID = 3:
Если второй UPDATE упадёт (например, нарушится CHECK на отрицательную стипендию), первый тоже должен откатиться — иначе деньги «исчезнут» из системы.
Рисунок 1. Два UPDATE в одной транзакции — атомарность (A).
| Свойство | Смысл | Пример на UniversityDB |
|---|---|---|
| A — Atomicity | Всё или ничего | Оба UPDATE стипендии зафиксированы или оба отменены |
| C — Consistency | БД остаётся в согласованном состоянии | После COMMIT выполняются FK, CHECK, NOT NULL |
| I — Isolation | Параллельные транзакции не мешают друг другу | Уровни изоляции — лекции 6–7 |
| D — Durability | После COMMIT данные переживут сбой | Запись в журнал .ldf до ответа клиенту |
Гарантирует: ограничения, объявленные в схеме — STIPEND >= 0, оценка 2–5, существующий UNIVERSITY_ID.
Не гарантирует автоматически: «суммарная стипендия группы не больше N», «число отличников не меньше 50%» — такие правила программируют в процедурах или проверяют в приложении.
После успешного COMMIT SQL Server сначала записывает изменения в журнал транзакций (.ldf), затем подтверждает клиенту. При сбое питания восстановление идёт по журналу (подробнее — лекции 13–14).
На ЛР №6 вы будете выполнять опасные UPDATE и DELETE внутри транзакции с ROLLBACK, чтобы не испортить эталон. Сейчас — та же техника на простом примере.
После ROLLBACK стипендии должны совпасть с тем, что было до BEGIN TRAN. Вкладка Results — два одинаковых набора строк; на Messages — «Rollback Tran».
Окно запроса: транзакция с ROLLBACK — безопасный способ «попробовать» UPDATE на учебном сервере.
Два одинаковых результата SELECT — признак успешного отката.
SAVE TRAN — промежуточная «закладка». ROLLBACK TRAN step1 откатывает до неё, но транзакция продолжается до COMMIT или полного ROLLBACK.
На ЛР №16 разберёте TRY/CATCH подробнее. Здесь важно: при ошибке нужен ROLLBACK, иначе транзакция «висит» открытой.
UNIVERSITY_ID = 999? Почему?BEGIN TRAN не завершён, видят ли соседи ваши незафиксированные строки? (Зависит от уровня изоляции — по умолчанию частично защищены.)ACID не обещает: высокую скорость, отсутствие тупиков, защиту от удаления диска без резервной копии.
| Ошибка | Как правильно |
|---|---|
Забыли COMMIT | Транзакция держит блокировки; закройте окно или выполните ROLLBACK |
UPDATE без WHERE в транзакции и случайный COMMIT | Сначала SELECT с тем же WHERE, на ЛР — только ROLLBACK |
| Путают ROLLBACK и DELETE | ROLLBACK отменяет незафиксированные изменения; DELETE — DML-команда |
STIPEND >= 0 — про Consistency, а «фонд группы ≤ N» — уже нет?ROLLBACK вместо COMMIT?SAVE TRAN отличается от полного ROLLBACK?BEGIN TRAN … ROLLBACK на практике?Итог. Транзакция группирует операции; ACID описывает гарантии СУБД. На практике в SSMS освоите BEGIN TRAN, COMMIT, ROLLBACK и SAVE TRAN. Перед опасными изменениями на общем сервере — откат, а не коммит.
Дата: 13.10.2026, пн
О чём эта лекция. Если две транзакции работают параллельно без изоляции, результат может отличаться от любого последовательного выполнения. У каждой такой ситуации есть имя — аномалия.
Главная мысль одной фразой: потерянное обновление, грязное, неповторяемое и фантомное чтение — четыре классических конфликта; зная их, на следующей лекции вы выберете подходящий уровень изоляции.
После прочтения вы сможете:
| Тема |
|---|
| Четыре аномалии на примерах UniversityDB |
| Расписания операций T1 / T2 |
| Шпаргалка, отличия похожих случаев |
| Мини-задачи, частые ошибки |
| Самопроверка, связь с лекцией 7 и ЛР №6 |
На лекции 5 вы группировали команды в транзакции. Если две транзакции идут параллельно, а изоляция недостаточна, результат может не совпасть ни с одним «честным» последовательным порядком. Такие эффекты имеют имена — их нужно узнавать на слух.
Два сеанса читают одно значение, оба считают от него, оба пишут — одно изменение затирается.
Пример со складом: 40 учебников. T1 продаёт 10 → пишет 30. T2 продаёт 5, но считала от 40 → пишет 35. Продано 15, в базе 35 — продажа T1 потеряна.
Пример из UniversityDB: два сеанса одновременно меняют STIPEND одного студента — как на лекции 4 и 5.
T1 изменила строку, но ещё не сделала COMMIT. T2 прочитала «новое» значение. T1 откатилась — T2 опиралась на данные, которых «не было».
Пример: T1 в транзакции начислила стипендию +500 и напечатала ведомость для проверки; T2 по этой сумме выдала справку; T1 сделала ROLLBACK — справка ложная.
T1 дважды читает одну и ту же строку — между чтениями T2 изменила и зафиксировала её.
Пример: T1 дважды читает RATING вуза ВГУ (UNIVERSITY_ID = 10): сначала 450, потом 470 — между чтениями другой сеанс обновил строку и сделал COMMIT.
T1 дважды выполняет один и тот же запрос с условием — второй раз набор строк другой: появились или исчезли строки, подходящие под условие.
Пример: T1: SELECT COUNT(*) FROM dbo.STUDENT WHERE KURS = 1 → 4. T2 вставила нового первокурсника и сделала COMMIT. T1 повторяет COUNT → 5. «Лишняя» строка — фантом.
Рисунок 1. Нарисуйте такую схему на листе для любой аномалии — так проще объяснить конфликт.
| Аномалия | Что ломается | Пример в нашей БД |
|---|---|---|
| Потерянное обновление | Два WRITE одного поля | Два UPDATE STIPEND одного STUDENT_ID |
| Грязное чтение | Чтение до COMMIT | SELECT стипендии до отката чужой транзакции |
| Неповторяемое чтение | Одна строка изменилась | Два SELECT RATING одного вуза |
| Фантом | Изменился набор по условию | Два COUNT первокурсников |
Вопрос для разбора: отчёт дважды посчитал средний балл по предмету: 4.1 и 3.9, потому что между расчётами исправили одну оценку. Это неповторяемое чтение (изменилась конкретная строка в EXAM_MARKS).
Если между двумя COUNT добавили новую ведомость (новую строку) — это фантом.
Если справку напечатали по стипендии до чужого COMMIT, а потом транзакция откатилась — грязное чтение.
ROLLBACK — связь с грязным чтением для соседей?Ответы: (1) потерянное обновление; (2) фантом; (3) незафиксированные изменения не должны остаться в общей базе — откат убирает «мусор» для других сеансов.
| Путают | Как запомнить |
|---|---|
| Неповторяемое и фантом | Неповторяемое — одна строка; фантом — другой набор строк |
| Грязное и неповторяемое | Грязное — читали до COMMIT; неповторяемое — после чужого COMMIT |
| «Транзакция = нет аномалий» | Нужен ещё подходящий уровень изоляции (лекция 7) |
STUDENT.Итог. Четыре аномалии — словарь для обсуждения параллельного доступа. Зная названия и примеры на UniversityDB, на следующей лекции сопоставите их с уровнями изоляции SQL Server.
Дата: 13.10.2026, вт, 14:15–15:50
О чём эта лекция. Полная сериализуемость — идеал, но дорогой: транзакции будут долго ждать друг друга. SQL Server предлагает несколько уровней изоляции — осознанный компромисс между скоростью и точностью чтения.
Главная мысль одной фразой: уровень изоляции задаёт, какие аномалии допустимы; умолчание SQL Server — READ COMMITTED, для жёстких инвариантов берут REPEATABLE READ или SERIALIZABLE.
После прочтения вы сможете:
SET TRANSACTION ISOLATION LEVEL … в SSMS;| Тема |
|---|
| Компромисс «скорость / точность»; связь с лекцией 6 |
| Четыре уровня SQL-92 и таблица аномалий |
| Блокировки S и X; как уровень влияет на ожидание |
SET TRANSACTION ISOLATION LEVEL в SSMS |
| Снимки (snapshot), SQLite, выбор уровня на практике |
| Мини-задачи, самопроверка, связь с ЛР №7–8 |
На лекции 6 вы разобрали четыре аномалии параллельного доступа. Идеальный вариант — когда транзакции ведут себя так, будто выполняются строго по очереди (сериализуемость). На практике полная сериализуемость дорога: сеансы долго ждут блокировок друг друга.
Уровень изоляции — явный договор: «я согласен на часть аномалий ради скорости». Вы выбираете, какие из четырёх эффектов лекции 6 допустимы в вашем сценарии.
Деканат строит отчёт «средний балл по предметам» — ему не нужны незафиксированные оценки (грязное чтение), но допустимо, что между двумя SELECT кто-то добавит новую ведомость (фантом). Кассовая операция «списать стипендию и зачислить на другой счёт» — наоборот, нужна жёсткая атомарность и минимум параллельных изменений одних строк.
Стандарт SQL-92 задаёт четыре уровня. В SQL Server по умолчанию — READ COMMITTED. Столбец «потерянное обновление» — для связи с лекцией 6 (конфликт двух UPDATE одной строки).
| Уровень | Грязное | Неповтор. | Фантом | Потерянное обновление* | Где применяют |
|---|---|---|---|---|---|
READ UNCOMMITTED | да | да | да | да | Грубая оценка «на сейчас», мониторинг |
READ COMMITTED | нет | да | да | редко** | Умолчание SQL Server; обычные формы |
REPEATABLE READ | нет | нет | да | нет | Два чтения одной строки должны совпасть |
SERIALIZABLE | нет | нет | нет | нет | Короткие критичные операции |
* Упрощённо для курса. ** При обычных блокировках строк SQL Server на READ COMMITTED два одновременных UPDATE одной строки сериализуются — второй сеанс ждёт первый.
| Аномалия (лекция 6) | Какой уровень запрещает первым |
|---|---|
| Грязное чтение | READ COMMITTED и выше |
| Неповторяемое чтение | REPEATABLE READ и выше |
| Фантом | SERIALIZABLE (или snapshot с подходящими настройками) |
| Потерянное обновление | Блокировки на запись; часто достаточно READ COMMITTED |
Рисунок 1. Запомните порядок уровней слева направо — его часто спрашивают на самопроверке.
СУБД реализует уровни через блокировки на строках, страницах или таблицах.
Если T1 держит X на строке STUDENT_ID = 1, T2 не сможет ни прочитать её «для изменения», ни обновить, пока T1 не сделает COMMIT или ROLLBACK.
На READ COMMITTED второй сеанс не увидит «грязную» стипендию до COMMIT первого — но может подождать, если первый ещё держит X.
Уровень задаётся для текущего сеанса до следующего изменения:
Окно New Query: команда SET TRANSACTION ISOLATION LEVEL перед BEGIN TRAN.
Результат агрегирующего SELECT — на следующей лабораторной (№7) вы считаете такие же средние без смены уровня изоляции.
Начиная с SQL Server 2005, есть версионность строк: читатели могут видеть согласованный «снимок» на момент начала транзакции, не блокируя писателей так жёстко, как при SERIALIZABLE. Режим включают на уровне базы (ALLOW_SNAPSHOT_ISOLATION) и задают SET TRANSACTION ISOLATION LEVEL SNAPSHOT. Для длинных отчётов по UniversityDB это часто удобнее, чем максимальная блокировка.
В SQLite нет полного набора четырёх уровней. BEGIN DEFERRED / IMMEDIATE / EXCLUSIVE задают, когда сеанс получает право записи. Для курса основной стенд — SQL Server; SQLite упоминаем только для сравнения.
| Сценарий | Разумный выбор | Почему |
|---|---|---|
| Онлайн-форма «показать баланс стипендии» | READ COMMITTED | Не показывать незафиксированные суммы |
| Отчёт «средний балл» на 50 страниц | Snapshot или READ COMMITTED | Долгое чтение не должно блокировать приём оценок |
| Перевод стипендии между двумя студентами | Короткая транзакция + проверки | Атомарность важнее «мягкой» изоляции чтения |
| Инвентаризация: два COUNT подряд должны совпасть | REPEATABLE READ или выше | Запрет неповторяемого чтения |
COMMIT?SELECT COUNT(*) FROM dbo.STUDENT WHERE KURS = 1 дали 4 и 5. Какая аномалия и какой уровень её убирает?SERIALIZABLE «везде по умолчанию»?Ответы: (1) READ COMMITTED; (2) фантом, SERIALIZABLE; (3) лишние ожидания и риск тупиков — тема лекции 8.
| Ошибка | Как запомнить |
|---|---|
Путают уровень изоляции и BEGIN TRAN | Транзакция группирует команды; уровень — правила для параллельных транзакций |
Ждут, что READ COMMITTED убирает фантомы | Фантомы уходит только на SERIALIZABLE (или snapshot с нужной семантикой) |
| Меняют уровень в середине транзакции | В SQL Server уровень лучше задавать до BEGIN TRAN |
READ COMMITTED?SERIALIZABLE?ROLLBACK, хотя уровень по умолчанию уже READ COMMITTED?Итог. Уровень изоляции — осознанный компромисс: вы отмечаете в таблице, какие аномалии лекции 6 допустимы. Умолчание SQL Server (READ COMMITTED) подходит для большинства учебных запросов; для жёстких инвариантов повышают уровень или используют snapshot.
Дата: 20.10.2026, вт, 14:15–15:50
О чём эта лекция. Блокировки защищают данные, но могут привести к тупику, когда две транзакции вечно ждут друг друга. Отдельно — репликация: копирование данных на другой сервер для отчётов и резерва.
Главная мысль одной фразой: тупик — следствие конкуренции, а не «поломка СУБД»; SQL Server выбирает жертву (ошибка 1205), а репликация снимает нагрузку с основного сервера.
После прочтения вы сможете:
CASE, COALESCE).| Тема |
|---|
| Связь блокировок с уровнями изоляции (лекция 7) |
| Двухфазный протокол блокировок (2PL) |
Тупик на примере UniversityDB |
| Ошибка 1205, профилактика |
| Репликация — зачем и виды |
| Мини-задачи, самопроверка, связь с ЛР №9–14 |
На лекции 7 вы выбирали уровень изоляции по таблице аномалий. Реализует это СУБД через блокировки: S на чтение, X на запись. Чем строже уровень, тем дольше блокировки держатся и тем чаще сеансы ждут друг друга.
Идея: блокировка — «бронь» на строку или страницу. Пока T1 держит X на строке STUDENT_ID = 1, T2 не может её изменить — это защита от потерянного обновления и грязного чтения.
Блокировать можно строку, страницу, всю таблицу. Без индекса фильтр WHERE CITY = N'Воронеж' иногда блокирует больше строк, чем нужно — отсюда рекомендация «нужные индексы» при проектировании отчётов по STUDENT.
Двухфазный протокол блокировок — правило, которому следуют многие СУБД:
Строгий вариант (Strict 2PL): все X-блокировки снимаются только при COMMIT или ROLLBACK. Так гарантируется, что никто не прочитает незафиксированную запись.
Рисунок 1. Схема 2PL — основа для понимания порядка конфликтов между транзакциями.
Тупик — цикл ожидания: T1 держит ресурс A и ждёт B; T2 держит B и ждёт A. Без вмешательства обе транзакции зависнут навсегда.
Два сеанса переводят стипендию между студентами, но в разном порядке блокируют строки:
Каждый сеанс держит «свою» строку и ждёт вторую — получается цикл. SQL Server строит граф ожидания, находит цикл и выбирает жертву.
Рисунок 2. Цикл в графе ожидания — признак тупика. СУБД откатывает одну из транзакций.
Код ошибки — 1205. Клиентское приложение может повторить транзакцию (обычно ограниченное число раз). На учебном сервере для демонстрации тупика нужны два окна SSMS — выполняйте только по указанию преподавателя.
Для демонстрации тупика открывают два окна New Query к одной базе — как на лекции 4 для сеансов.
| Правило | Смысл на UniversityDB |
|---|---|
| Одинаковый порядок таблиц | Везде сначала STUDENT, потом EXAM_MARKS — не наоборот в разных процедурах |
| Короткие транзакции | Не держать BEGIN TRAN, пока пользователь думает над формой |
| Индексы по фильтрам | Меньше «широких» блокировок при WHERE UNIVERSITY_ID = … |
| Обработка 1205 | Повтор транзакции в коде приложения |
| Меньше лишней строгости | Не ставить SERIALIZABLE, если хватает READ COMMITTED (лекция 7) |
Репликация — копирование данных (или изменений) на другой сервер. Зачем: отчёты не нагружают основной сервер, резервная копия «живых» данных, филиал в другом городе.
| Вид | Идея | Когда уместна |
|---|---|---|
| Снимковая | Периодически полная копия | Редко меняющиеся справочники |
| Транзакционная | Почти онлайн передача изменений | Актуальная копия для чтения |
| Слиянием (merge) | Изменения на нескольких узлах, потом сводят | Распределённые филиалы с локальной записью |
Реплика не заменяет транзакции и блокировки на основном сервере — это отдельный механизм доставки данных. Связь с лекцией 4: распределённая БД может хранить студентов по регионам, репликация — один из способов синхронизации узлов.
EXAM_MARKS, затем STUDENT — в разном порядке. Возможен тупик?ROLLBACK на ЛР №6 снижает риск конфликтов на общем сервере?Ответы: (1) да, если блокируют пересекающиеся ресурсы в разном порядке; (2) меньше времени держит X-блокировки; (3) транзакционная ближе к «онлайн», снимковая — с большим лагом между копиями.
Итог. Блокировки реализуют уровни изоляции; при неудачном порядке доступа возникает тупик — SQL Server выбирает жертву (1205). Репликация снимает нагрузку с основного узла, но не отменяет правила транзакций на master-базе.
Дата: 27.10.2026, вт, 14:15–15:50
О чём эта лекция. Не все данные удобно класть в таблицы с фиксированными столбцами. Разберём три «типа» данных и когда реляционная модель остаётся лучшим выбором, а когда — JSON, документы или файловое хранилище.
Главная мысль одной фразой: структурированные данные — основа курса (UniversityDB); полуструктурированные и неструктурированные требуют других моделей, но метаданные часто всё равно хранят в SQL Server.
После прочтения вы сможете:
| Тема |
|---|
Три типа данных на примерах вуза и UniversityDB |
| Модели хранения: реляционная, документная, key-value |
| Где хранят файлы и метаданные |
| Big Data — три «V» обзорно |
| Мини-задачи, самопроверка, связь с лекцией 10 и ЛР №17–19 |
До сих пор курс опирался на структурированные данные — таблицы SQL с фиксированными столбцами. Реальная информационная система вуза смешивает и другие форматы.
Строки и столбцы с типами, ограничениями, связями FK. Весь эталон UniversityDB: STUDENT, EXAM_MARKS, UNIVERSITY. Запросы SELECT, GROUP BY (ЛР №7–8), подзапросы (ЛР №9–10) работают именно с такими данными.
Есть именованные поля и вложенность, но схема гибче таблицы:
{"pair": 3, "subject": "Базы данных", "room": "220"}.timestamp, level, message, но набор полей может меняться.Нет фиксированной таблицы полей: PDF заявления, фото студбилета, видеолекция. В SQL Server обычно хранят метаданные (имя файла, дата, автор, ссылка), а сам файл — в файловом или объектном хранилище (S3, SharePoint, сетевой диск).
Рисунок 1. UniversityDB — левый столбец; к концу семестра добавятся XML и документная MongoDB.
| Модель | Пример СУБД | Как выглядит | Когда уместна |
|---|---|---|---|
| Реляционная | SQL Server | Таблицы, FK, JOIN | Учёт, отчёты, строгие связи (оценки ↔ студенты) |
| Документная | MongoDB | Документ JSON/BSON | Гибкая схема, вложенные объекты (анкета с разным числом полей) |
| Иерархическая / XML | XML в SQL Server | Дерево элементов | Обмен между системами, XSD-контракт |
| Key-Value | Redis | Ключ → значение | Кэш сессий, счётчики, очереди |
Отчёт «средний балл по кафедрам с JOIN трёх таблиц» на нормализованной схеме проще и надёжнее в SQL. Документная модель хороша, когда структура записи часто меняется или глубоко вложена — например, черновик анкеты абитуриента с опциональными блоками.
Гибрид: основные учётные данные — SQL Server; кэш или лог — Redis; обмен — XML; прототип мобильного приложения — MongoDB (ЛР №19).
Хранить большой PDF в столбце VARBINARY(MAX) можно, но на практике:
Типичная схема: таблица DocumentMeta(FileId, StudentId, FileName, StoredAt, StorageUrl) — структурированные метаданные; путь или URL — на неструктурированный файл снаружи.
На ЛР №17 вы загрузите настоящий XML в тип XML — это полуструктурированные данные внутри реляционной СУБД.
Когда данных слишком много для одного SQL Server на одном диске, говорят о Big Data. Три «V» (без формул на экзамене — только смысл):
| «V» | Смысл | Пример |
|---|---|---|
| Volume (объём) | Терабайты и больше | Логи посещаемости LMS за годы |
| Velocity (скорость) | Поток данных в реальном времени | Датчики, клики на портале |
| Variety (разнообразие) | Разные форматы одновременно | Таблицы + JSON + видео |
Для учебной UniversityDB (19 студентов, 24 оценки) достаточно одного SQL Server. Big Data — контекст, зачем в индустрии появляются Hadoop, Spark, озёра данных.
EXAM_MARKS, JSON расписания, скан диплома.Ответы: (1) структурированные, полуструктурированные, неструктурированные (+ метаданные в SQL); (2) целостность FK, транзакции, отчёты GROUP BY; (3) когда набор полей у записей сильно различается.
UniversityDB.VARBINARY «на всякий случай»?Итог. Структурированные таблицы — основа курса и большинства учётных систем вуза. Полуструктурированные и неструктурированные данные требуют других инструментов, но метаданные о них часто всё равно лежат в SQL Server.
Дата: 03.11.2026, вт, 14:15–15:50
О чём эта лекция. XML — стандарт обмена иерархическими данными между системами. Разберём синтаксис, отличие well-formed от valid документа и как SQL Server хранит XML в столбце типа XML.
Главная мысль одной фразой: XML описывает дерево элементов и атрибутов; XSD задаёт правила, а XPath и методы .value() / .query() извлекают нужные узлы прямо в T-SQL.
После прочтения вы сможете:
| Тема |
|---|
| Синтаксис XML: элементы, атрибуты, пролог |
| Well-formed и valid; роль XSD |
| XPath на примере вуза и студентов |
Тип XML в SQL Server: .value(), .query() |
| XML vs JSON; мини-задачи, связь с ЛР №17 |
На лекции 9 вы разделили данные на структурированные таблицы и полуструктурированные форматы. XML — один из стандартов обмена иерархическими данными между организациями: банк, деканат, госуслуги могут требовать файл по XSD-схеме, а не «произвольный Excel».
UniversityDB остаётся реляционной; XML понадобится, когда нужно передать фрагмент данных (список студентов вуза) в систему партнёра или сохранить документ в столбце XML рядом с ключами SQL.
<Name>…</Name>.id="22" в открывающем теге; не путать с дочерним элементом.University).<?xml …?> с версией и кодировкой (UTF-8 для кириллицы).Рисунок 1. Корень, дочерние элементы и атрибут — базовая модель для XPath.
| Проверка | Что смотрит | Пример ошибки |
|---|---|---|
| Well-formed | Синтаксис: закрытые теги, одна корневая вершина | <Name>МГУ<City>… без закрытия |
| Valid | Соответствие XSD/DTD: обязательные поля, типы | Нет атрибута id у University |
Парсер SQL Server при вставке в XML сначала проверяет well-formed. Valid — ответственность обмена: партнёр отклонит файл, не прошедший XSD.
maxOccurs="unbounded" — сколько угодно студентов; use="required" — атрибут id обязателен.
XPath — язык путей к узлам. Примеры для документа выше:
| XPath | Результат |
|---|---|
/University/Name | Элемент с названием вуза |
/University/Student[@kurs='1'] | Студенты первого курса |
//Student | Все элементы Student на любой глубине |
(/University/Name)[1] | Первый Name (для .value() в SQL) |
Столбец типа XML хранит документ внутри таблицы. Основные методы T-SQL:
.value() — одно скалярное значение (как подзапрос с одной строкой). .query() — фрагмент XML (несколько узлов). На ЛР №17 вы создадите таблицу dbo.UnivXml и загрузите похожий документ.
Окно New Query: переменная типа XML и метод .value().
| Критерий | XML | JSON |
|---|---|---|
| Типичное применение | Банки, госсистемы, старые интеграции | REST API, веб и мобильные клиенты |
| Схема | XSD, строгий контракт | JSON Schema (реже в старых системах) |
| В SQL Server | Тип XML, XPath | OPENJSON, JSON_VALUE (2016+) |
<Student>Иванов<Stipend>150</Student> — что не так?id у University?XML, а не в NVARCHAR(MAX)?Ответы: (1) не закрыт Stipend; (2) (/University/@id)[1]; (3) проверка well-formed, индексы, методы XPath.
<Student id="101">?XML, если есть NVARCHAR?.value() на ЛР №17?Итог. XML описывает дерево данных; XSD задаёт контракт; SQL Server хранит документы в типе XML и извлекает поля через XPath. Это мост от реляционной UniversityDB к полуструктурированному обмену.
Дата: 17.11.2026, вт, 12:30–14:05
О чём эта лекция. База данных живёт на сервере годами — нужен человек (или команда), который следит за доступностью, резервными копиями, правами и производительностью. Это задачи администратора БД.
Главная мысль одной фразой: экземпляр SQL Server содержит системные и пользовательские базы; мониторинг через SSMS и динамические представления показывает, чего ждут запросы и где узкое место.
После прочтения вы сможете:
master, tempdb;DBCC CHECKDB;wait_type в sys.dm_exec_requests;| Тема |
|---|
| Роль DBA; что уже делали на ЛР №1 |
| Экземпляр SQL Server, системные базы, файлы .mdf/.ldf |
| Модели восстановления SIMPLE / FULL |
Мониторинг: Activity Monitor, sys.dm_exec_requests |
| Обслуживание, самопроверка, связь с лекциями 13–14 |
На ЛР №1 вы подключались к SQL Server и создавали UniversityDB. База будет жить на сервере месяцами: её нужно копировать, защищать, наблюдать и чинить после сбоев.
Администратор баз данных (DBA) отвечает за:
STUDENT, кто — только VIEW);Разработчик пишет запросы; DBA следит, чтобы сервер выдержал нагрузку и данные не пропали. На маленькой учебной базе роли часто совмещают — но различать их полезно.
Экземпляр (instance) — одна установленная служба SQL Server на машине. В Object Explorer вы видите экземпляр → базы данных.
| База | Назначение |
|---|---|
master | Метаданные сервера: логины, список баз |
msdb | Задания SQL Server Agent, история бэкапов |
tempdb | Временные объекты; пересоздаётся при перезапуске |
model | Шаблон для новых баз |
UniversityDB | Пользовательская учебная база |
Object Explorer → System Databases: master, model, msdb, tempdb. Пользовательские базы (в т.ч. UniversityDB) — в том же узле Databases.
У UniversityDB два основных файла: .mdf (данные) и .ldf (журнал транзакций). Журнал — тема лекций 5–8; без него нельзя надёжно восстанавливать базу в модели FULL.
SIMPLE — журнал усечён автоматически; point-in-time restore ограничен. FULL — нужен для цепочки BACKUP LOG и восстановления «на минуту». Подробно — лекция 13.
Activity Monitor (правый клик на экземпляре) показывает:
Для текстового отчёта — динамическое представление sys.dm_exec_requests:
wait_type — чего ждёт запрос: PAGEIOLATCH (диск), LCK_M_* (блокировка), NETWORKIO (сеть). Если отчёт по JOIN трёх таблиц «висит», здесь видна причина.
Activity Monitor открывают правым кликом по имени экземпляра в Object Explorer (тот же узел, что на рисунке в §2).
| Действие | Зачем |
|---|---|
| Перестроение / реорганизация индексов | Точный план запроса, меньше Scan |
| Обновление статистики | Оптимизатор правильно оценивает число строк |
DBCC CHECKDB | Проверка целостности страниц файлов |
| Резервное копирование по расписанию | SQL Server Agent (обзорно) |
На учебном сервере не работайте под sa без необходимости и не запускайте CHECKDB в часы сдачи лабораторных без согласования.
blocking_session_id вместе с wait_type?Ответы: (1) msdb; (2) журнал фиксирует изменения до COMMIT; (3) блокировка — частая причина ожидания при параллельных UPDATE.
wait_type = PAGEIOLATCH?DBCC CHECKDB по расписанию?Итог. SQL Server — не только «место для таблиц», а управляемый сервис с системными базами, журналом и инструментами мониторинга. Администрирование делает учебную UniversityDB пригодной для реальной эксплуатации.
Дата: 24.11.2026, вт, 12:30–14:05
О чём эта лекция. Часть логики можно перенести на сервер: представления, хранимые процедуры и триггеры выполняются рядом с данными — меньше трафика и единые правила для всех клиентов.
Главная мысль одной фразой: VIEW прячет сложный JOIN; процедура параметризует запрос; триггер реагирует на INSERT/UPDATE/DELETE — AFTER после изменения, INSTEAD OF вместо него.
После прочтения вы сможете:
CREATE VIEW для пользователя отчётов;usp_StudentByKurs и вызвать её в SSMS;| Тема |
|---|
| VIEW — зачем прятать JOIN |
| Хранимые процедуры и EXEC |
| Триггеры AFTER и INSTEAD OF |
| План запроса: Seek vs Scan |
| Индексы, самопроверка, связь с ЛР №20–22 |
На ЛР №11 вы писали длинный JOIN «студент + вуз + оценки». Пользователю отчётов неудобно каждый раз повторять связи — им нужна «виртуальная таблица» с понятными столбцами.
VIEW — сохранённый SELECT с именем. Данные не копируются: при SELECT * FROM v_StudentUniv сервер выполняет запрос из определения VIEW.
Не путать с таблицей: в Object Explorer VIEW лежит в папке Views; INSERT в простой VIEW с JOIN обычно невозможен — помогает триггер INSTEAD OF (ЛР №22).
Процедура — программа T-SQL на сервере с параметрами. Один вызов EXEC вместо копирования текста запроса в каждое приложение.
Плюсы: меньше сетевого трафика; единая логика; можно выдать GRANT EXECUTE без права SELECT на таблицу (ЛР №23).
Триггер — код, который SQL Server запускает при INSERT, UPDATE или DELETE.
| Тип | Когда | Пример |
|---|---|---|
| AFTER | После изменения строк | Аудит в AuditLog |
| INSTEAD OF | Вместо операции | INSERT через VIEW с JOIN |
Внутри триггера доступны псевдотаблицы inserted (новые значения) и deleted (старые). На ЛР №22 вы запишете изменения в EXAM_MARKS и запретите понижение оценки.
В SSMS: кнопка Include Actual Execution Plan (Ctrl+M). Смотрите операторы:
Индекс на STUDENT(UNIVERSITY_ID) ускорит JOIN с UNIVERSITY. Выражение в WHERE «ломает» индекс: WHERE YEAR(BIRTHDAY) = 2005 — лучше диапазон BIRTHDAY BETWEEN '2005-01-01' AND '2005-12-31'.
В SSMS включите Include Actual Execution Plan (Ctrl+M), выполните JOIN из §1 и откройте вкладку Execution plan под результатами — ищите операторы Index Seek по ключу FK или Index Scan при его отсутствии. Готового скриншота плана в материалах нет: на ЛР №20–21 сделайте свой.
STUDENT?SET NOCOUNT ON в процедуре?MARK?Ответы: (1) да, VIEW показывает актуальные данные; (2) не слать клиенту «(N rows affected)» на каждый внутренний SELECT; (3) триггер может писать в другую таблицу и откатывать транзакцию.
usp_StudentByKurs, если можно написать тот же SELECT?Итог. VIEW, процедуры и триггеры переносят логику на сервер рядом с данными — меньше дублирования в приложениях и единые правила для всех клиентов SSMS.
Дата: 01.12.2026, вт, 14:15–15:50
О чём эта лекция. Диск может выйти из строя, студент может ошибочно выполнить DELETE, ransomware шифрует файлы — без резервной копии данные не вернуть. Разберём виды backup в SQL Server и правило 3-2-1.
Главная мысль одной фразой: полная, разностная копия и журнал транзакций образуют цепочку восстановления; модель FULL позволяет восстановиться на минуту, SIMPLE — только до последней полной копии.
После прочтения вы сможете:
BACKUP DATABASE и BACKUP LOG;| Тема |
|---|
| Зачем копировать: сценарии потери данных |
| RPO и RTO на примере деканата |
| FULL, DIFF, LOG backup |
| Модели SIMPLE и FULL |
| Правило 3-2-1, SQLite, связь с ЛР №24 |
На ЛР №6 вы делали UPDATE и DELETE. Одна ошибка в WHERE без транзакции может стереть половину EXAM_MARKS. Диск выходит из строя, ransomware шифрует .mdf — без копии восстановить нельзя.
Резервная копия — не «галочка для отчёта», а часть RPO/RTO: сколько данных можно потерять и как быстро поднять сервис.
| Метрика | Вопрос | Пример |
|---|---|---|
| RPO | Сколько истории можно потерять? | «Не больше 1 часа ведомости» → бэкап лога каждый час |
| RTO | Как быстро снова работать? | «Деканат открыт через 4 часа после сбоя» |
| Тип | Содержимое | Файл (пример) |
|---|---|---|
| FULL | Вся база целиком | univ_full.bak |
| DIFFERENTIAL | Изменения с последней FULL | univ_diff.bak |
| LOG | Записи журнала транзакций | univ_log.trn |
Цепочка FULL → DIFF → LOG позволяет восстановиться на конкретную минуту — только в модели восстановления FULL (лекция 11).
SIMPLE — журнал усекается автоматически; point-in-time restore ограничен. FULL — нужен для регулярного BACKUP LOG и STOPAT на лекции 14.
Три копии данных, на двух носителях, одна копия вне площадки (облако, другой офис).
Файл .db копируют, когда нет записи. «Горячая» копия — VACUUM INTO 'backup.db'. Копирование файла во время активной записи без WAL рискованно.
Итог. Стратегия бэкапов выбирается от RPO/RTO; без проверенного восстановления копия не даёт уверенности.
Дата: 08.12.2026, вт, 12:30–14:05
О чём эта лекция. Резервная копия бесполезна, если вы ни разу не пробовали восстановление. Разберём порядок RESTORE, восстановление на момент времени и параллельно — права доступа: login, user, role, GRANT.
Главная мысль одной фразой: NORECOVERY накатывает цепочку файлов, RECOVERY открывает базу; при логической ошибке поднимают копию рядом и переносят нужные строки, а не откатывают всю боевую базу.
После прочтения вы сможете:
STOPAT;UniversityDB.| Тема |
|---|
| Цепочка RESTORE: NORECOVERY / RECOVERY |
| STOPAT — откат ошибочного DELETE |
| Логическая ошибка: копия «рядом» |
| Login, user, role, GRANT/REVOKE |
| Персональные данные в UniversityDB |
Копия бесполезна, если вы ни разу не делали RESTORE. Общий порядок:
NORECOVERY.NORECOVERY.RECOVERY.NORECOVERY оставляет базу в режиме «ещё накатываем файлы». RECOVERY открывает базу для работы.
Если в 10:15 выполнили ошибочный DELETE FROM EXAM_MARKS WHERE …, а цепочка лога сохранена — можно откатиться на секунду до ошибки.
Если после ошибки уже наработали новые данные, не откатывайте всю боевую базу на вчера. Поднимите копию рядом (UniversityDB_restore), вытащите нужные строки, вставьте в основную базу — так делают на ЛР №24.
Login — учётная запись на уровне сервера. User — сопоставление login внутри базы. Role — набор прав для группы пользователей.
Принцип минимальных привилегий: только то, что нужно для работы. В UniversityDB есть ФИО и даты рождения — персональные данные; в проекте нужна политика доступа и аудит (триггер на ЛР №22).
NORECOVERY?STOPAT помогает после ошибочного DELETE?EXAM_MARKS для роли «читатель»?Итог. Восстановление и права — две стороны надёжности: данные можно вернуть, а доступ — ограничить.
Дата: 15.12.2026, вт, 12:30–14:05
О чём эта лекция. Возвращаемся к распределённым системам на уровне протоколов: как согласовать COMMIT на двух серверах с помощью двухфазной фиксации (2PC) и зачем фрагментировать таблицы по регионам.
Главная мысль одной фразой: 2PC — «сначала спроси всех, готовы ли зафиксировать, потом COMMIT или ROLLBACK всем»; это цена масштаба распределённой БД.
После прочтения вы сможете:
| Тема |
|---|
| Распределённая БД — повторение лекции 4 |
| Архитектуры доступа к данным |
| Репликация (связь с лекцией 8) |
| Двухфазная фиксация 2PC |
| Фрагментация, компромиссы |
Студенты ВГУ в Воронеже, филиал в другом городе — данные могут лежать на разных серверах, но приложение видит одну базу. Важна прозрачность: разработчик пишет обычный SQL, система направляет запрос на нужный узел.
| Вид | Когда |
|---|---|
| Снимок | Редко меняющиеся справочники вузов |
| Транзакционная | Отчёты с копии, минимальная задержка |
| Слиянием | Филиалы с автономной работой офлайн |
Связь с лекцией 8: реплика — способ масштабировать чтение и повышать доступность.
Одна бизнес-операция затрагивает два узла (списание и зачисление на разных серверах). Протокол:
Минус: при сбое координатора участники могут долго ждать. Для курса достаточно понимать идею согласованности vs доступности.
Горизонтальная — строки по регионам (STUDENT Москвы на узле A). Вертикальная — редкие столбцы на отдельном узле. Цель — баланс нагрузки и близость к пользователю.
Итог. Распределённые системы — продолжение многопользовательского режима и репликации; 2PC — цена согласованности на нескольких узлах.
Дата: 15.12.2026, вт, 14:15–15:50
О чём эта лекция. Завершение курса: чем операционная база (OLTP) отличается от аналитической (OLAP), что такое хранилище данных и Data Mining — и как подготовиться к экзамену по материалам семестра.
Главная мысль одной фразой: UniversityDB учит оперативному учёту; хранилище и OLAP отвечают на вопросы «как менялось за годы», а экзамен проверяет связное понимание модели, SQL и надёжности.
После прочтения вы сможете:
| Тема |
|---|
| OLTP vs OLAP на примере UniversityDB |
| Хранилище данных, схема «звезда» |
| Data Mining — три задачи без формул |
| Итоги семестра |
| Формат экзамена и план повторения |
OLTP (UniversityDB) | OLAP / DWH | |
|---|---|---|
| Цель | Выставить оценку, изменить стипендию | «Как менялся средний балл по городам за 5 лет» |
| Схема | 3НФ, много JOIN | «Звезда»: факты + измерения |
| Нагрузка | Короткие INSERT/UPDATE | Тяжёлые отчёты, сканы |
| История | Текущее состояние | Снимки за годы, ETL |
Факт — измеримое событие (оценка, сумма). Измерение — контекст (время, предмет, вуз). Операции OLAP-куба: срез, детализация, свёртка.
DWH собирает данные из учётных систем (ETL). Схема «звезда»: центральная таблица фактов (FactExam), вокруг — справочники (DimStudent, DimSubject, DimDate). Витрины — готовые срезы для конкретного отдела.
Цепочка семестра: модель и нормализация → SQL и JOIN → транзакции и блокировки → XML, иерархии, MongoDB → VIEW, процедуры, триггеры → бэкап, права, аналитика.
UniversityDB — сквозной пример от CREATE TABLE до GRANT и RESTORE.
24 контрольных вопроса и билеты — на странице «Экзамен»; учебный план — на вкладке «Учебный план».
Типичные темы SQL: подзапросы, JOIN, GROUP BY, EXISTS, NULL, VIEW.
UniversityDB отличается от OLAP-отчёта?Итог. Курс связал проектирование, SQL, надёжность и аналитику. Перед экзаменом пройдите учебный план, страницу экзамена (контрольные вопросы + билеты) и повторите ЛР №1–24 на UniversityDB.
Дата: 15.09.2026, 19:30–21:05, ауд. 102 · Отчёт: скриншоты + скрипт lab01_FIO.sql (ФИО латиницей).
Цель: впервые открыть SQL Server Management Studio (SSMS), подключиться к серверу в классе, разобраться с системными и пользовательскими базами, создать UniversityDB.
SQL Server Management Studio (SSMS) в меню Пуск — Microsoft SQL Server Tools.
(local), .\SQLEXPRESS, ИМЯ-ПК\SQLEXPRESS).
Рисунок 1. Окно Connect to Server в SSMS.
master, model, msdb, tempdb.master и tempdb.UniversityDB или базы других групп.
Рисунок 2. Узел System Databases в Object Explorer (скриншот SSMS).
Если база UniversityDB уже есть от прошлой попытки — согласуйте с преподавателем: использовать её или создать UniversityDB_Фамилия.
UniversityDB, OK.UniversityDB появилась.UniversityDB — Properties — вкладка Files: запишите путь к файлам .mdf и .ldf.
Создание базы: New Database… или CREATE DATABASE.
Рисунок 3. Свойства базы — путь к файлам .mdf и .ldf (вкладка Files).
UniversityDB.lab01_FIO.sql (ФИО латиницей).На всех лабораторных имя файла: labNN_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab01_IvanovII.sql.
Окно New Query, выбор базы, команды SELECT.
Рисунок 4. Результат выполнения запроса в панели Results.
SELECT name, database_id, create_date FROM sys.databases ORDER BY name; — найдите в списке свою UniversityDB.UniversityDB отличается от файла Excel с тем же списком студентов.lab01_FIO.sql (ФИО латиницей), но после CREATE DATABASE?Дата: 16.09.2026, ср, 19:30–21:05, ауд. 104 · Отчёт: скрипт lab02_FIO.sql (ФИО латиницей) + скриншоты результатов запросов.
Цель: в уже созданной на ЛР №1 пустой базе UniversityDB создать таблицы учебного эталона, загрузить данные и выполнить первые запросы SELECT.
UniversityDB → Tables. Список пользовательских таблиц должен быть пуст (или только системные).UniversityDB, выполните:Если базы нет — вернитесь к ЛР №1 или выполните CREATE DATABASE UniversityDB;.
Готовые команды CREATE TABLE и INSERT — на странице Приложение: БД и скрипты, раздел «Сборка базы по шагам». Там же объяснено, что такое SQL-скрипт и зачем он разбит на блоки.
На этой лабораторной вы не скачиваете файл — копируете блоки в окно запроса и сохраняете свою версию как lab02_FIO.sql (ФИО латиницей).
| Блок в приложении | Нужен на ЛР №2? | Что делает |
|---|---|---|
| 1. База данных | частично | Достаточно USE UniversityDB; — база уже есть |
| 2. Очистка таблиц | нет* | Только если таблицы уже создавали и нужно начать заново |
| 3. UNIVERSITY, SUBJECT | да | Справочники без внешних ключей — создаются первыми |
| 4. STUDENT, LECTURER | да | Строки ссылаются на вуз через UNIVERSITY_ID |
| 5. EXAM_MARKS, SUBJ_LECT, ORG_UNIT | да | Оценки и связи; на FK ссылаются на таблицы из блоков 3–4 |
| 6. INSERT | да | Эталонные данные — порядок 6.1 → 6.7, как в приложении |
* Если на прошлой попытке таблицы уже есть — выполните блок 2, затем блоки 3–6 заново.
UniversityDB.UniversityDB → Tables должны появиться семь таблиц.dbo.STUDENT → Design — видны столбцы STUDENT_ID, UNIVERSITY_ID, значок ключа у PK и FK.CREATE TABLE завершился ошибкой «foreign key» — вы, скорее всего, перепутали порядок блоков. Сначала родитель (UNIVERSITY), потом дочерние таблицы.Вставляйте блоки 6.1 → 6.7 по порядку из приложения (сначала вузы и предметы, в конце — подразделения). Можно выполнить весь блок 6 целиком или по частям — главное не нарушать порядок таблиц.
Контрольная проверка:
В ответе должно быть 19 студентов и 8 вузов. Сохраните скриншот результата для отчёта.
SELECT читает данные из таблиц; он ничего не меняет. Выполните запросы ниже по очереди, результаты — в отчёт.
Звёздочка * означает «все столбцы строки»:
В результате — 8 строк, столбцы UNIVERSITY_ID, UNIVERSITY_NAME, RATING, CITY.
Список столбцов через запятую — это проекция (выбор нужных полей):
Условие WHERE отбирает строки. Номер 10 — это ВГУ в эталонных данных:
В списке столбцов сначала NAME (имя), затем SURNAME (фамилия) — как требуется в задании.
Агрегатная функция COUNT(*) считает строки. Для эталона ответ снова 19.
Окно New Query: сверху выбрана база UniversityDB, ниже — текст SQL.
Результат SELECT — на вкладке Results.
lab02_FIO.sql (ФИО латиницей): команды USE, все CREATE TABLE, все INSERT и все SELECT из этой работы.-- ЛР №2, IvanovII, группа ВО-ИСИТ-31 (подставьте свои фамилию и инициалы латиницей).COUNT(*), один из запросов из §4.CHECK (стипендия ≥ 0, курс 1–6, оценка 2–5). Выполните заведомо неверный INSERT, например студента с KURS = 9, и прочитайте текст ошибки.UNIVERSITY_ID = 999. СУБД должна отклонить строку — нет такого вуза, сработал внешний ключ.dbo.EXAM_MARKS и найдите студента без оценок (STUDENT_ID = 19). Эта строка специально нужна для заданий с IS NULL на следующих лабораторных.UniversityDB после ЛР №1 отличается от той же базы после этой работы?UNIVERSITY создают раньше, чем STUDENT?SELECT * FROM UNIVERSITY и чем он отличается от SELECT UNIVERSITY_NAME, CITY FROM UNIVERSITY?INSERT студента с несуществующим UNIVERSITY_ID?lab02_FIO.sql (ФИО латиницей), если база уже создана на сервере?Дата: 22.09.2026, вт, 16:00–17:35, ауд. 112 · Отчёт: скрипт lab03_FIO.sql (ФИО латиницей) + скриншоты ошибок ограничений.
Цель: спроектировать отдельную базу «Библиотека», создать таблицы с ограничениями PRIMARY KEY, UNIQUE, CHECK, FOREIGN KEY, загрузить данные и убедиться, что СУБД отклоняет неверные строки.
Связь с лекцией 3: три таблицы — три сущности без лишних повторов (автор, книга, экземпляр). После работы ответьте, какие нормальные формы выполняет схема.
UniversityDB с ЛР №2 должна остаться нетронутой — на этой работе создаётся новая база Lab03_Library.DROP DATABASE UniversityDB и не пересоздавайте таблицы учебного эталона — они понадобятся на следующих лабораторных.Команда CREATE DATABASE создаёт пустой контейнер для таблиц. Пакет GO завершает пакет команд (как на ЛР №1).
В результате последнего запроса должно быть Lab03_Library. Обновите Object Explorer (F5) — база появится в списке.
Три таблицы связаны цепочкой: у книги один автор, у экземпляра одна книга. Создавайте таблицы в этом порядке — иначе внешний ключ не найдёт родительскую таблицу.
| Таблица | Назначение | Ключевые ограничения |
|---|---|---|
AUTHOR | Авторы | author_id — PK; name — NOT NULL |
BOOK | Книги (издания) | book_id — PK; isbn — UNIQUE; год издания — CHECK; author_id — FK |
COPY | Экземпляры на полке | copy_id — PK; inventory_no — UNIQUE; status — CHECK и DEFAULT; book_id — FK с CASCADE |
Столбец pub_year — год издания; CHECK не допускает «1300» и будущие годы.
ON DELETE CASCADE: при удалении книги СУБД удалит все её экземпляры. status: in — на полке, out — выдан читателю.
После выполнения проверьте Object Explorer: под Lab03_Library → Tables — три таблицы.
Сначала авторы, затем книги, затем экземпляры — как при загрузке UniversityDB на ЛР №2.
Можете добавить свои строки (минимум 3–5 в каждой таблице). Проверка:
Выполните команды ниже по одной. Каждая должна завершиться ошибкой — это ожидаемый результат. Сохраните текст ошибки или скриншот для отчёта.
Нарушение UNIQUE на isbn.
Нарушение CHECK на pub_year.
Нарушение CHECK на status — допустимы только in и out.
Нарушение внешнего ключа — автора с author_id = 999 нет.
Кратко ответьте в комментарии в lab03_FIO.sql или в сопроводительном тексте:
AUTHOR, а не копируется в каждую строку COPY)Ожидаемый вывод: схема из трёх таблиц в 1НФ и 3НФ; разделение убирает аномалии обновления (смена имени автора — одна строка в AUTHOR).
lab03_FIO.sql (ФИО латиницей): CREATE DATABASE, USE, все CREATE TABLE, все успешные INSERT, контрольные SELECT COUNT.INSERT из §4 можно оставить в файле закомментированными (-- в начале строки) с пометкой «ожидаемая ошибка».-- ЛР №3, IvanovII, группа ВО-ИСИТ-31.Lab03_Library, а не изменения в UniversityDB?BOOK создают после AUTHOR, а COPY — после BOOK?PRIMARY KEY отличается от UNIQUE на примере isbn и book_id?ON DELETE CASCADE при удалении строки из BOOK?AUTHOR?Дата: 23.09.2026, ср, 12:30–14:05, ауд. 205 · Отчёт: скрипт lab04_FIO.sql (ФИО латиницей) + скриншоты из §1–5.
Цель: изменить существующую схему UniversityDB командами ALTER TABLE, добавить индексы, поработать с пакетами GO и убедиться, что ограничения FK и UNIQUE работают.
Связь с лекцией 4: схема живёт на общем сервере; ваш ALTER TABLE видят все сеансы. Внешние ключи с ЛР №2 защищают ссылки; сегодня добавляете столбец и индексы без пересоздания таблиц.
UniversityDB → Tables — должны быть семь таблиц после ЛР №2.UniversityDB, выполните контроль:Ожидается: 19 студентов и непустая таблица оценок. Если база пуста — повторите ЛР №2 (блоки приложения 3–6).
DROP DATABASE и не трогайте чужие базы на общем сервере.
Object Explorer: под UniversityDB → Tables — STUDENT, UNIVERSITY, …
На ЛР №2 таблицы создавали через CREATE TABLE. В живой системе схему чаще дополняют — так деканат добавляет поле «email» без пересоздания таблицы и без потери 19 строк.
dbo.STUDENT → Design — в списке столбцов появился EMAIL, тип varchar(100), Allow Nulls = да.student<STUDENT_ID>@edu.local:Конкретный запрос SELECT и ожидаемый фрагмент результата:
| STUDENT_ID | SURNAME | |
|---|---|---|
| 1 | … | student1@edu.local |
| 2 | … | student2@edu.local |
| … | … | … |
Фамилии возьмутся из вашего эталона; важны столбец EMAIL и шаблон адреса. Сделайте скриншот вкладки Results.
Окно New Query: сверху выбрана UniversityDB, ниже — ALTER и UPDATE.
Результат SELECT TOP 5 … EMAIL — приложите к отчёту.
UNIQUE запрещает два одинаковых значения в столбце (кроме NULL — в SQL Server несколько NULL в UNIQUE допустимы, но у вас все EMAIL заполнены).
Теперь намеренно нарушите правило — скопируйте адрес студента 1 студенту 2:
Ожидаемо: выполнение прервётся, на вкладке Messages текст вроде:
Сохраните скриншот вкладки Messages — это доказательство работы ограничения. Верните уникальные значения:
Если бы вы добавляли столбец UNIVERSITY_ID вместо EMAIL, FK не дал бы записать несуществующий вуз. Проверка (ожидается ошибка):
Индекс — отдельная структура для быстрого поиска по столбцу. На ЛР №5–6 вы часто будете писать WHERE CITY = … и WHERE UNIVERSITY_ID = … AND KURS = … — под такие фильтры индексы уместны.
Clustered индекс один на таблицу (обычно PK); nonclustered — дополнительные «указатели» к строкам.
В результате должны быть как минимум:
| index_name | type_desc | is_unique | Комментарий |
|---|---|---|---|
| PK__STUDENT… | CLUSTERED | 1 | первичный ключ |
| UQ_STUDENT_EMAIL | NONCLUSTERED | 1 | ваше UNIQUE |
| IX_STUDENT_CITY | NONCLUSTERED | 0 | создали в §3 |
| IX_STUDENT_UNIV_KURS | NONCLUSTERED | 0 | составной индекс |
Точное имя PK может отличаться — смотрите столбец index_name.
GO — не команда T-SQL, а разделитель пакетов в SSMS. Переменная, объявленная в одном пакете, не видна в следующем.
Ожидаемый результат второго пакета: students = 19.
Эксперимент: уберите оба GO и выполните скрипт целиком. Вторая строка DECLARE @cnt в том же пакете даст ошибку «имя переменной уже объявлено» или конфликт с первым пакетом — зафиксируйте текст ошибки в отчёте.
Cannot find object STUDENT — выполните USE UniversityDB;. Если столбец EMAIL уже добавлен — пропустите §1 или согласуйтесь с преподавателем. Повторный CREATE INDEX даст ошибку — индекс уже есть.lab04_FIO.sql (ФИО латиницей): USE, все ALTER, UPDATE, CREATE INDEX, SELECT из sys.indexes, скрипт с GO.-- ЛР №4, IvanovII, группа ВО-ИСИТ-31 (подставьте свои фамилию и инициалы латиницей).EMAIL и индексы для ЛР №5+ или удалить в конце скрипта:Имя файла отчёта: lab04_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab04_IvanovII.sql.
EXEC sp_helpindex 'dbo.STUDENT'; — сравните вывод с sys.indexes.IF NOT EXISTS (на курсе достаточно комментария).ALTER TABLE ADD безопаснее, чем «удалить STUDENT и создать заново».ALTER TABLE ADD отличается от повторного CREATE TABLE STUDENT?GO?sys.indexes отличить clustered и nonclustered индекс?Дата: 29.09.2026, вт, 14:15–15:50, ауд. 210 · Отчёт: скрипт lab05_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: выполнить выборку с проекцией (список столбцов) и селекцией (WHERE): сравнение, AND/OR/NOT, IN, BETWEEN, LIKE, IS NULL на UniversityDB.
Связь с лекцией 2: вы уже делали простые SELECT на ЛР №2; здесь — систематическая работа с фильтрами. Справочник таблиц и эталонные данные — в приложении.
UniversityDB.EMAIL — он не мешает; все запросы ниже работают и без него.Ожидается: 19 студентов, 24 строки в EXAM_MARKS, 8 предметов в SUBJECT (см. приложение).
Перед работой убедитесь, что в списке баз выбрана UniversityDB.
Проекция — какие столбцы показать. Селекция — какие строки отобрать (WHERE, §2–4).
Ожидается 8 строк, столбцы SUBJ_ID, SUBJ_NAME, HOUR, SEMESTER.
SUBJ_ID = 10)В эталоне — несколько строк (оценки разных студентов). В комментарии к скрипту укажите -- rows: N.
Ожидается 19 строк. Звёздочка * здесь не нужна — вы явно перечисляете столбцы отчёта.
Выполняйте запросы по одному. После каждого — запишите число строк (rows в углу Results или SELECT COUNT(*) … с тем же WHERE).
Ожидается 1 строка — «История» (SUBJ_ID = 56).
Ожидается 4 строки (56, 72, 56, 56 часов в эталоне).
Ожидается 6 вузов (рейтинг 410, 450, 470, 580, 650, 700).
Пример результата с фильтром — приложите один такой скриншот к отчёту.
Буква N перед строкой — Unicode для кириллицы.
Без скобок AND связывал бы только KURS = 2 со стипендией — логика изменилась бы.
% — любое продолжение. Укажите в комментарии, сколько строк вернулось.
Ожидается 1 строка — STUDENT_ID = 19 (специально для этой проверки).
Сохраните скриншот: сравнение «0 строк» и «1 строка» — хороший фрагмент отчёта.
| Ошибка | Что проверить |
|---|---|
| 0 строк там, где ждали данные | Выбрана ли UniversityDB; нет ли опечатки в N'Воронеж' |
CITY = NULL | Только IS NULL / IS NOT NULL |
| Фильтр по SEMESTER в STUDENT | Семестр — столбец таблицы SUBJECT, не студента |
Забыли dbo. | На учебном сервере лучше явно: dbo.STUDENT |
lab05_FIO.sql (ФИО латиницей).-- ЛР №5, IvanovII, группа ВО-ИСИТ-31 (подставьте свои фамилию и инициалы латиницей).-- rows: N с числом строк результата.= NULL и IS NULL из §4.3.Имя файла отчёта: lab05_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab05_IvanovII.sql.
SELECT * FROM dbo.STUDENT WHERE NOT (KURS < 3); — сравните с KURS >= 3.UNIVERSITY_ID = 10) с стипендией выше средней по этому вузу (подсказка: подзапрос — ЛР №9).SELECT не меняет данные и не требует ROLLBACK (в отличие от ЛР №6).SELECT?SEMESTER относится к таблице SUBJECT, а не STUDENT?LIKE N'С%' и зачем буква N?IS NULL отличается от = NULL?lab05_FIO.sql (ФИО латиницей), если результат виден на экране?Дата: 30.09.2026, ср, 12:30–14:05, ауд. 210 · Отчёт: скрипт lab06_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: изменять данные (DML), сортировать выборку, использовать TOP и DISTINCT; безопасно экспериментировать в транзакции с ROLLBACK (лекция 5).
Связь с лекцией 5–6: на общем сервере незафиксированные UPDATE/DELETE видят другие сеансы — поэтому учебные изменения только с откатом.
UPDATE, INSERT и DELETE ниже выполняйте внутри BEGIN TRAN … ROLLBACK. Не нажимайте COMMIT, пока не согласовали с преподавателем.Ожидается 19 студентов. Запишите число оценок — после всех ROLLBACK оно должно совпасть.
ORDER BY сортирует результат; TOP n ограничивает число строк (аналог LIMIT в других СУБД). DISTINCT убирает дубликаты в выборке.
Вверху списка — студенты с наибольшей стипендией. Скриншот для отчёта.
Ровно 5 строк (если в таблице ≥ 5 студентов).
В первом запросе — уникальные оценки (2–5); во втором — уникальные пары «курс + город».
Результат TOP 5 … ORDER BY STIPEND DESC — приложите к отчёту.
Сначала «пробные» строки — затем откат. Порядок: родитель UNIVERSITY, потом дочерний STUDENT (FK).
INSERT … SELECT вставляет строку, вычисленную запросом (здесь — рейтинг выше текущего максимума).
Перед изменением — SELECT с тем же WHERE; после UPDATE — повторный SELECT; в конце — ROLLBACK.
После ROLLBACK у студента 15 снова должен быть исходный UNIVERSITY_ID из эталона.
После отката последний COUNT совпадает с первым — двойки (если были) на месте.
Нельзя удалить вуз, пока на него ссылаются студенты. Сначала проверьте ошибку:
Правильный порядок внутри транзакции: сначала DELETE студентов, потом вуза.
| Ошибка | Что делать |
|---|---|
| Случайный COMMIT | На учебном сервере — только ROLLBACK; пересоздайте эталон с преподавателем |
| UPDATE без WHERE | Сначала SELECT с тем же условием — убедитесь, что трогаете нужные строки |
| DELETE родителя раньше ребёнка | Сначала дочерние строки или CASCADE (если задан) |
| Забыли ROLLBACK | SELECT @@TRANCOUNT; — если > 0, выполните ROLLBACK |
lab06_FIO.sql (ФИО латиницей).-- ЛР №6, IvanovII, группа ВО-ИСИТ-31.SELECT COUNT(*) FROM dbo.STUDENT; = 19.Имя файла отчёта: lab06_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab06_IvanovII.sql.
SELECT TOP 5 PERCENT STIPEND, … ORDER BY STIPEND DESC; — чем отличается от TOP 5?UPDATE с заведомо неверным CHECK (KURS = 9) внутри TRY/CATCH (ЛР №16).ORDER BY пишут после WHERE?ROLLBACK после демонстрационного UPDATE на общем сервере?INSERT … SELECT отличается от INSERT … VALUES?DELETE вуза без удаления студентов вызывает ошибку FK?Дата: 06.10.2026, вт, 12:30–14:05, ауд. 220 · Отчёт: скрипт lab07_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: использовать COUNT, SUM, AVG, MIN, MAX; понять, как NULL влияет на агрегаты; сверить ответы с эталоном из приложения.
Связь с курсом: на лекции 2 вы делали простые SELECT; здесь одна строка результата суммирует много строк таблицы. На ЛР №8 добавится GROUP BY — группы вместо «всей таблицы сразу».
Напоминание: все агрегаты, кроме COUNT(*), игнорируют строки, где аргумент равен NULL.
Ожидается: 19 студентов, 24 оценки, 8 предметов. Если числа другие — восстановите эталон (ЛР №2, блок 6 приложения).
COUNT(*) считает строки. COUNT(столбец) не учитывает NULL в этом столбце. COUNT(DISTINCT …) — число различных значений (NULL не входит).
Ожидается: 19, 18, 8. У студента STUDENT_ID = 19 поле CITY специально NULL — поэтому COUNT(CITY) на 1 меньше, чем COUNT(*).
В комментарии к скрипту запишите: -- all_rows: 19; with_city: 18; distinct_cities: 8.
Ожидается: min_st = 0, max_st = 250, avg_st ≈ 122.89 (среднее по всем 19, включая нулевые стипендии). Во втором запросе среднее только по студентам с STIPEND > 0 — ≈ 155.67 (15 строк).
Обратите внимание: нули в данных — не NULL; они участвуют в AVG первого запроса и занижают среднее.
Выполняйте запросы по одному; после каждого сверяйте результат с эталоном.
Ожидается: total_hours = 382 (сумма часов восьми предметов); min_rating = 320 (БГУ), max_rating = 700 (МГУ).
Ожидается: avg_mark ≈ 4.08; 9 пятёрок; 1 двойка; первая дата 2026-01-15, последняя 2026-06-12.
CAST(MARK AS FLOAT) нужен, чтобы среднее было дробным, а не целым от деления типа INT.
Пример вкладки Results для блока §3 — одна строка с несколькими агрегатами. Сделайте скриншот для отчёта.
В эталоне у всех 24 строк поле MARK заполнено — оба счётчика дают 24, разница 0. Это нормально: NULL в оценках зарезервирован для других заданий; здесь вы фиксируете, что COUNT(MARK) и COUNT(*) совпали.
Для строк с NULL смотрите §1: COUNT(CITY) vs COUNT(*) у STUDENT.
lab07_FIO.sql (ФИО латиницей).-- ЛР №7, IvanovII, группа ВО-ИСИТ-31.AVG и CAST.Имя файла отчёта: lab07_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab07_IvanovII.sql.
SELECT COUNT(*), COUNT(STIPEND) FROM dbo.STUDENT; — совпадут ли счётчики? Почему?SELECT AVG(CAST(STIPEND AS FLOAT)) FROM dbo.STUDENT WHERE KURS = 1; — посчитайте вручную для первого курса (подготовка к GROUP BY на ЛР №8).AVG(STIPEND) по всей таблице и среднее «только по получающим стипендию»?COUNT(CITY) меньше COUNT(*) у STUDENT?AVG(STIPEND) по всей таблице отличается от AVG при STIPEND > 0?CAST(MARK AS FLOAT) перед AVG?COUNT(MARK), если в столбце есть NULL?MIN/MAX по EXAM_DATE вы получили и что это означает для учебного семестра?Дата: 06.10.2026, вт, 14:15–15:50, ауд. 220 · Отчёт: скрипт lab08_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: группировать строки (GROUP BY), отбирать группы через HAVING, строить итоги GROUP BY ROLLUP в SQL Server.
Связь с ЛР №7: там агрегаты считали по всей таблице; здесь — отдельно по каждому курсу, городу, предмету. Справочник эталона — в приложении.
Правило SQL: каждый столбец в SELECT должен быть либо в GROUP BY, либо внутри агрегатной функции (COUNT, AVG, …).
Ожидается 19 студентов. Если база пуста — повторите ЛР №2.
GROUP BY делит строки на группы с одинаковым значением столбца; агрегат считается внутри каждой группы.
Ожидается 5 строк (курсы 1–5). Пример значений: курс 1 — 6 студентов, средняя стипендия 135.00; курс 2 — 4 студента, 167.50; курс 3 — 4, 96.25; курс 4 — 3, 120.00; курс 5 — 2, 55.00.
Групп с заполненным городом — 8; отдельная группа с CITY IS NULL (студент 19) — 1 строка. Чаще всего встречаются Воронеж и Москва (по 4 студента).
Ожидается 8 групп (вузы 10, 11, 12, 14, 15, 18, 22, 32). Например: UNIVERSITY_ID = 10 — 5 студентов, средняя стипендия ≈ 95.00; 22 (МГУ) — 4 студента, ≈ 102.50.
Результат GROUP BY KURS — несколько строк вместо одной сводки с ЛР №7.
Ожидается 7 предметов с оценками. Примеры: SUBJ_ID = 10 — 8 экзаменов, средний ≈ 4.00; 43 — 2 экзамена, средний 5.00; 22 — 4 экзамена, средний 3.50.
WHERE отбирает строки до группировки; HAVING — группы после агрегации (можно использовать условие на COUNT(*), AVG, …).
Ожидается 3 строки: курсы 1 (6), 2 (4), 3 (4). Курсы 4 и 5 отсеялись — в группе ≤ 3 студента.
Ожидается 6 предметов: 10, 18, 31, 43, 56, 94. Предмет 22 (средний 3.50) в список не попадает.
Сначала отбрасываются нулевые стипендии, затем считается среднее по оставшимся в группе. Пример: курс 1 — среднее ≈ 162.00 (5 студентов с ненулевой стипендией), курс 4 — 180.00 (студент 6 с нулём не участвует).
Если написать HAVING AVG(STIPEND) > 0 вместо WHERE STIPEND > 0, нули всё равно войдут в расчёт среднего внутри группы — результат будет другим. Это частая ошибка на защите.
ROLLUP добавляет строку с KURS IS NULL — итог по всей таблице: cnt = 19, avg_st ≈ 122.89 (как на ЛР №7 без группировки). Строки с числом в KURS — группы по курсам из §1.1.
lab08_FIO.sql (ФИО латиницей).-- ЛР №8, IvanovII, группа ВО-ИСИТ-31.GROUP BY KURS; HAVING COUNT(*) > 3; ROLLUP с итоговой строкой NULL.Имя файла отчёта: lab08_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab08_IvanovII.sql.
GROUP BY KURS, CITY — сколько групп получится? Сравните с группировкой только по KURS.SELECT KURS, SURNAME, COUNT(*) FROM STUDENT GROUP BY KURS вызывает ошибку?WITH ROLLUP к запросу §3.2 — что изменится в результате?Дата: 06.10.2026, вт, 16:00–17:35, ауд. 220 · Отчёт: скрипт lab09_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: писать скалярные подзапросы, использовать IN и NOT IN; понять, почему NOT IN опасен при NULL в подзапросе.
Связь с ЛР №8: там вы считали агрегаты с GROUP BY; здесь тот же MAX/AVG спрятан внутри WHERE — подзапрос возвращает одно значение для сравнения с каждой строкой внешнего запроса.
Ожидается 19 студентов.
Скалярный подзапрос возвращает одно значение (одну строку, один столбец). Его ставят в WHERE после =, >, < и т.д. Если вернётся больше одной строки — ошибка.
Ожидается 1 строка: Морозова, стипендия 250 (STUDENT_ID = 7).
Средняя по ненулевым ≈ 155.67. Ожидается 7 строк (Сидорова, Козлова, Морозова, Соколова, Зайцева, Лебедева, Крылова).
Средний рейтинг ≈ 496.25. Ожидается 3 вуза: НГУ (580), СПбГУ (650), МГУ (700).
Результат §1.1 — одна строка с максимальной стипендией.
IN (подзапрос) проверяет, входит ли значение во множество строк подзапроса. Эквивалентно нескольким OR, но короче и читабельнее.
В эталоне в Москве только МГУ (UNIVERSITY_ID = 22). Ожидается 4 студента (Сидорова, Сидоров, Кузнецов, Лебедева).
Предмет SUBJ_ID = 10 (Информатика). Ожидается 8 строк в EXAM_MARKS по этому предмету.
Тот же результат можно получить через JOIN — на ЛР №11 сравните оба стиля.
NOT IN исключает строки, попадающие в список подзапроса. Важно: если подзапрос вернёт хотя бы один NULL, результат внешнего запроса может стать пустым (логика трёхзначная). Поэтому в подзапросе часто пишут WHERE столбец IS NOT NULL.
В эталоне студенты есть в каждом из 8 вузов — результат 0 строк. Это нормально: запишите в отчёте «пустой результат — все вузы представлены».
Ожидается 1 строка: Медведев (STUDENT_ID = 19) — специально для заданий с NOT EXISTS на ЛР №10.
Ожидается 1 предмет: Физкультура (SUBJ_ID = 73).
WHERE SUBJ_ID IS NOT NULL и в EXAM_MARKS появится строка с SUBJ_ID = NULL, NOT IN может вернуть ноль строк для всех предметов. На ЛР №10 сравните с NOT EXISTS — он NULL не «ломает».lab09_FIO.sql (ФИО латиницей).-- ЛР №9, IvanovII, группа ВО-ИСИТ-31.-- rows: N и краткий вывод.Имя файла отчёта: lab09_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab09_IvanovII.sql.
JOIN с UNIVERSITY — совпали ли строки?WHERE STIPEND > ALL (SELECT STIPEND FROM STUDENT WHERE STIPEND > 0 AND STUDENT_ID <> 7) — кого оставит?SELECT * FROM STUDENT WHERE STUDENT_ID NOT IN (SELECT STUDENT_ID FROM EXAM_MARKS) без фильтра NULL может вести себя странно, если в EXAM_MARKS появится NULL в STUDENT_ID?WHERE должен вернуть ровно одно значение?IN с подзапросом отличается от JOIN?NOT IN опасен, если в подзапросе есть NULL?NOT IN?DISTINCT в подзапросе для UNIVERSITY_ID?Дата: 13.10.2026, вт, 12:30–14:05, ауд. 220 · Отчёт: скрипт lab10_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: писать коррелированные подзапросы; использовать EXISTS, NOT EXISTS, операторы ANY/ALL.
Связь с ЛР №9: там подзапрос был «сам по себе»; здесь внутренний запрос ссылается на строку внешнего (s1.UNIVERSITY_ID) — выполняется заново для каждой строки снаружи.
Внутренний SELECT использует столбец внешней строки (s1.UNIVERSITY_ID, s1.KURS). Для каждого студента заново считается средняя стипендия в его вузе на его курсе.
Ожидается 3 строки: Иванов (ВГУ, 1 курс — выше среднего по группе), Орлов (ЮФУ, 1 курс), Белкин (ВГУ, 3 курс). Нули в знаменателе не мешают — они входят в среднее по группе.
EXISTS (подзапрос) возвращает true, если подзапрос вернул хотя бы одну строку. Часто пишут SELECT 1 — важен факт наличия строк, а не их содержимое.
Ожидается 2 вуза: БГУ (студент 16) и МГУ (студент 10).
В эталоне у каждого вуза есть студенты — результат 0 строк (как NOT IN в ЛР №9).
Ожидается 8 студентов с хотя бы одной «5» (в эталоне — Иванов, Петров, Козлова, Волков, Кузнецов, Лебедева, Крылова и др.).
Ожидается 1 строка: Медведев (STUDENT_ID = 19) — тот же результат, что NOT IN на ЛР №9, но без ловушки NULL.
Результат §3 — один студент без оценок.
Строки, где оценка максимальна для своего предмета. Ожидается 12 строк (несколько «лучших» по предметам 10, 43, 56, 94 и т.д.). Если для предмета одна оценка — она тоже «максимальна».
Если подзапрос после ALL пуст (нет оценок по предмету), условие для внешней строки не выполняется — такие строки не попадут в результат.
lab10_FIO.sql (ФИО латиницей).-- ЛР №10, IvanovII, группа ВО-ИСИТ-31.-- rows: N и пояснение корреляции или EXISTS.Имя файла отчёта: lab10_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab10_IvanovII.sql.
LEFT JOIN … WHERE em.STUDENT_ID IS NULL.IN vs EXISTS для §2.1 — кратко в комментарии.WHERE STIPEND > ANY (SELECT …) — чем отличается от > ALL?s1.UNIVERSITY_ID?Дата: 20.10.2026, вт, 14:15–15:50, ауд. 220 · Отчёт: скрипт lab11_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: соединять таблицы через INNER JOIN и LEFT JOIN; строить отчёты по связям FK; считать агрегаты после JOIN.
Связь с ЛР №9–10: подзапрос с IN можно заменить JOIN — на этой работе учитесь читать и писать явные соединения. Схема FK — в приложении.
Нарисуйте цепочку: UNIVERSITY ← STUDENT → EXAM_MARKS → SUBJECT; отдельно SUBJ_LECT связывает SUBJECT и LECTURER. Условие соединения — равенство ключей FK.
INNER JOIN оставляет только строки, для которых есть пара в обеих таблицах. У каждого студента в эталоне есть вуз — потерь строк не будет.
Ожидается 19 строк — по числу студентов.
Ожидается 13 строк (студенты вузов в Москве, СПб, Новосибирске и т.д.; вузы ВГУ и ВГМУ в Воронеже отсеяны).
Ожидается 24 строки — все строки EXAM_MARKS с подставленными фамилиями и названиями предметов.
Ожидается 12 строк — по таблице SUBJ_LECT в приложении.
К отчёту приложите свой скриншот вкладки Results для запроса §2.1 (ожидается 24 строки: фамилия, предмет, оценка, дата).
LEFT JOIN сохраняет все строки левой таблицы; если справа нет пары — столбцы справа NULL.
Ожидается 19 строк с фамилиями (у каждого вуза есть студенты; «пустых» вузов нет).
В эталоне — 0 строк. Запишите в отчёте: «все 8 вузов представлены студентами».
Ожидается 1 строка: Медведев (STUDENT_ID = 19) — тот же результат, что NOT EXISTS на ЛР №10.
Ожидается 8 строк. Используйте COUNT(s.STUDENT_ID), а не COUNT(*) — иначе вуз без студентов дал бы 1 вместо 0 (в эталоне все счётчики ≥ 1).
Только студенты с оценками; у Медведева строки не будет. Число строк — 18 (19 − 1 без ведомости).
lab11_FIO.sql или приложите схему отдельно в PDF.-- ЛР №11, IvanovII, группа ВО-ИСИТ-31.Имя файла отчёта: lab11_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab11_IvanovII.sql.
IN (ЛР №9) — совпали ли строки?RIGHT JOIN отличается от LEFT JOIN (поменяли таблицы местами)?ON (декартово произведение).Дата: 21.10.2026, ср, 12:30–14:05 · Отчёт: скрипт lab12_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: объединять результаты нескольких SELECT; понять разницу UNION и UNION ALL; применить множественные операции к эталону UniversityDB.
Связь с ЛР №11: JOIN соединяет таблицы в одном запросе; UNION складывает результаты двух запросов с одинаковым числом столбцов.
В эталоне: 19 студентов, 10 преподавателей, 24 строки EXAM_MARKS; у Медведева (STUDENT_ID=19) нет оценок.
Средний балл по студенту с названием вуза — закрепление ЛР №11.
Ожидается 19 строк; у Медведева avg_mark = NULL.
Ожидается 29 строк (19 студентов + 10 преподавателей).
INTERSECT — 7 городов (Воронеж, Москва, Новосибирск, Санкт-Петербург, Белгород, Томск, Ростов-на-Дону). EXCEPT — 1 строка: Курск (есть у студентов, нет среди городов вузов).
Повторите §2 с UNION вместо UNION ALL. В эталоне фамилии студентов и преподавателей не пересекаются — снова 29 строк. Запишите в отчёте: UNION удаляет дубликаты между двумя наборами; UNION ALL — нет.
Только предметы с не менее двух оценок. Ожидается до 5 строк — зафиксируйте фактическое число и значения avg_mark в комментарии -- rows: N.
lab12_FIO.sql.-- ЛР №12, IvanovII, группа ВО-ИСИТ-31.Имя файла отчёта: lab12_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab12_IvanovII.sql.
Дата: 27.10.2026, вт, 14:15–15:50 · Отчёт: скрипт lab13_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: строковые и дата-функции T-SQL, ROUND, CAST на UniversityDB.
Первый запрос — 19 строк. LEN(SURNAME)=6 — 8 студентов: Петров, Козлова, Новиков, Сидоров, Волков, Павлов, Белкин, Крылова.
Ожидается 16 экзаменов в январе 2026 (все даты EXAM_MARKS в эталоне — 2026 год).
По каждому курсу — одна строка агрегата (курсы 1–4 в эталоне).
Ожидается 8 строк — по числу вузов.
lab13_FIO.sql.-- ЛР №13, IvanovII, группа ВО-ИСИТ-31.Имя файла отчёта: lab13_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab13_IvanovII.sql.
Дата: 28.10.2026, ср, 12:30–14:05 · Отчёт: скрипт lab14_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: условные выражения и обработка NULL в SELECT; студент STUDENT_ID=19 (Медведев) с CITY IS NULL.
Ожидается 1 строка: STUDENT_ID=19, Медведев, CITY = NULL.
Ожидается 24 строки — все записи ведомости.
Ожидается 19 строк — по каждому студенту.
У Медведева в обоих запросах — не указан вместо NULL.
Во втором запросе Медведев с NULL — в конце списка.
Ожидается 4 строки — по числу категорий стипендии.
lab14_FIO.sql.-- ЛР №14, IvanovII, группа ВО-ИСИТ-31.Имя файла отчёта: lab14_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab14_IvanovII.sql.
Дата: 03.11.2026, вт, 14:15–15:50 · Отчёт: скрипт lab15_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: объявление переменных DECLARE/SET, ветвление IF/ELSE, проверка IF EXISTS в T-SQL.
При @kurs = 3 ожидается 4 студента.
Результат PRINT — на вкладке Messages в SSMS.
Ожидается сообщение «Есть студенты без экзаменов» (Медведев, STUDENT_ID=19).
lab15_FIO.sql.-- ЛР №15, IvanovII, группа ВО-ИСИТ-31.Имя файла отчёта: lab15_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab15_IvanovII.sql.
Дата: 04.11.2026, ср, 12:30–14:05 · Отчёт: скрипт lab16_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: цикл WHILE, обработка ошибок TRY/CATCH, транзакция с откатом.
Ожидается 10 строк — числа от 1 до 10.
Ожидается строка с err_num (нарушение FK) — без изменения данных.
Оценка 6 вне диапазона CHECK — попадание в CATCH, строка не вставляется.
При успехе стипендии студентов 1 и 3 не меняются в сумме; при ошибке — ROLLBACK.
lab16_FIO.sql.-- ЛР №16, IvanovII, группа ВО-ИСИТ-31.Имя файла отчёта: lab16_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab16_IvanovII.sql.
Дата: 10.11.2026, вт, 14:15–15:50 · Отчёт: скрипт lab17_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: тип XML, методы .value() и .query(); связь с лекциями 9–10.
Ожидается 1 строка в UnivXml для univ_id=10 (ВГУ).
Ожидается название ВГУ и город Воронеж.
Во втором запросе — 2 строки (Иванов, Петров из XML).
Если права позволяют:
Иначе в отчёте опишите: индекс ускоряет XPath-запросы к большим документам.
lab17_FIO.sql.-- ЛР №17, IvanovII, группа ВО-ИСИТ-31.Имя файла отчёта: lab17_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab17_IvanovII.sql.
Дата: 11.11.2026, ср, 12:30–14:05 · Отчёт: скрипт lab18_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: рекурсивный CTE по таблице ORG_UNIT в UniversityDB; сравнение adjacency list и nested sets.
В эталоне 10 строк в ORG_UNIT (иерархии ВГУ и МГУ).
От корня UNIT_ID=1 (ВГУ) ожидается 7 строк — всё поддерево вуза 10.
Столбец lvl — уровень вложенности (0 у ректората, 1 у факультетов и т.д.).
Кратко сравните adjacency list (PARENT_ID, как в ORG_UNIT) и nested sets (left/right): плюсы и минусы каждой модели.
lab18_FIO.sql.-- ЛР №18, IvanovII, группа ВО-ИСИТ-31.Имя файла отчёта: lab18_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab18_IvanovII.sql.
Дата: 17.11.2026, вт, 14:15–15:50 · Отчёт: скриншоты Compass + lab19_FIO.pdf (ФИО латиницей).
Цель: документная модель в MongoDB Compass; сравнение с реляционной строкой dbo.STUDENT.
Стенд: MongoDB Compass на учебном ПК (или MongoDB Atlas по указанию преподавателя). SQL Server для сравнения — UniversityDB.
University и коллекцию students.USE UniversityDB; — данные для документов возьмите из STUDENT + UNIVERSITY.Вставьте минимум пять документов с полями _id, surname, name, kurs, вложенный объект university: { name, city }:
Данные можно взять из:
Ожидается 5 документов в коллекции students.
Зафиксируйте число документов при фильтре kurs: 3 — в эталоне SQL при KURS=3 четыре студента.
После deleteOne документ 99 отсутствует — приложите скриншот.
lab19_FIO.pdf: скриншоты Compass, примеры запросов.STUDENT+JOIN UNIVERSITY.Имя файла отчёта: lab19_FIO.pdf (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab19_IvanovII.pdf.
Дата: 18.11.2026, ср, 12:30–14:05 · Отчёт: скрипт lab20_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: создать представления VIEW на UniversityDB, упростить доступ к JOIN и проверить чтение через представление.
Связь с лекцией 12: VIEW — сохранённый запрос с именем, а не копия таблицы.
VIEW содержит 19 строк — по числу студентов.
Во VIEW — 24 строки; фильтр MARK=5 — 9 пятёрок в эталоне.
Объясните в комментарии к скрипту: WITH SCHEMABINDING защищает определение VIEW от изменения базовых столбцов.
lab20_FIO.sql.-- ЛР №20, IvanovII, группа ВО-ИСИТ-31.v_StudentUniv и v_StudentMarks WHERE MARK=5.Имя файла отчёта: lab20_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab20_IvanovII.sql.
Дата: 24.11.2026, вт, 14:15–15:50 · Отчёт: скрипт lab21_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: создать и вызвать хранимые процедуры на T-SQL, в том числе usp_StudentByKurs из лекции 12.
При @kurs = 3 ожидается 4 студента.
lab21_FIO.sql.-- ЛР №21, IvanovII, группа ВО-ИСИТ-31.Имя файла отчёта: lab21_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab21_IvanovII.sql.
Дата: 01.12.2026, вт, 12:30–14:05 · Отчёт: скрипт lab22_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: создать AFTER-триггер аудита на EXAM_MARKS и INSTEAD OF INSERT на представление v_StudentUniv.
Измените оценку в транзакции с ROLLBACK и проверьте SELECT * FROM dbo.AuditLog; — после ROLLBACK записей аудита не останется.
Объясните в отчёте: VIEW с JOIN не всегда updatable — INSTEAD OF перенаправляет INSERT на базовые таблицы.
lab22_FIO.sql.-- ЛР №22, IvanovII, группа ВО-ИСИТ-31.Имя файла отчёта: lab22_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab22_IvanovII.sql.
Дата: 02.12.2026, ср, 12:30–14:05 · Отчёт: скрипт lab23_FIO.sql (ФИО латиницей) + скриншоты результатов.
Цель: login, user, database role; выдать минимальные права на UniversityDB; связь с лекцией 14.
Подключитесь вторым окном SSMS как reader_test и попробуйте:
Ожидается отказ — нет INSERT на STUDENT (только SELECT через role_read).
После GRANT EXECUTE пользователь reader_test может вызвать процедуру без прямого SELECT на LECTURER.
lab23_FIO.sql.-- ЛР №23, IvanovII, группа ВО-ИСИТ-31.Имя файла отчёта: lab23_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab23_IvanovII.sql.
Дата: 08.12.2026, вт, 14:15–15:50 · Отчёт: lab24_FIO.sql (ФИО латиницей) + защита.
Цель: резервное копирование и восстановление (лекции 13–14) + комплексный практикум по материалам семестра на UniversityDB.
UniversityDB в эталонном состоянии: 19 студентов, 24 оценки..bak на учебном сервере.Если нет прав — приложите скриншоты SSMS и текстовый план RESTORE.
Опишите цепочку FULL / DIFF / LOG backup и когда нужен STOPAT.
Выполните минимум восемь пунктов ниже; каждый — отдельный блок в lab24_FIO.sql с комментарием.
GROUP BY + HAVING (средний балл по предметам).EXISTS (студенты без оценок — ожидается Медведев).CREATE VIEW + SELECT из VIEW.usp_StudentByKurs с @kurs=3 — 4 строки.DROP TRIGGER в конце скрипта).CITY.GRANT/REVOKE или описание, если нет прав.ORG_UNIT от UNIT_ID=1 — 7 строк.dbo.UnivXml (если таблица ещё есть с ЛР №17).lab24_FIO.sql.-- ЛР №24, IvanovII, группа ВО-ИСИТ-31.Имя файла отчёта: lab24_FIO.sql (ФИО латиницей) — вместо FIO подставьте фамилию и инициалы латиницей, например lab24_IvanovII.sql.
UniversityDB_restore, а не поверх боевой базы?| № | Тема | Вид | Часы | Материал курса |
|---|---|---|---|---|
| Раздел 1. Основы баз данных и проектирование (нед. 1–3) | ||||
| 1 | Основные понятия баз данных и СУБД | Лек | 2 | Л.1 |
| 2 | SSMS: системные и учебные БД | Лаб | 2 | ЛР №1 |
| 3 | Реляционная модель. Функциональные зависимости | Лек | 2 | Л.2 |
| 4 | Таблицы и первый SELECT | Лаб | 2 | ЛР №2 |
| 5 | Нормализация. Аномалии обновления | Лек | 2 | Л.3 |
| 6 | DDL: CREATE, типы, ограничения | Лаб | 2 | ЛР №3 |
| 7 | FK, ALTER TABLE, индексы | Лаб | 2 | ЛР №4 |
| Раздел 2. SQL: выборка и изменение данных (нед. 4) | ||||
| 8 | Многопользовательские и распределённые БД | Лек | 2 | Л.4 |
| 9 | INSERT, SELECT, WHERE | Лаб | 2 | ЛР №5 |
| 10 | UPDATE, DELETE, ORDER BY | Лаб | 2 | ЛР №6 |
| Раздел 3. Транзакции и многопользовательский доступ (нед. 5–8) | ||||
| 11 | Транзакции. Свойства ACID | Лек | 2 | Л.5 |
| 12 | Агрегатные функции | Лаб | 2 | ЛР №7 |
| 13 | GROUP BY, HAVING, ROLLUP | Лаб | 2 | ЛР №8 |
| 14 | Аномалии параллельного доступа | Лек | 2 | Л.6 |
| 15 | Вложенные подзапросы | Лаб | 2 | ЛР №9 |
| 16 | Коррелированные подзапросы и EXISTS | Лаб | 2 | ЛР №10 |
| 17 | Уровни изоляции транзакций | Лек | 2 | Л.7 |
| 18 | INNER и OUTER JOIN | Лаб | 2 | ЛР №11 |
| 19 | UNION, EXCEPT, INTERSECT | Лаб | 2 | ЛР №12 |
| 20 | Блокировки, тупики, репликация | Лек | 2 | Л.8 |
| 21 | Функции строк, чисел, дат | Лаб | 2 | ЛР №13 |
| 22 | CASE, ISNULL, COALESCE | Лаб | 2 | ЛР №14 |
| Раздел 4. XML, иерархии и нереляционные модели (нед. 9–10) | ||||
| 23 | Структурированные и неструктурированные данные | Лек | 2 | Л.9 |
| 24 | Переменные и IF | Лаб | 2 | ЛР №15 |
| 25 | Циклы WHILE и TRY/CATCH | Лаб | 2 | ЛР №16 |
| 26 | Язык XML | Лек | 2 | Л.10 |
| 27 | XML в SQL Server | Лаб | 2 | ЛР №17 |
| 28 | Иерархические данные | Лаб | 2 | ЛР №18 |
| Раздел 5. Администрирование и программирование в СУБД (нед. 11–12) | ||||
| 29 | Администрирование и мониторинг СУБД | Лек | 2 | Л.11 |
| 30 | MongoDB — документная БД | Лаб | 2 | ЛР №19 |
| 31 | Представления VIEW | Лаб | 2 | ЛР №20 |
| 32 | Программирование в БД: процедуры, триггеры | Лек | 2 | Л.12 |
| 33 | Хранимые процедуры | Лаб | 2 | ЛР №21 |
| 34 | Триггеры DML и INSTEAD OF | Лаб | 2 | ЛР №22 |
| Раздел 6. Резервное копирование и защита данных (нед. 13–14) | ||||
| 35 | Резервное копирование | Лек | 2 | Л.13 |
| 36 | GRANT, REVOKE, роли | Лаб | 2 | ЛР №23 |
| 37 | Восстановление данных и защита | Лек | 2 | Л.14 |
| 38 | Восстановление данных и итоговый практикум | Лаб | 2 | ЛР №24 |
| Раздел 7. Распределённые БД и хранилища данных (нед. 15–16) | ||||
| 39 | Распределённые БД и двухфазная фиксация | Лек | 2 | Л.15 · курсовые №6, 21 |
| 40 | Хранилища данных и подготовка к экзамену | Лек | 2 | Л.16 · билеты |
| Раздел 8. Итоговая аттестация | ||||
| 41 | Экзамен по дисциплине «Управление данными» | ИКР | 2,3 | Экзамен · вопросы |
| Лекция | Тема | ЛР | На практике |
|---|---|---|---|
| Л.1 | Понятия БД, СУБД, SSMS | №1 | CREATE DATABASE, подключение |
| Л.2 | Реляционная модель, ФЗ | №2 | таблицы, INSERT, SELECT |
| Л.3 | Нормализация, ключи | №3–4 | DDL, FK, ALTER, индексы |
| Л.4 | Многопользовательский доступ | №5–6 | DML, WHERE, UPDATE, DELETE |
| Л.5 | ACID, транзакции | №7–8 | агрегаты, GROUP BY |
| Л.6 | Аномалии параллельного доступа | №9–10 | подзапросы, EXISTS |
| Л.7 | Уровни изоляции | №11–12 | JOIN, UNION |
| Л.8 | Блокировки, тупики, репликация | №13–14 | функции, CASE |
| Л.9 | Структурированные / неструктурированные данные | №15–16 | переменные, TRY/CATCH |
| Л.10 | XML, XSD | №17–18 | XML в SQL Server, CTE-иерархии |
| Л.11 | Администрирование, мониторинг | №19–20 | MongoDB, VIEW |
| Л.12 | Процедуры, триггеры, планы | №21–22 | процедуры, триггеры |
| Л.13 | Резервное копирование | №23 | GRANT, роли |
| Л.14 | Восстановление, защита данных | №24 | BACKUP/RESTORE + практикум |
| Л.15 | Распределённые БД, 2PC | — | теория · курсовые №6, 21 |
| Л.16 | OLAP, подготовка к экзамену | — | вопросы · билеты |
| Вид | Количество | Академ. часы |
|---|---|---|
| Лекции | 16 пар | 32 |
| Лабораторные | 24 пары | 48 |
| Итого контакт | 40 пар | 80 |
| Экзамен (ИКР) | 1 | 2,3 |
Kursovaya_FIO (или согласованное имя); не менее 5 таблиц с PRIMARY KEY, FOREIGN KEY, минимум два ограничения CHECK или UNIQUE; осмысленное наполнение (не «пустые таблицы»).SELECT с WHERE, JOIN, агрегаты с GROUP BY/HAVING, подзапрос или EXISTS; плюс один из элементов серверного программирования: VIEW, хранимая процедура или AFTER-триггер (аудит или бизнес-правило).BEGIN TRAN … COMMIT/ROLLBACK (операция из нескольких шагов) или демонстрация резервного копирования своей базы (BACKUP / описание RESTORE).kursovaya_FIO.sql (ФИО латиницей) + пояснительная записка со скриншотами SSMS (схема, примеры запросов, при наличии — план выполнения или права доступа).Свою тему (не из списка) можно предложить преподавателю, если она укладывается в минимум выше и не дублирует UniversityDB «одной таблицей Excel».
| № | Тема и содержание проекта |
|---|---|
| 1 | Интернет-магазин. Спроектировать БД: товары, категории, клиенты, заказы, строки заказа. Реализовать оформление заказа в транзакции; отчёты — топ товаров, сумма по клиентам; VIEW «активные заказы». |
| 2 | Частная клиника. Пациенты, врачи, приёмы, диагнозы, назначения. Связи M:N «врач — специализация»; CHECK на дату приёма; процедура «расписание врача на неделю». |
| 3 | Автосервис. Клиенты, автомобили, заказ-наряды, работы, запчасти. FK «авто → владелец»; агрегат «выручка по месяцам»; триггер аудита изменения стоимости наряда. |
| 4 | Гостиница. Номера, типы номеров, бронирования, гости, оплаты. Запрет пересечения броней (CHECK или триггер); JOIN «загрузка номеров»; резервная копия перед тестовым наполнением. |
| 5 | Публичная библиотека. Книги, авторы, экземпляры, читатели, выдачи. Нормализация «автор не дублируется в каждой выдаче»; EXISTS «книги на руках у читателя»; процедура выдачи/возврата. |
| 6 | Фитнес-клуб. Абонементы, типы, посещения, тренеры, групповые занятия. GROUP BY «популярность занятий»; транзакция продления абонемента; VIEW для ресепшена. |
| 7 | Ресторан / доставка. Меню, блюда, ингредиенты, заказы, курьеры. M:N «блюдо — ингредиент»; HAVING «блюда дороже среднего»; XML-описание акции (столбец XML, извлечение поля). |
| 8 | Агентство недвижимости. Объекты, типы, районы, клиенты, сделки, агенты. Иерархия районов (рекурсивный CTE); подзапрос «объекты без сделок»; индекс по цене + комментарий к плану запроса. |
| 9 | Ветеринарная клиника. Владельцы, питомцы, породы, приёмы, вакцинации. CHECK на вид животного; LEFT JOIN «питомцы без приёмов за год»; роли «ветеринар / регистратор» (GRANT на уровне учебного login). |
| 10 | Музыкальная школа. Ученики, преподаватели, инструменты, уроки, абонементы. Расписание без двойного бронирования кабинета; GROUP BY «часы по преподавателям»; процедура usp_LessonsByTeacher. |
| 11 | Фото-студия. Клиенты, пакеты услуг, брони слотов, фотографы, оборудование. Транзакция «бронь + предоплата»; VIEW «загрузка студии по дням»; миграция прайса из Excel (описать шаги загрузки). |
| 12 | Прокат велосипедов. Пункты проката, велосипеды, клиенты, аренды, штрафы. FK и CASCADE при списании велосипеда; отчёт «простой парка»; BACKUP после наполнения эталоном. |
| 13 | Кафе настольных игр. Игры, жанры, столы, брони, участники турниров. M:N «турнир — игрок»; EXISTS «игроки без турниров»; триггер запрета удаления игры с активными бронями. |
| 14 | Центр репетиторства. Предметы, репетиторы, ученики, занятия, оплаты. Нормализация «не хранить ФИО репетитора в каждой оплате»; JOIN «долги учеников»; процедура отчёта за период. |
| 15 | Цветочный магазин. Букеты, компоненты, поставщики, заказы, доставки. CHECK на сезонность/остаток; UNION «все контактные лица (клиенты + поставщики)»; VIEW для витрины заказов. |
| 16 | IT-Helpdesk. Пользователи, категории заявок, тикеты, комментарии, исполнители. Статусы и история (таблица аудита или триггер); GROUP BY «среднее время закрытия»; демонстрация блокировки при параллельном UPDATE статуса. |
| 17 | Садовое товарищество. Участки, владельцы, взносы, показания счётчиков, обращения. Иерархия «улица — участок»; агрегаты по задолженности; сравнение «плохая одна таблица» vs нормализованная схема в записке. |
| 18 | Приют для животных. Питомцы, породы, поступления, усыновления, волонтёры, пожертвования. NOT EXISTS «давно не усыновлённые»; транзакция «усыновление + закрытие карточки»; этичные тестовые данные без реальных ФИО. |
| 19 | Коворкинг. Помещения, рабочие места, тарифы, брони, резиденты. Рекурсивный CTE по зонам этажа; процедура поиска свободного места; RESTORE на копию Kursovaya_FIO_restore после ошибочного DELETE. |
| 20 | Кинотеатр. Залы, сеансы, фильмы, места, билеты, кассиры. Уникальность «место + сеанс»; JOIN «заполняемость сеансов»; VIEW для онлайн-расписания; индекс по дате сеанса. |
| 21 | Прачечная / химчистка. Клиенты, изделия, услуги, приёмы в работу, статусы, оплаты. CHECK на допустимый статус; GROUP BY «выручка по видам услуг»; сценарий ROLLBACK при ошибочном массовом UPDATE. |
| 22 | Каршеринг (локальный парк). Автомобили, тарифы, поездки, клиенты, штрафы, ТО. FK и даты; подзапрос «клиенты с поездками > N»; описание RPO/RTO для такой БД в записке. |
| 23 | Музей. Экспонаты, залы, эпохи, экскурсии, гиды, билеты. M:N «экскурсия — экспонат»; агрегат «посещаемость по залам»; хранение текста экспозиции в XML с выборкой XPath. |
| 24 | Спортивная секция. Секции, тренеры, спортсмены, соревнования, результаты, медосмотры. GROUP BY «медали по секциям»; процедура зачисления в секцию; GRANT «тренер видит только свою секцию» через VIEW и права. |
| 25 | Своя тема (по согласованию). Любая предметная область студента: от онлайн-курсов до складского учёта — при условии выполнения минимума из списка выше и защиты ER-схемы на консультации до сдачи. |
UniversityDB — учебная база курса: вузы, студенты, преподаватели, предметы, оценки. На ней выполняются почти все лабораторные (кроме отдельных схем вроде «Библиотека» на ЛР №3). После лабораторных с изменением данных (DML, триггеры) базу можно восстановить, заново выполнив блоки ниже.
SQL-скрипт — это обычный текст с командами T-SQL: создание таблиц, вставка строк, запросы. В SSMS его набирают или вставляют в окно New Query и выполняют клавишей F5 (или кнопкой Execute). Сервер выполняет команды и сохраняет результат в файлах базы на диске — не в окне SSMS.
Эталонный скрипт UniversityDB собран для этого курса и лежит на этой странице — отдельного файла скачивать не нужно. Ниже он разбит на блоки с пояснениями. На ЛР №2 вы копируете блоки по порядку в SSMS и сохраняете свою копию в файл lab02_FIO.sql (ФИО латиницей) — это уже ваш рабочий файл, а не «чужой скрипт из ниоткуда».
UniversityDB.CREATE TABLE. Блок 6 — INSERT. Между частями с GO можно выполнять по очереди.UNIVERSITY 1—∞ STUDENT, UNIVERSITY 1—∞ LECTURER, UNIVERSITY 1—∞ ORG_UNIT.
SUBJECT 1—∞ EXAM_MARKS, STUDENT 1—∞ EXAM_MARKS.
LECTURER ∞—∞ SUBJECT через SUBJ_LECT.
ORG_UNIT.PARENT_ID ссылается на ORG_UNIT.UNIT_ID (иерархия).
Выполняйте блоки по порядку. Если база пустая после ЛР №1, блок 2 можно пропустить.
Создаёт базу UniversityDB, если её ещё нет, и переключает контекст на неё. На ЛР №1 вы уже делали то же командой CREATE DATABASE — здесь повтор для полного эталона.
Нужен только если таблицы уже создавали и хотите пересобрать схему с нуля. Удаление идёт от зависимых таблиц к независимым — иначе СУБД не даст удалить родительскую таблицу.
Таблицы, на которые ссылаются другие: список вузов и список предметов. Создаются первыми.
У каждой строки — ссылка UNIVERSITY_ID на справочник вузов (внешний ключ). Именно так устроена схема из лекции 2.
EXAM_MARKS — оценка студента по предмету. SUBJ_LECT — кто какой предмет ведёт. ORG_UNIT — иерархия кафедр (нужна на ЛР №18).
Строки вставляются в порядке зависимостей: сначала родители (UNIVERSITY, SUBJECT), потом дети. Иначе внешний ключ не найдёт ссылку и INSERT завершится ошибкой.
6.1. Вузы:
6.2. Предметы:
6.3. Студенты (19 строк; у id=19 город NULL — для заданий с IS NULL):
6.4. Преподаватели:
6.5. Оценки (24 строки; у студента 19 оценок нет — для NOT EXISTS и LEFT JOIN):
6.6. Кто какой предмет ведёт:
6.7. Подразделения вузов:
Проверка после блока 6: SELECT COUNT(*) FROM STUDENT; — должно быть 19. У студента с STUDENT_ID = 19 нет строк в EXAM_MARKS.
Те же строки, что в блоке 6, в удобном виде — можно сверить результат после INSERT.
На телефоне широкие таблицы прокручиваются пальцем влево и вправо.
| UNIVERSITY_ID | UNIVERSITY_NAME | RATING | CITY |
|---|---|---|---|
| 10 | ВГУ | 450 | Воронеж |
| 11 | НГУ | 580 | Новосибирск |
| 12 | СПбГУ | 650 | Санкт-Петербург |
| 14 | БГУ | 320 | Белгород |
| 15 | ТГУ | 390 | Томск |
| 18 | ВГМУ | 410 | Воронеж |
| 22 | МГУ | 700 | Москва |
| 32 | ЮФУ | 470 | Ростов-на-Дону |
| ID | Фамилия | Имя | Стип. | Курс | Город | Рождение | Вуз |
|---|---|---|---|---|---|---|---|
| 1 | Иванов | Иван | 150 | 1 | Воронеж | 2007-03-12 | 10 |
| 2 | Сидорова | Анна | 200 | 1 | Москва | 2007-07-01 | 22 |
| 3 | Петров | Пётр | 0 | 3 | Курск | 2005-11-20 | 10 |
| 4 | Козлова | Мария | 180 | 2 | Санкт-Петербург | 2006-04-15 | 12 |
| 5 | Новиков | Дмитрий | 120 | 2 | Новосибирск | 2006-09-03 | 11 |
| 6 | Сидоров | Вадим | 0 | 4 | Москва | 2004-01-28 | 22 |
| 7 | Морозова | Елена | 250 | 1 | Белгород | 2007-12-05 | 14 |
| 8 | Волков | Алексей | 140 | 3 | Томск | 2005-06-17 | 15 |
| 9 | Соколова | Ирина | 160 | 2 | Воронеж | 2006-02-22 | 18 |
| 10 | Кузнецов | Борис | 0 | 5 | Москва | 2003-08-09 | 22 |
| 11 | Орлов | Никита | 130 | 1 | Ростов-на-Дону | 2007-05-14 | 32 |
| 12 | Зайцева | Ольга | 170 | 4 | Воронеж | 2004-10-30 | 10 |
| 13 | Павлов | Андрей | 90 | 3 | Новосибирск | 2005-03-08 | 11 |
| 14 | Лебедева | Татьяна | 210 | 2 | Москва | 2006-12-19 | 22 |
| 15 | Котов | Павел | 0 | 1 | Курск | 2008-01-11 | 10 |
| 16 | Лукин | Артём | 110 | 5 | Белгород | 2003-04-25 | 14 |
| 17 | Белкин | Вадим | 155 | 3 | Воронеж | 2005-09-16 | 10 |
| 18 | Крылова | Светлана | 190 | 4 | Санкт-Петербург | 2004-07-07 | 12 |
| 19 | Медведев | Олег | 80 | 1 | NULL | 2007-08-21 | 32 |
| ID | Фамилия | Имя | Город | Вуз |
|---|---|---|---|---|
| 24 | Колесников | Борис | Воронеж | 10 |
| 46 | Никонов | Иван | Воронеж | 10 |
| 74 | Лагутин | Павел | Москва | 22 |
| 108 | Струков | Николай | Москва | 22 |
| 276 | Николаев | Виктор | Воронеж | 10 |
| 328 | Сорокин | Андрей | Орёл | 10 |
| 401 | Смирнова | Ольга | Санкт-Петербург | 12 |
| 512 | Гусев | Игорь | Новосибирск | 11 |
| 620 | Фролов | Сергей | Томск | 15 |
| 705 | Макарова | Анна | Белгород | 14 |
| SUBJ_ID | Название | Часы | Семестр |
|---|---|---|---|
| 10 | Информатика | 56 | 1 |
| 18 | Химия | 40 | 2 |
| 22 | Физика | 34 | 1 |
| 31 | Базы данных | 72 | 5 |
| 43 | Математика | 56 | 2 |
| 56 | История | 34 | 4 |
| 73 | Физкультура | 34 | 5 |
| 94 | Английский | 56 | 3 |
| EXAM_ID | STUDENT_ID | SUBJ_ID | MARK | EXAM_DATE |
|---|---|---|---|---|
| 1 | 1 | 10 | 5 | 2026-01-15 |
| 2 | 1 | 22 | 4 | 2026-01-18 |
| 3 | 3 | 10 | 3 | 2026-01-15 |
| 4 | 3 | 22 | 4 | 2026-01-18 |
| 5 | 2 | 10 | 5 | 2026-01-16 |
| 6 | 4 | 43 | 5 | 2026-06-10 |
| 7 | 5 | 10 | 4 | 2026-01-15 |
| 8 | 6 | 56 | 3 | 2026-06-12 |
| 9 | 8 | 94 | 5 | 2026-01-20 |
| 10 | 9 | 18 | 4 | 2026-06-08 |
| 11 | 10 | 31 | 5 | 2026-01-22 |
| 12 | 12 | 56 | 4 | 2026-06-12 |
| 13 | 13 | 10 | 2 | 2026-01-15 |
| 14 | 14 | 94 | 5 | 2026-01-20 |
| 15 | 17 | 22 | 3 | 2026-01-18 |
| 16 | 7 | 10 | 5 | 2026-01-16 |
| 17 | 11 | 10 | 4 | 2026-01-16 |
| 18 | 15 | 22 | 3 | 2026-01-18 |
| 19 | 18 | 56 | 5 | 2026-06-12 |
| 20 | 16 | 31 | 4 | 2026-01-22 |
| 21 | 1 | 43 | 5 | 2026-06-10 |
| 22 | 12 | 31 | 3 | 2026-01-22 |
| 23 | 6 | 31 | 4 | 2026-01-22 |
| 24 | 4 | 10 | 4 | 2026-01-16 |
Студент 19 (Медведев) специально без строк в EXAM_MARKS и с CITY NULL: на нём проверяют IS NULL, NOT EXISTS и LEFT JOIN … IS NULL.
| LECTURER_ID | SUBJ_ID |
|---|---|
| 24 | 10 |
| 24 | 31 |
| 46 | 22 |
| 46 | 18 |
| 74 | 43 |
| 108 | 56 |
| 276 | 73 |
| 328 | 10 |
| 401 | 94 |
| 512 | 10 |
| 620 | 18 |
| 705 | 56 |
| UNIT_ID | PARENT_ID | UNIT_NAME | UNIVERSITY_ID |
|---|---|---|---|
| 1 | NULL | Ректорат | 10 |
| 2 | 1 | Учебное управление | 10 |
| 3 | 1 | Факультет КНиИТ | 10 |
| 4 | 3 | Кафедра информационных технологий | 10 |
| 5 | 3 | Кафедра математики | 10 |
| 6 | 1 | Факультет ПММ | 10 |
| 7 | 6 | Кафедра механики | 10 |
| 20 | NULL | Ректорат | 22 |
| 21 | 20 | Факультет ВМК | 22 |
| 22 | 21 | Кафедра алгоритмических языков | 22 |
| Задача | SQL Server | SQLite |
|---|---|---|
| Первые N строк | TOP (N) … ORDER BY | LIMIT N |
| Пагинация | OFFSET FETCH | LIMIT … OFFSET |
| Строка сейчас | GETDATE(), SYSDATETIME() | datetime('now') |
| Конкатенация | + или CONCAT | || |
| Авточисло | INT IDENTITY | INTEGER PRIMARY KEY |
| Юникод-литерал | N'текст' | 'текст' UTF-8 |
| Удаление дубликатов строк запроса | DISTINCT | DISTINCT |
| FULL JOIN | есть | эмуляция UNION |
| Процедуры | CREATE PROC | нет |
| Бэкап | BACKUP DATABASE | VACUUM INTO / копия файла |
На экзамене из этого списка задают два вопроса (см. билеты ниже).
На экзамене выдаётся один билет из списка ниже: два теоретических вопроса + одна SQL-задача по UniversityDB. Нажмите на номер билета, чтобы открыть.
NOT EXISTS или LEFT JOIN … IS NULL).GROUP BY, HAVING).SUBJ_LECT).CITY IS NULL (ожидается Медведев, STUDENT_ID=19).UNIVERSITY_ID=10 от UNIT_ID=1.NOT EXISTS или LEFT JOIN … IS NULL).GROUP BY, HAVING).SUBJ_LECT).CITY IS NULL (ожидается Медведев, STUDENT_ID=19).UNIVERSITY_ID=10 от UNIT_ID=1.NOT EXISTS или LEFT JOIN … IS NULL).GROUP BY, HAVING).SUBJ_LECT).CITY IS NULL (ожидается Медведев, STUDENT_ID=19).UNIVERSITY_ID=10 от UNIT_ID=1.