Проектирование БД
Выделены основные сущности:
Первым делом можно выделить сущность «преподаватель». Она будет хранить в себе информацию о преподавателе, который пользуется порталом. Основные атрибуты: уникальный идентификатор; электронная почта (будет использоваться для подтверждения учетной записи и в качестве логина); пароль, ФИО; флаг активности учетной записи(При регистрации без подтверждения через почту - учетная запись будет неактивна).
Также вводится сущность «курс», указывающая на то, на каком этапе обучения находится группа. Атрибуты: уникальный идентификатор; код курса.
Для деления студентов и тестов вводится сущность «группа». Ее атрибутами будут: уникальный идентификатор; код группы; идентификатор курса, к которому относится группа.
Группа будет относиться к курсам связью «многие к одному».
Также можно выделить сущность «студент». Она будет хранить в себе информацию о студенте, который пользуется порталом. Основные атрибуты: уникальный идентификатор; электронная почта (будет использоваться для подтверждения учетной записи и в качестве логина); пароль, ФИО; флаг активности учетной записи (При регистрации без подтверждения через почту - учетная запись будет неактивна), идентификатор группы, к которой относится студент.
Также можно выделить сущность «категория». Будет использоваться для разделения тестов на отдельные группы по темам. Атрибуты: уникальный идентификатор; заголовок; описание.
Следующим же этапом можно выделить сущность «Тест». Она будет связана с категорией связью «многие к одному», то есть один тест может относиться лишь к одной категории, но разные тесты могут относиться как к одной и той же категории, так и к разным. К атрибутам сущности можно отнести: уникальный идентификатор; заголовок; описание; флаг активности;
15
идентификатор категории, к которой относится тест; максимальное количество попыток прохождения теста.
Для более тонкой категоризации тестов вводится сущность тема, которая будет связана с тестами связью «многие-ко-многим» через отдельную связующую таблицу. Атрибуты: заголовок и уникальный идентификатор.
Сам по себе тест не несет в себе особой информации, поэтому для проведения тестирования понадобится еще одна сущности - «вопрос». Она будет связана с тестом связью «многие ко многим». То есть один вопрос может отно ситься к множе ству те стов. Атрибуты: уникальный идентификатор; контент вопроса; идентификатор теста, к которому относится вопрос; время, отведенное на вопрос; количество баллов за правильный ответ.
Ответы на вопросы представлены в виде отдельной сущности. Вопросы будут связаны с ответами связью один ко многим. Атрибуты: уникальный идентификатор; контент ответа; идентификатор вопроса, к которому относится ответ; флаг, указывающий на то, правильный ответ или нет.
Для допуска определенных групп студентов к решению тестов, используется сущность «прохождение».
Сущность «вопрос-тест» введена для того, чтобы была возможность привязывать один вопрос сразу к нескольким тестам, избегая дублирования.
Ну и главное, это сущность «результат», которая будет хранить в себе результат прохождения теста. Атрибуты: уникальный идентификатор; идентификатор пользователя; количество баллов, полученных за тест; (опционально) отдельным атрибутом можно хранить то, какой ответ был дан на каждый из вопросов и то, какой правильный ответ был указан в вопросе. По связям: результат будет связан с таблицей пользователей связью многие к одному, так как у одного пользователя может быть много результатов прохождения. Аналогично и со связью с сущностью тест, у каждого теста может быть множество результатов прохождения.
16
В среде Erwin создана логическая диаграмма, изображенная на рисунке
12.
Рисунок 12Логическая модель базы данных
На рисунке 13 изображена физическая схема БД, отрисованная с помощью средств DBeaver.
Рисунок 13Физическая модель базы данных
17
В листинге 1 представлен результат формирования БД в виде DDL sql. Листинг 1. Схема БД
CREATE TABLE teachers (
id uuid NOT NULL DEFAULT gen_random_uuid(), email varchar(30) NOT NULL,
"password" varchar(150) NOT NULL, first_name varchar(30) NOT NULL, last_name varchar(30) NOT NULL, active bool NOT NULL DEFAULT true,
CONSTRAINT teachers_pkey PRIMARY KEY (id)
);
CREATE TABLE courses (
id uuid NOT NULL DEFAULT gen_random_uuid(), code varchar(15) NOT null,
CONSTRAINT courses_pkey PRIMARY KEY (id)
);
create table groups (
id uuid NOT NULL DEFAULT gen_random_uuid(), code varchar(15) not null,
course_id uuid not null,
CONSTRAINT groups_pkey PRIMARY KEY (id),
CONSTRAINT courses_groups_fk FOREIGN KEY (course_id) REFERENCES courses(id)
);
CREATE TABLE students (
id uuid NOT NULL DEFAULT gen_random_uuid(), email varchar(30) NOT NULL,
"password" varchar(150) NOT NULL, first_name varchar(30) NOT NULL, last_name varchar(30) NOT NULL, active bool NOT NULL DEFAULT true, group_id uuid not null,
CONSTRAINT students_pkey PRIMARY KEY (id),
CONSTRAINT students_groups_fk FOREIGN KEY (group_id) REFERENCES groups(id)
);
CREATE TABLE categories (
id uuid NOT NULL DEFAULT gen_random_uuid(), title varchar(75) NULL,
description varchar(1000) NULL,
CONSTRAINT categories_pkey PRIMARY KEY (id),
CONSTRAINT categories_title_key UNIQUE (title)
);
create table topics (
id uuid NOT NULL DEFAULT gen_random_uuid(), title varchar(30) not null,
18
CONSTRAINT topics_pkey PRIMARY KEY (id)
);
CREATE TABLE quizzes (
id uuid NOT NULL DEFAULT gen_random_uuid(), title varchar(30) NOT NULL,
description varchar(1000) NOT NULL, active bool NOT NULL,
category_id uuid NOT NULL, owner_id uuid not null, max_attempt int4 NULL,
CONSTRAINT quizzes_pkey PRIMARY KEY (id),
CONSTRAINT quizzes_teachers_fk FOREIGN KEY (owner_id) REFERENCES teachers(id),
CONSTRAINT categories_quizzes_fk FOREIGN KEY (category_id) REFERENCES categories(id)
);
create table topics_quizzes ( topic_id uuid not null, quizz_id uuid not null,
CONSTRAINT topics_quizzes_pkey PRIMARY KEY (topic_id, quizz_id), CONSTRAINT quizzes_topics_quizzes_fk FOREIGN KEY (quizz_id)
REFERENCES quizzes(id),
CONSTRAINT topics_topics_quizzes_fk FOREIGN KEY (topic_id)
REFERENCES topics(id) );
CREATE TABLE results (
id uuid NOT NULL DEFAULT gen_random_uuid(), given_answer_by_question_id jsonb NOT NULL, quiz_id uuid NOT NULL,
student_id uuid NOT NULL, max_marks int4 NOT NULL, exam_answers jsonb NOT NULL,
CONSTRAINT results_pkey PRIMARY KEY (id),
CONSTRAINT quizzes_results_fk FOREIGN KEY (quiz_id) REFERENCES quizzes(id),
CONSTRAINT students_results_fk FOREIGN KEY (student_id) REFERENCES students(id)
);
CREATE TABLE questions (
id uuid NOT NULL DEFAULT gen_random_uuid(), "content" varchar(4000) NOT NULL,
quiz_id uuid NOT NULL, marks int4 NOT NULL, "time" int4 NOT NULL,
CONSTRAINT questions_pkey PRIMARY KEY (id),
CONSTRAINT quizzes_questions_fk FOREIGN KEY (quiz_id) REFERENCES quizzes(id)
);
19
CREATE TABLE answers (
id uuid NOT NULL DEFAULT gen_random_uuid(), "content" varchar(4000) NOT NULL, question_id uuid NOT NULL,
is_right boolean NOT NULL,
CONSTRAINT answers_pkey PRIMARY KEY (id),
CONSTRAINT answers_questions_fk FOREIGN KEY (question_id) REFERENCES questions(id)
);
create table topics_questions ( quiz_id uuid NOT null, question_id uuid NOT null,
CONSTRAINT topics_questions_topics_fk FOREIGN KEY (quiz_id) REFERENCES topics(id),
CONSTRAINT topics_questions_questions_fk FOREIGN KEY (question_id) REFERENCES questions(id)
);
create table passings ( quiz_id uuid NOT null, group_id uuid NOT null,
CONSTRAINT passings_groups_fk FOREIGN KEY (group_id) REFERENCES groups(id),
CONSTRAINT passings_questions_fk FOREIGN KEY (quiz_id) REFERENCES quizzes(id),
CONSTRAINT passings_pkey PRIMARY KEY (group_id, quiz_id)
);
20
