Работа 2

This commit is contained in:
2024-10-09 00:07:48 +03:00
parent 71f1563d00
commit 0d8296b412

View File

@@ -233,4 +233,148 @@
\label{fig:insert_error}
\end{figure}
\subsection{Работа 2: Событийная модель, триггеры}
\textbf{Задача:} Разработать триггер, производящий манипуляции над БД при добавлении, удалении и обновлении данных.
\textbf{Формулировка задачи:} Необходимо вести статистику о том, в скольки соревнованиях участвовал каждый судья. Событийная модель должна поддерживать актуальность данных в таблицах со статистикой при изменении данных.
Для выполнения поставленной задачи, была создана отдельная таблица для сохранения статистики. Код запроса для её создания представлен в листинге~\ref{lst:trigger-table}.
\begin{lstlisting}[mathescape=true, language=SQL, caption={Код запроса для создания таблицы \texttt{judge\_statistics}.}, label={lst:trigger-table}]
create table judge_statistics (
id_judge integer primary key,
competition_count integer not null default 0,
foreign key (id_judge) references judge(id_judge)
);
\end{lstlisting}
Данные в таблице \texttt{judge\_statistics} должны изменяться при изменении таблиц \texttt{judge} и \texttt{judge\_request}. Список созданных для этого триггеров представлен ниже.
\begin{enumerate}
\item \texttt{after\_judge\_insert}
\begin{itemize}
\item \textbf{Срабатывает при} добавлении новых судей в таблицу \texttt{judge}.
\item \textbf{Действие:} добавляет нового судью в \texttt{judge\_statistics}.
\item \textbf{Код:} листинг~\ref{lst:trigger1}.
\end{itemize}
\begin{lstlisting}[mathescape=true, language=SQL, caption={Код запроса для создания триггера \texttt{after\_judge\_insert} и функции \texttt{update\_statistics\_on\_judge\_insert}.}, label={lst:trigger1}]
create or replace function update_statistics_on_judge_insert()
returns trigger as $$
begin
insert into judge_statistics (id_judge, competition_count)
values (new.id_judge, 0);
return new;
end;
$$ language plpgsql;
create trigger after_judge_insert
after insert on judge
for each row
execute function update_statistics_on_judge_insert();
\end{lstlisting}
\item \texttt{after\_judge\_delete}
\begin{itemize}
\item \textbf{Срабатывает при} удалении судей из таблицы \texttt{judge}.
\item \textbf{Действие:} удаляет судей из \texttt{judge\_statistics}.
\item \textbf{Код:} листинг~\ref{lst:trigger2}.
\end{itemize}
\begin{lstlisting}[mathescape=true, language=SQL, caption={Код запроса для создания триггера \texttt{after\_judge\_delete} и функции \texttt{update\_statistics\_on\_judge\_delete}.}, label={lst:trigger2}]
create or replace function update_statistics_on_judge_delete()
returns trigger as $$
begin
delete from judge_statistics where id_judge = old.id_judge;
return old;
end;
$$ language plpgsql;
create trigger after_judge_delete
after delete on judge
for each row
execute function update_statistics_on_judge_delete();
\end{lstlisting}
\item \texttt{after\_judge\_request\_insert}
\begin{itemize}
\item \textbf{Срабатывает при} добавлении заявки судьи на участие в соревновании в таблицу \texttt{judge\_request}.
\item \textbf{Действие:} увеличивает на единицу счётчик с количеством соревнований \\ в \texttt{judge\_statistics} для судьи, от имени которого была добавлена заявка.
\item \textbf{Код:} листинг~\ref{lst:trigger3}.
\end{itemize}
\begin{lstlisting}[mathescape=true, language=SQL, caption={Код запроса для создания триггера \texttt{after\_judge\_request\_insert} и функции \texttt{update\_statistics\_on\_judge\_request\_insert}.}, label={lst:trigger3}]
create or replace function update_statistics_on_judge_request_insert()
returns trigger as $$
begin
update judge_statistics
set competition_count = competition_count + 1
where id_judge = new.id_judge;
return new;
end;
$$ language plpgsql;
create trigger after_judge_request_insert
after insert on judge_request
for each row
execute function update_statistics_on_judge_request_insert();
\end{lstlisting}
\item \texttt{after\_judge\_request\_delete}
\begin{itemize}
\item \textbf{Срабатывает при} удалении заявки судьи на участие в соревновании из таблицы \texttt{judge\_request}.
\item \textbf{Действие:} уменьшает на единицу счётчик с количеством соревнований \\ в \texttt{judge\_statistics} для судьи, от имени которого была добавлена заявка.
\item \textbf{Код:} листинг~\ref{lst:trigger4}.
\end{itemize}
\begin{lstlisting}[mathescape=true, language=SQL, caption={Код запроса для создания триггера \texttt{after\_judge\_request\_delete} и функции \texttt{update\_statistics\_on\_judge\_request\_delete}.}, label={lst:trigger4}]
create or replace function update_statistics_on_judge_request_delete()
returns trigger as $$
begin
update judge_statistics
set competition_count = competition_count - 1
where id_judge = old.id_judge;
return old;
end;
$$ language plpgsql;
create trigger after_judge_request_delete
after delete on judge_request
for each row
execute function update_statistics_on_judge_request_delete();
\end{lstlisting}
\item \texttt{after\_judge\_request\_update}
\begin{itemize}
\item \textbf{Срабатывает при} изменении заявки судьи на участие в соревновании в таблице \texttt{judge\_request}.
\item \textbf{Действие:} уменьшает на единицу счётчик с количеством соревнований для \\ в \texttt{judge\_statistics} для судьи, от имени которого была добавлена заявка.
\item \textbf{Код:} листинг~\ref{lst:trigger5}.
\end{itemize}
\begin{lstlisting}[mathescape=true, language=SQL, caption={Код запроса для создания триггера \texttt{after\_judge\_request\_update} и функции \texttt{update\_statistics\_on\_judge\_request\_update}.}, label={lst:trigger5}]
create or replace function update_statistics_on_judge_request_update()
returns trigger as $$
begin
-- уменьшение счётчика у старого судьи
update judge_statistics
set competition_count = competition_count - 1
where id_judge = old.id_judge;
-- увеличение счётчика у нового судьи
update judge_statistics
set competition_count = competition_count + 1
where id_judge = new.id_judge;
return new;
end;
$$ language plpgsql;
create trigger after_judge_request_update
after update on judge_request
for each row
execute function update_statistics_on_judge_request_update();
\end{lstlisting}
\end{enumerate}
После создания таблицы \texttt{judge\_statistics} и всех триггеров, база данных была заполнена заново с помощью скрипта, разработанного ещё в прошлом семестре, для того, чтобы таблица содержала актуальные данные. Первые десять строк таблицы \texttt{judge\_statistics} демонстрируются на Рис.~\ref{fig:judge_stat}.
\begin{figure}[h]
\centering
\includegraphics[width=0.35\linewidth]{img/judge_stat.png}
\caption{Первые десять записей в таблице \texttt{judge\_statistics}.}
\label{fig:judge_stat}
\end{figure}
\end{document}