Добавил:
владимир Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
отчеты по лабам / СУБД_ЛР7.docx
Скачиваний:
4
Добавлен:
21.06.2025
Размер:
38.99 Кб
Скачать
    1. Задание 2.

Предположим, что студент группы ИВТ-42 Полиграф Шариков во время зимней сессии пересдал экзамен по дисциплине «Операционные системы» на оценку 5 и пересдал экзамен по дисциплине «Базы данных» на 5. Одновременно с проставлением баллов за его успехами следила методист кафедры. Для работы с несколькими транзакциями запустите два командных окна (запросника). В первом вводите команды за преподавателя, проставляющего оценки, а во втором за методиста, просматривающего результаты.

      1. Работа с транзакциями

В рамках транзакции измените значение оценки студента по Операционным системам и проверьте значение в первом и втором окне. Зафиксируйте изменения и вновь проверьте значения. Аналогично внесите новую оценку по Базам данных и проверьте изменения.

Преподаватель

Методист

BEGIN;

Изменяет оценку

Добавляет оценку

COMMIT

Смотрит результат до фиксации изменений преподавателем

Смотрит результат после фиксации изменений преподавателем

      1. Отмена изменений транзакций

Удалите добавленное значение и верните исправленную оценку в прежнее состояние. Повторите аналогичные действия, только по окончании внесения изменений преподавателем откатите их с помощью команды ROLLBACK. Какое значение увидела методист?

      1. Моделирование аномалий при выполнении транзакций

Повторите эксперименты в п. 1.2.1, используя различные уровни изоляции.

Преподаватель

Методист

BEGIN ISOLATION LEVEL …

Изменяет оценку

Добавляет оценку

COMMIT

BEGIN ISOLATION LEVEL …

Смотрит результат до фиксации изменений преподавателем

Смотрит результат после фиксации изменений преподавателем

Внесите в таблицу в какой момент были получены ошибочные значения из-за аномалий.

Уровень изоляции

До фиксации

После фиксации

Read uncommited

Read committed

Repeatable read

Serializable

Как вы считаете, какой уровень изоляции необходимо использовать на практике и почему?

    1. Задание 3.

Проанализируйте учебную базу данных и проиндексируйте одно из полей любой таблицы. Объясните свой выбор.

Контрольные вопросы

  1. За счет чего индексы ускоряют выборку данных?

  2. Существуют ли случаи, когда использование индексов замедляет выборку данных?

  3. Какая структура данных хранит в себе индексные записи?

  4. Для чего предназначены транзакции?

  5. В чем отличие между неповторяющимся и фантомным чтением?

1)

CREATE TABLE attendance (

attendance_id SERIAL PRIMARY KEY, -- Уникальный идентификатор записи

generated_code VARCHAR(64), -- Сгенерированный код для посещения

person_id INTEGER, -- Идентификатор студента

enter_time TIMESTAMP, -- Время входа

exit_time TIMESTAMP, -- Время выхода

FOREIGN KEY (person_id) REFERENCES student_ids (student_id) -- Внешний ключ, ссылающийся на таблицу студентов

);

2)

DO

$$

DECLARE

enter_time TIMESTAMP(0); -- Время входа

exit_time TIMESTAMP(0); -- Время выхода

person_id INTEGER; -- Идентификатор студента

enter_id VARCHAR(64); -- Сгенерированный код для посещения

BEGIN

FOR i IN 1..1000000 LOOP -- Генерация 1 миллиона записей

-- Генерация случайной даты в пределах 2025 года

enter_time := to_timestamp(

random() * (

extract(epoch from '2025-12-31'::date) -

extract(epoch from '2025-01-01'::date)

) + extract(epoch from '2025-01-01'::date)

);

-- Генерация случайного времени, не более 10 часов (36000 секунд)

exit_time := enter_time + (floor(random() * 36000 + 1) * '1 SECOND'::interval);

-- Получаем случайного студента из таблицы студентов

person_id := (

SELECT student_id FROM students

ORDER BY random()

LIMIT 1

);

-- Генерация уникального кода для посещения

enter_id := md5(random()::text);

-- Вставка данных в таблицу attendance

INSERT INTO attendance(generated_code, person_id, enter_time, exit_time)

VALUES (enter_id, person_id, enter_time, exit_time);

END LOOP;

END

$$;

3)

-- Удаляем индекс, если он существует

DROP INDEX IF EXISTS idx_generated_code;

