386 lines
18 KiB
PL/PgSQL
Executable File
386 lines
18 KiB
PL/PgSQL
Executable File
-- ==========================================
|
||
-- Инициализация расширений
|
||
-- ==========================================
|
||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||
|
||
-- ===============================
|
||
-- Справочники высшего уровня
|
||
-- ===============================
|
||
CREATE TABLE IF NOT EXISTS departments (
|
||
id BIGSERIAL UNIQUE PRIMARY KEY NOT NULL,
|
||
name VARCHAR(255) NOT NULL,
|
||
code BIGINT UNIQUE NOT NULL
|
||
);
|
||
|
||
INSERT INTO departments (name, code) VALUES
|
||
('Кафедра ИБ', 1),
|
||
('Кафедра ВТ', 2),
|
||
('Кафедра КТ', 3);
|
||
|
||
CREATE TABLE IF NOT EXISTS specialties (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
name VARCHAR(255) NOT NULL,
|
||
specialty_code VARCHAR(255) NOT NULL
|
||
);
|
||
|
||
INSERT INTO specialties (name, specialty_code) VALUES
|
||
('Информационная безопасность', '10.03.01'),
|
||
('Информатика и вычислительная техника', '09.03.01'),
|
||
('Программная инженерия', '09.03.04');
|
||
|
||
-- ==========================================
|
||
-- Пользователи и роли
|
||
-- ==========================================
|
||
CREATE TABLE IF NOT EXISTS users (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
username VARCHAR(50) UNIQUE NOT NULL,
|
||
password VARCHAR(255) NOT NULL,
|
||
role VARCHAR(20) NOT NULL DEFAULT 'STUDENT',
|
||
full_name VARCHAR(255) NOT NULL,
|
||
job_title VARCHAR(255) NOT NULL,
|
||
department_id BIGINT NOT NULL REFERENCES departments(id),
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
-- Админ по умолчанию: admin / admin (bcrypt через pgcrypto)
|
||
INSERT INTO users (username, password, role, full_name, job_title, department_id)
|
||
VALUES ('admin', crypt('admin', gen_salt('bf', 10)), 'ADMIN', 'Иванов Админ Иванович', 'Доцент', 1),
|
||
('Тестовый преподаватель', crypt('1234567890', gen_salt('bf', 10)), 'TEACHER', 'Петров Препод Петрович', 'Профессор', 2)
|
||
ON CONFLICT (username) DO NOTHING;
|
||
|
||
-- ==========================================
|
||
-- Образовательные формы
|
||
-- ==========================================
|
||
CREATE TABLE IF NOT EXISTS education_forms (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
name VARCHAR(100) UNIQUE NOT NULL,
|
||
description TEXT,
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
INSERT INTO education_forms (name) VALUES
|
||
('Бакалавриат'),
|
||
('Магистратура'),
|
||
('Специалитет')
|
||
ON CONFLICT (name) DO NOTHING;
|
||
|
||
-- ==========================================
|
||
-- Учебные группы
|
||
-- ==========================================
|
||
CREATE TABLE IF NOT EXISTS student_groups (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
name VARCHAR(100) UNIQUE NOT NULL,
|
||
group_size BIGINT NOT NULL,
|
||
education_form_id BIGINT NOT NULL REFERENCES education_forms(id),
|
||
department_id BIGINT NOT NULL REFERENCES departments(id),
|
||
course INT CHECK (course BETWEEN 1 AND 6),
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
-- Тестовая базовая группа для работы
|
||
INSERT INTO student_groups (name, group_size, education_form_id, department_id, course)
|
||
VALUES ('ИВТ-21-1', 25, 1, 1, 3),
|
||
('ИБ-41м', 15, 2, 1, 2)
|
||
ON CONFLICT (name) DO NOTHING;
|
||
|
||
-- ==========================================
|
||
-- Подгруппы (например: "ИВТ-21-1 Подгруппа 1")
|
||
-- ==========================================
|
||
CREATE TABLE IF NOT EXISTS subgroups (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
group_id BIGINT NOT NULL REFERENCES student_groups(id) ON DELETE CASCADE,
|
||
name VARCHAR(100) NOT NULL,
|
||
student_capacity INT,
|
||
UNIQUE(group_id, name)
|
||
);
|
||
|
||
-- ==========================================
|
||
-- Справочники
|
||
-- ==========================================
|
||
|
||
-- Дисциплины
|
||
CREATE TABLE IF NOT EXISTS subjects (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
name VARCHAR(200) UNIQUE NOT NULL,
|
||
code VARCHAR(20),
|
||
department_id BIGINT NOT NULL REFERENCES departments(id),
|
||
description TEXT,
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
INSERT INTO subjects (name, department_id) VALUES
|
||
('Высшая математика', 1),
|
||
('Философия', 1),
|
||
('Информатика', 1),
|
||
('Базы данных', 1),
|
||
('Английский язык', 1)
|
||
ON CONFLICT (name) DO NOTHING;
|
||
|
||
-- Типы занятий
|
||
CREATE TABLE IF NOT EXISTS lesson_types (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
name VARCHAR(50) UNIQUE NOT NULL,
|
||
color_code VARCHAR(7) DEFAULT '#3788d8',
|
||
duration_minutes INT DEFAULT 90
|
||
);
|
||
|
||
INSERT INTO lesson_types (name, color_code) VALUES
|
||
('Лекция', '#FF6B6B'),
|
||
('Практика', '#4ECDC4'),
|
||
('Лабораторная работа', '#45B7D1')
|
||
ON CONFLICT (name) DO NOTHING;
|
||
|
||
-- Оборудование
|
||
CREATE TABLE IF NOT EXISTS equipments (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
name VARCHAR(50) UNIQUE NOT NULL,
|
||
description TEXT,
|
||
inventory_number VARCHAR(50)
|
||
);
|
||
|
||
INSERT INTO equipments (name) VALUES
|
||
('Проектор'),
|
||
('ПК'),
|
||
('Лаборатория'),
|
||
('Интерактивная доска'),
|
||
('Документ-камера'),
|
||
('Аудиосистема')
|
||
ON CONFLICT (name) DO NOTHING;
|
||
|
||
-- Аудитории
|
||
CREATE TABLE IF NOT EXISTS classrooms (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
name VARCHAR(50) UNIQUE NOT NULL,
|
||
capacity INT NOT NULL CHECK (capacity > 0),
|
||
building VARCHAR(50),
|
||
floor INT,
|
||
is_available BOOLEAN DEFAULT TRUE,
|
||
description TEXT,
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
INSERT INTO classrooms (name, capacity, building, floor) VALUES
|
||
('101 Ленинская', 120, 'Главный корпус', 1),
|
||
('202 IT Lab', 20, 'Корпус IT', 2),
|
||
('303 Обычная', 30, 'Главный корпус', 3)
|
||
ON CONFLICT (name) DO NOTHING;
|
||
|
||
-- Привязка оборудования к аудиториям (Many-to-Many)
|
||
CREATE TABLE IF NOT EXISTS classroom_equipments (
|
||
classroom_id BIGINT NOT NULL REFERENCES classrooms(id) ON DELETE CASCADE,
|
||
equipment_id BIGINT NOT NULL REFERENCES equipments(id) ON DELETE CASCADE,
|
||
quantity INT DEFAULT 1 CHECK (quantity > 0),
|
||
notes TEXT,
|
||
PRIMARY KEY (classroom_id, equipment_id)
|
||
);
|
||
|
||
INSERT INTO classroom_equipments (classroom_id, equipment_id, quantity)
|
||
SELECT c.id, e.id,
|
||
CASE
|
||
WHEN e.name = 'ПК' AND c.name = '202 IT Lab' THEN 15
|
||
WHEN e.name = 'ПК' THEN 1
|
||
ELSE 1
|
||
END
|
||
FROM classrooms c, equipments e
|
||
WHERE
|
||
(c.name = '101 Ленинская' AND e.name IN ('Проектор', 'Интерактивная доска', 'Аудиосистема'))
|
||
OR (c.name = '202 IT Lab' AND e.name IN ('ПК', 'Проектор', 'Лаборатория', 'Интерактивная доска'))
|
||
OR (c.name = '303 Обычная' AND e.name IN ('Проектор'))
|
||
ON CONFLICT (classroom_id, equipment_id) DO NOTHING;
|
||
|
||
-- ==========================================
|
||
-- Связи для преподавателей
|
||
-- ==========================================
|
||
|
||
CREATE TABLE IF NOT EXISTS teacher_subjects (
|
||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||
subject_id BIGINT NOT NULL REFERENCES subjects(id) ON DELETE CASCADE,
|
||
qualification_level VARCHAR(50),
|
||
experience_years INT,
|
||
PRIMARY KEY(user_id, subject_id)
|
||
);
|
||
|
||
CREATE TABLE IF NOT EXISTS teacher_lesson_types (
|
||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||
subject_id BIGINT NOT NULL REFERENCES subjects(id) ON DELETE CASCADE,
|
||
lesson_type_id BIGINT NOT NULL REFERENCES lesson_types(id) ON DELETE CASCADE,
|
||
PRIMARY KEY (user_id, subject_id, lesson_type_id)
|
||
);
|
||
|
||
-- ==========================================
|
||
-- Основная таблица Расписания (Lessons)
|
||
-- ==========================================
|
||
CREATE TABLE IF NOT EXISTS lessons (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
teacher_id BIGINT NOT NULL REFERENCES users(id),
|
||
group_id BIGINT NOT NULL REFERENCES student_groups(id),
|
||
subject_id BIGINT NOT NULL REFERENCES subjects(id),
|
||
lesson_format VARCHAR(255) NOT NULL,
|
||
type_lesson VARCHAR(255) NOT NULL,
|
||
classroom_id BIGINT NOT NULL REFERENCES classrooms(id),
|
||
day VARCHAR(255) NOT NULL,
|
||
week VARCHAR(255) NOT NULL,
|
||
time VARCHAR(255) NOT NULL
|
||
);
|
||
|
||
INSERT INTO lessons (teacher_id, group_id, subject_id, lesson_format, type_lesson, classroom_id, day, week, time) VALUES
|
||
(2, 1, 1, 'Очно', 'Лекция', 1, 'Понедельник', 'Верхняя', '11:40 - 13:10'),
|
||
(1, 1, 2, 'Онлайн', 'Практическая работа', 2, 'Вторник', 'Нижняя', '15:00 - 16:30'),
|
||
(2, 1, 3, 'Очно', 'Лабораторная работа', 3, 'Среда', 'Верхняя', '8:00 - 9:30'),
|
||
(1, 1, 4, 'Онлайн', 'Лекция', 1, 'Четверг', 'Нижняя', '11:40 - 13:10'),
|
||
(2, 1, 5, 'Очно', 'Практическая работа', 2, 'Пятница', 'Верхняя', '15:00 - 16:30'),
|
||
(1, 1, 3, 'Онлайн', 'Лабораторная работа', 3, 'Суббота', 'Нижняя', '8:00 - 9:30');
|
||
|
||
-- ===============================
|
||
-- Создание таблицы данных расписания (schedule_data)
|
||
-- ===============================
|
||
CREATE TABLE IF NOT EXISTS schedule_data (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
department_id BIGINT NOT NULL REFERENCES departments(id),
|
||
semester INT NOT NULL,
|
||
group_id BIGINT NOT NULL REFERENCES student_groups(id),
|
||
subjects_id BIGINT NOT NULL REFERENCES subjects(id),
|
||
lesson_type_id BIGINT NOT NULL REFERENCES lesson_types(id),
|
||
number_of_hours INT NOT NULL,
|
||
is_division BOOLEAN NOT NULL DEFAULT FALSE,
|
||
teacher_id BIGINT NOT NULL REFERENCES users(id),
|
||
semester_type VARCHAR(255) NOT NULL,
|
||
period VARCHAR(255) NOT NULL
|
||
);
|
||
|
||
INSERT INTO schedule_data (department_id, semester, group_id, subjects_id, lesson_type_id, number_of_hours, is_division, teacher_id, semester_type, period)
|
||
VALUES (1, 1, 1, 1, 3, 2, true, 1, 'Весенний', '2024/2025'),
|
||
(2, 4, 2, 3, 2, 1, false, 2, 'Осенний', '2025/2026'),
|
||
(3, 5, 1, 2, 1, 3, true, 1, 'Весенний', '2023/2024');
|
||
|
||
-- ==========================================
|
||
-- Функция обновления timestamp
|
||
-- ==========================================
|
||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||
RETURNS TRIGGER AS $$
|
||
BEGIN
|
||
NEW.updated_at = CURRENT_TIMESTAMP;
|
||
RETURN NEW;
|
||
END;
|
||
$$ LANGUAGE plpgsql;
|
||
|
||
CREATE TRIGGER update_users_updated_at
|
||
BEFORE UPDATE ON users
|
||
FOR EACH ROW
|
||
EXECUTE FUNCTION update_updated_at_column();
|
||
|
||
-- ==========================================
|
||
-- Комментарии к таблицам и полям (для документации)
|
||
-- ==========================================
|
||
COMMENT ON TABLE users IS 'Пользователи системы (студенты, преподаватели, администраторы)';
|
||
COMMENT ON TABLE lessons IS 'Основное расписание занятий';
|
||
COMMENT ON TABLE departments IS 'Кафедры';
|
||
COMMENT ON TABLE specialties IS 'Специальности';
|
||
COMMENT ON TABLE schedule_data IS 'Данные к составлению расписания';
|
||
COMMENT ON COLUMN schedule_data.department_id IS 'Идентификатор кафедры';
|
||
COMMENT ON COLUMN schedule_data.semester IS 'Номер семестра';
|
||
COMMENT ON COLUMN schedule_data.group_id IS 'Идентификатор группы';
|
||
COMMENT ON COLUMN schedule_data.subjects_id IS 'Идентификатор предмета';
|
||
COMMENT ON COLUMN schedule_data.lesson_type_id IS 'Идентификатор типа занятия';
|
||
COMMENT ON COLUMN schedule_data.number_of_hours IS 'Количество часов';
|
||
COMMENT ON COLUMN schedule_data.is_division IS 'Является ли занятие разделенным';
|
||
COMMENT ON COLUMN schedule_data.teacher_id IS 'Идентификатор преподавателя';
|
||
COMMENT ON COLUMN schedule_data.semester_type IS 'Тип семестра (Весенний, Осенний)';
|
||
COMMENT ON COLUMN schedule_data.period IS 'Период занятий (год/год)';
|
||
|
||
COMMENT ON TABLE education_forms IS 'Формы обучения';
|
||
COMMENT ON TABLE subgroups IS 'Подгруппы';
|
||
COMMENT ON TABLE lesson_types IS 'Типы занятий';
|
||
COMMENT ON TABLE equipments IS 'Оборудование';
|
||
COMMENT ON TABLE classrooms IS 'Аудитории';
|
||
COMMENT ON TABLE classroom_equipments IS 'Привязка оборудования к аудиториям';
|
||
COMMENT ON TABLE teacher_subjects IS 'Привязка преподавателей к дисциплинам';
|
||
COMMENT ON TABLE teacher_lesson_types IS 'Типы занятий преподавателя';
|
||
|
||
COMMENT ON COLUMN users.id IS 'ID пользователя';
|
||
COMMENT ON COLUMN users.username IS 'Логин пользователя';
|
||
COMMENT ON COLUMN users.password IS 'Хэш пароля пользователя';
|
||
COMMENT ON COLUMN users.role IS 'Роль пользователя';
|
||
COMMENT ON COLUMN users.created_at IS 'Дата и время создания';
|
||
COMMENT ON COLUMN users.updated_at IS 'Дата и время последнего обновления';
|
||
COMMENT ON COLUMN users.full_name IS 'ФИО пользователя';
|
||
COMMENT ON COLUMN users.job_title IS 'Должность пользователя';
|
||
COMMENT ON COLUMN users.department_id IS 'ID кафедры';
|
||
|
||
COMMENT ON COLUMN education_forms.id IS 'ID формы обучения';
|
||
COMMENT ON COLUMN education_forms.name IS 'Название формы обучения';
|
||
COMMENT ON COLUMN education_forms.description IS 'Описание';
|
||
COMMENT ON COLUMN education_forms.created_at IS 'Дата и время создания';
|
||
|
||
COMMENT ON COLUMN student_groups.id IS 'ID учебной группы';
|
||
COMMENT ON COLUMN student_groups.name IS 'Название группы';
|
||
COMMENT ON COLUMN student_groups.group_size IS 'Количество студентов';
|
||
COMMENT ON COLUMN student_groups.education_form_id IS 'ID формы обучения, к которой относится группа';
|
||
COMMENT ON COLUMN student_groups.department_id IS 'ID кафедры';
|
||
COMMENT ON COLUMN student_groups.course IS 'Курс';
|
||
COMMENT ON COLUMN student_groups.created_at IS 'Дата и время создания';
|
||
|
||
COMMENT ON COLUMN subgroups.id IS 'ID подгруппы';
|
||
COMMENT ON COLUMN subgroups.group_id IS 'ID учебной группы, к которой относится подгруппа';
|
||
COMMENT ON COLUMN subgroups.name IS 'Название подгруппы';
|
||
COMMENT ON COLUMN subgroups.student_capacity IS 'Количество студентов в подгруппе';
|
||
|
||
COMMENT ON COLUMN subjects.id IS 'ID предмета';
|
||
COMMENT ON COLUMN subjects.name IS 'Название предмета';
|
||
COMMENT ON COLUMN subjects.code IS 'Код предмета';
|
||
COMMENT ON COLUMN subjects.department_id IS 'ID кафедры';
|
||
COMMENT ON COLUMN subjects.description IS 'Описание предмета';
|
||
COMMENT ON COLUMN subjects.created_at IS 'Дата и время создания';
|
||
|
||
COMMENT ON COLUMN lesson_types.id IS 'ID урока';
|
||
COMMENT ON COLUMN lesson_types.name IS 'Название типа урока';
|
||
COMMENT ON COLUMN lesson_types.color_code IS 'Цветовой код для типа урока';
|
||
COMMENT ON COLUMN lesson_types.duration_minutes IS 'Длительность урока в минутах';
|
||
|
||
COMMENT ON COLUMN equipments.id IS 'ID оборудования';
|
||
COMMENT ON COLUMN equipments.name IS 'Название оборудования';
|
||
COMMENT ON COLUMN equipments.description IS 'Описание оборудования';
|
||
COMMENT ON COLUMN equipments.inventory_number IS 'Инвентарный номер оборудования';
|
||
|
||
COMMENT ON COLUMN classrooms.id IS 'ID аудитории';
|
||
COMMENT ON COLUMN classrooms.name IS 'Название аудитории';
|
||
COMMENT ON COLUMN classrooms.capacity IS 'Вместимость аудитории';
|
||
COMMENT ON COLUMN classrooms.building IS 'Корпус';
|
||
COMMENT ON COLUMN classrooms.floor IS 'Этаж';
|
||
COMMENT ON COLUMN classrooms.is_available IS 'Доступность аудитории';
|
||
COMMENT ON COLUMN classrooms.description IS 'Описание аудитории';
|
||
COMMENT ON COLUMN classrooms.created_at IS 'Дата и время создания';
|
||
|
||
COMMENT ON COLUMN classroom_equipments.classroom_id IS 'ID аудитории';
|
||
COMMENT ON COLUMN classroom_equipments.equipment_id IS 'ID оборудования';
|
||
COMMENT ON COLUMN classroom_equipments.quantity IS 'Дата и время создания'; -- Так было в V2
|
||
COMMENT ON COLUMN classroom_equipments.notes IS 'Примечания к записи';
|
||
|
||
COMMENT ON COLUMN teacher_subjects.user_id IS 'ID преподавателя';
|
||
COMMENT ON COLUMN teacher_subjects.subject_id IS 'ID предмета';
|
||
COMMENT ON COLUMN teacher_subjects.qualification_level IS 'Уровень квалификации преподавателя';
|
||
COMMENT ON COLUMN teacher_subjects.experience_years IS 'Опыт преподавания';
|
||
|
||
COMMENT ON COLUMN lessons.id IS 'ID урока';
|
||
COMMENT ON COLUMN lessons.teacher_id IS 'Идентификатор преподавателя, который проводит урок';
|
||
COMMENT ON COLUMN lessons.group_id IS 'ID группы, в которой проходит урок';
|
||
COMMENT ON COLUMN lessons.subject_id IS 'ID предмета, который преподается';
|
||
COMMENT ON COLUMN lessons.lesson_format IS 'Формат урока';
|
||
COMMENT ON COLUMN lessons.type_lesson IS 'Тип урока';
|
||
COMMENT ON COLUMN lessons.classroom_id IS 'ID аудитории, в которой проходит урок';
|
||
COMMENT ON COLUMN lessons.day IS 'День недели, в который проходит урок';
|
||
COMMENT ON COLUMN lessons.week IS 'Номер недели, в которой проходит урок';
|
||
COMMENT ON COLUMN lessons.time IS 'Время урока';
|
||
|
||
COMMENT ON COLUMN departments.id IS 'ID кафедры';
|
||
COMMENT ON COLUMN departments.name IS 'Название кафедры';
|
||
COMMENT ON COLUMN departments.code IS 'Код кафедры';
|
||
|
||
COMMENT ON COLUMN specialties.id IS 'ID специальности';
|
||
COMMENT ON COLUMN specialties.name IS 'Название специальности';
|
||
COMMENT ON COLUMN specialties.specialty_code IS 'Код специальности';
|
||
|
||
COMMENT ON COLUMN teacher_lesson_types.user_id IS 'ID преподавателя';
|
||
COMMENT ON COLUMN teacher_lesson_types.subject_id IS 'ID предмета';
|
||
COMMENT ON COLUMN teacher_lesson_types.lesson_type_id IS 'ID типа занятия'; |