Работа 2
This commit is contained in:
144
report.tex
144
report.tex
@@ -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}
|
||||
Reference in New Issue
Block a user