-- Выполнение анализа производительности при вставке данных

EXPLAIN ANALYZE

INSERT INTO attendance (generated_code, person_id, enter_time, exit_time)

VALUES ('ABC123', 1, '2024-12-03 10:00:00', '2024-12-03 11:00:00');-------- 4 шаг

EXPLAIN ANALYZE SELECT * FROM attendance

EXPLAIN ANALYZE SELECT * FROM attendance WHERE person_id = 1;

CREATE INDEX idx_person_id ON attendance (person_id);

EXPLAIN ANALYZE SELECT * FROM attendance

EXPLAIN ANALYZE SELECT * FROM attendance WHERE person_id = 1;

-- Удаляем индекс, если он существует

DROP INDEX IF EXISTS idx_generated_code;

-- Выполнение анализа производительности при вставке данных

EXPLAIN ANALYZE

INSERT INTO attendance (generated_code, person_id, enter_time, exit_time)

VALUES ('ABC123', 1, '2024-12-03 10:00:00', '2024-12-03 11:00:00');

INSERT INTO students (student_id, last_name, first_name, patronymic, students_group_number, birthday)

VALUES (1, 'Ерёмин', 'Даниил', 'Валерьевич', 'ИВТ-43', '2003-10-13');

INSERT INTO student_ids (student_id)

VALUES (1);

-- Повторный анализ производительности после добавления данных

EXPLAIN ANALYZE

INSERT INTO attendance (generated_code, person_id, enter_time, exit_time)

VALUES ('XYZ789', 1, '2024-12-03 12:00:00', '2024-12-03 13:00:00');

CREATE INDEX idx_generated_code ON attendance (generated_code);

EXPLAIN ANALYZE

INSERT INTO attendance (generated_code, person_id, enter_time, exit_time)

VALUES ('LMN456', 1, '2024-12-03 14:00:00', '2024-12-03 15:00:00');

EXPLAIN ANALYZE

SELECT * FROM attendance ORDER BY generated_code;

5)

EXPLAIN ANALYZE SELECT * FROM attendance

WHERE generated_code LIKE '%a'

ORDER BY generated_code;

6)

ALTER TABLE grades

ADD COLUMN student_name VARCHAR(255);

UPDATE grades

SET student_name = (

SELECT CONCAT(s.first_name, ' ', s.last_name)

FROM students s

WHERE s.student_id = grades.student_id

);

ALTER TABLE grades

ADD COLUMN students_group_number VARCHAR(255);

UPDATE grades

SET students_group_number = (

SELECT s.students_group_number

FROM students s

WHERE s.student_id = grades.student_id

);

SELECT * FROM public.grades

ORDER BY grade_id DESC LIMIT 20

INSERT INTO grades (grade_id, student_id, professor_id, grade, student_name, students_group_number, subject)

VALUES

(7089, 1, 1, 3, ’Полиграф Шариков’, 'ИВТ-42', 'Операционные системы'),

(7090, 1, 1, 3, ’Полиграф Шариков’, 'ИВТ-42', 'Базы данных');

ALTER TABLE grades

ADD COLUMN subject VARCHAR(255);

UPDATE grades

SET subject = (

SELECT f.field_name

FROM fields f

WHERE f.field_name = grades.subject

);

Преподаватель

BEGIN;

UPDATE grades

SET grade = 5

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Операционные системы';

UPDATE grades

SET grade = 5

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Базы данных';

------

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

-----

COMMIT;

------

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

------C ROLLBACK

BEGIN;

UPDATE grades

SET grade = 3

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Операционные системы';

UPDATE grades

SET grade = 3

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Базы данных';

COMMIT;

---------------

BEGIN;

UPDATE grades

SET grade = 5

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Операционные системы';

UPDATE grades

SET grade = 5

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Базы данных';

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

-----------------

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

ROLLBACK;

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

-----Аномалия -----

------

BEGIN;

UPDATE grades

SET grade = 5

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Операционные системы';

UPDATE grades

SET grade = 5

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Базы данных';

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

-----------------

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

--------------

COMMIT;

-----------------

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

-----------

BEGIN;

UPDATE grades

SET grade = 3

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Операционные системы';

UPDATE grades

SET grade = 3

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Базы данных';

COMMIT;

-----Аномалия Read committed

----------------

BEGIN;

UPDATE grades

SET grade = 5

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Операционные системы';

UPDATE grades

SET grade = 5

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Базы данных';

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

-----------------

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

-----------------

COMMIT;

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

BEGIN;

UPDATE grades

SET grade = 3

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Операционные системы';

UPDATE grades

SET grade = 3

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Базы данных';

COMMIT;

-----Аномалия Repeatable read

---------------

BEGIN;

UPDATE grades

SET grade = 5

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Операционные системы';

UPDATE grades

SET grade = 5

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Базы данных';

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

COMMIT;

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

-----------SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

BEGIN;

UPDATE grades

SET grade = 3

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Операционные системы';

UPDATE grades

SET grade = 3

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Базы данных';

COMMIT;

-----Аномалия Serializable

BEGIN;

UPDATE grades

SET grade = 5

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Операционные системы';

UPDATE grades

SET grade = 5

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Базы данных';

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

COMMIT;

SELECT * FROM grades

WHERE student_name = ‘Полиграф Шариков’;

BEGIN;

UPDATE grades

SET grade = 3

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Операционные системы';

UPDATE grades

SET grade = 3

WHERE student_name = ‘Полиграф Шариков’ AND subject = 'Базы данных';

COMMIT;

Вкратце:

  1. Создал таблицу attendance согласно примеру из методических материалов.

  2. Заполнил таблицу данными, следуя примеру из методички.

  3. При попытке вставить данные в таблицу с person_id = 1 возникла ошибка, указывающая на отсутствие такого id в связанных таблицах. Для исправления добавил себя в таблицы students и student_ids с id = 1 как пример. После внесения изменений команды начали выполняться корректно.

Время до индексирования Tb

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

Ta/ Tb

SELECT

Planning Time: 0.225 ms

Execution Time: 1626.683 ms

Planning Time: 0.164 ms

Execution Time: 1055.04 ms

Planning Time 0.64

Execution Time 0.65

INSERT

Planning Time: 0.214 ms

Execution Time: 0.543 ms

Planning Time: 0.067 ms

Execution Time: 0.586 ms

Planning Time 0.33

Execution Time 0.94

SELECT Planning Time 1.59

Execution Time 1.55

INSERT Planning Time 3.26

Execution Time 1.08

По результатам можно сделать вывод, что индексирование ускоряет работу с базами данных в области поиска но незначительно ускоряет при добавлении данных

4)

Время до индексирования Tb

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

Ta/ Tb

SELECT

Planning Time: 0.379 ms

Execution Time: 177.351 ms

Planning Time: 0.517 ms

Execution Time: 135.950 ms

Planning Time 1.43

Execution Time 0.772

SELECT+WHERE

Planning Time: 0.519 ms

Execution Time: 103.511 ms

Planning Time: 0.171 ms

Execution Time: 0.332 ms

Planning Time 0.341

Execution Time 3.26e-3

SELECT Planning Time 1.42

Execution Time 1.31

INSERT Planning Time 2.93

Execution Time 307.23

По результатам видно, что время запроса с условием после добавления индекса в сотни раз меньше, чем время аналогичного запроса до индексирования

  1. После выполнения запроса к таблице были получены следующие результаты:

  • Время планирования: 42.136 мс

  • Время выполнения: 188.660 мс

Индекс в данном запросе не использовался, поскольку поиск с шаблоном, начинающимся с символа %, требует полного сканирования таблицы. Это связано с тем, что индекс не может эффективно сузить диапазон значений, если они начинаются с переменной части строки.

  1. Обновил таблицу grades, добавив фамилию и имя студента, его группу и название предмета. Открыл два окна: одно для преподавателя, другое — для методиста. 6.1) Для преподавателя обновил оценки студента и вывел информацию о нем (оценки изменились на 5). 6.2) Для методиста вывел информацию по тому же студенту (оценки остались прежними — 3). 6.3) Для преподавателя выполнил команду COMMIT;. 6.4) Для методиста повторил запрос и увидел обновленные оценки (5). 6.5) Для преподавателя откатил внесенные изменения с помощью команды ROLLBACK; (выводил информацию по студенту до и после отката — до ROLLBACK оценки изменились, а после отката остались прежними). 6.6) Для методиста повторил запрос и увидел, что оценки остались неизменными (3).

Уровень изоляции

До фиксации

После фиксации

Read uncommited

ПР5 МЕТ3

ПР5 МЕТ5

Read committed

ПР5 МЕТ3

ПР5 МЕТ5

Repeatable read

-

-

Serializable

-

-

Соседние файлы в папке отчеты по лабам