Files
magistr/docs/DATABASE.md

14 KiB
Raw Permalink Blame History

🗄 База данных

Общая информация

  • СУБД: PostgreSQL (локально postgres:alpine3.23, продакшн — managed PostgreSQL)
  • Управление схемой: Flyway (программный запуск)
  • Hibernate DDL: Отключён (ddl-auto=none)
  • Расширения: pgcrypto (bcrypt-хеширование паролей)
  • Мультитенантность: Каждый тенант = отдельная БД

ER-диаграмма

erDiagram
    departments {
        BIGSERIAL id PK
        VARCHAR name
        BIGINT code UK
    }
    
    specialties {
        BIGSERIAL id PK
        VARCHAR name
        VARCHAR specialty_code
    }
    
    users {
        BIGSERIAL id PK
        VARCHAR username UK
        VARCHAR password
        VARCHAR role
        VARCHAR full_name
        VARCHAR job_title
        BIGINT department_id FK
        TIMESTAMP created_at
        TIMESTAMP updated_at
    }
    
    education_forms {
        BIGSERIAL id PK
        VARCHAR name UK
        TEXT description
        TIMESTAMP created_at
    }
    
    student_groups {
        BIGSERIAL id PK
        VARCHAR name UK
        BIGINT group_size
        BIGINT education_form_id FK
        BIGINT department_id FK
        INT enrollment_year
        INT specialty_code FK
        TIMESTAMP created_at
    }
    
    subgroups {
        BIGSERIAL id PK
        BIGINT group_id FK
        VARCHAR name
        INT student_capacity
    }
    
    subjects {
        BIGSERIAL id PK
        VARCHAR name UK
        VARCHAR code
        BIGINT department_id FK
        TEXT description
        TIMESTAMP created_at
    }
    
    lesson_types {
        BIGSERIAL id PK
        VARCHAR name UK
        VARCHAR color_code
        INT duration_minutes
    }
    
    equipments {
        BIGSERIAL id PK
        VARCHAR name UK
        TEXT description
        VARCHAR inventory_number
    }
    
    classrooms {
        BIGSERIAL id PK
        VARCHAR name UK
        INT capacity
        VARCHAR building
        INT floor
        BOOLEAN is_available
        TEXT description
        TIMESTAMP created_at
    }
    
    classroom_equipments {
        BIGINT classroom_id FK,PK
        BIGINT equipment_id FK,PK
        INT quantity
        TEXT notes
    }
    
    teacher_subjects {
        BIGINT user_id FK,PK
        BIGINT subject_id FK,PK
        VARCHAR qualification_level
        INT experience_years
    }
    
    teacher_lesson_types {
        BIGINT user_id FK,PK
        BIGINT subject_id FK,PK
        BIGINT lesson_type_id FK,PK
    }
    
    lessons {
        BIGSERIAL id PK
        BIGINT teacher_id FK
        BIGINT group_id FK
        BIGINT subject_id FK
        VARCHAR lesson_format
        VARCHAR type_lesson
        BIGINT classroom_id FK
        VARCHAR day
        VARCHAR week
        VARCHAR time
    }
    
    schedule_data {
        BIGSERIAL id PK
        BIGINT department_id FK
        INT semester
        BIGINT group_id FK
        BIGINT subjects_id FK
        BIGINT lesson_type_id FK
        INT number_of_hours
        BOOLEAN is_division
        BIGINT teacher_id FK
        VARCHAR semester_type
        VARCHAR period
    }
    
    departments ||--o{ users : "department_id"
    departments ||--o{ student_groups : "department_id"
    departments ||--o{ subjects : "department_id"
    departments ||--o{ schedule_data : "department_id"
    education_forms ||--o{ student_groups : "education_form_id"
    student_groups ||--o{ subgroups : "group_id"
    student_groups ||--o{ lessons : "group_id"
    student_groups ||--o{ schedule_data : "group_id"
    users ||--o{ lessons : "teacher_id"
    users ||--o{ teacher_subjects : "user_id"
    users ||--o{ teacher_lesson_types : "user_id"
    users ||--o{ schedule_data : "teacher_id"
    subjects ||--o{ lessons : "subject_id"
    subjects ||--o{ teacher_subjects : "subject_id"
    subjects ||--o{ teacher_lesson_types : "subject_id"
    subjects ||--o{ schedule_data : "subjects_id"
    lesson_types ||--o{ teacher_lesson_types : "lesson_type_id"
    lesson_types ||--o{ schedule_data : "lesson_type_id"
    classrooms ||--o{ lessons : "classroom_id"
    classrooms ||--o{ classroom_equipments : "classroom_id"
    equipments ||--o{ classroom_equipments : "equipment_id"

Описание таблиц

Справочники высшего уровня

departments — Кафедры

Колонка Тип Описание
id BIGSERIAL PK ID кафедры
name VARCHAR(255) Название кафедры
code BIGINT UNIQUE Код кафедры

specialties — Специальности

Колонка Тип Описание
id BIGSERIAL PK ID специальности
name VARCHAR(255) Название специальности
specialty_code VARCHAR(255) Код ФГОС (напр. 10.03.01)

Пользователи

users — Пользователи системы

Колонка Тип Описание
id BIGSERIAL PK ID пользователя
username VARCHAR(50) UNIQUE Логин
password VARCHAR(255) bcrypt-хеш пароля
role VARCHAR(20) ADMIN, TEACHER, STUDENT
full_name VARCHAR(255) ФИО
job_title VARCHAR(255) Должность
department_id BIGINT FK → departments Кафедра
created_at TIMESTAMP Дата создания
updated_at TIMESTAMP Дата обновления (авто-триггер)

Триггер: update_users_updated_at автоматически обновляет updated_at при любом UPDATE.

Учебный процесс

education_forms — Формы обучения

Колонка Тип Описание
id BIGSERIAL PK ID
name VARCHAR(100) UNIQUE Название (Бакалавриат, Магистратура, Специалитет)
description TEXT Описание

student_groups — Учебные группы

Колонка Тип Описание
id BIGSERIAL PK ID
name VARCHAR(100) UNIQUE Название группы (напр. ИВТ-21-1)
group_size BIGINT Количество студентов
education_form_id BIGINT FK → education_forms Форма обучения
department_id BIGINT FK → departments Кафедра
enrollment_year INT NOT NULL Год начала обучения (напр. 2023)
specialty_code INT FK → specialties Код специальности

Примечание: Курс и семестр вычисляются динамически на основе enrollment_year и текущей даты (утилита CourseCalculator.java). В БД не хранятся.

subgroups — Подгруппы

Колонка Тип Описание
id BIGSERIAL PK ID
group_id BIGINT FK → student_groups (CASCADE) Родительская группа
name VARCHAR(100) Название подгруппы
student_capacity INT Количество студентов

subjects — Дисциплины

Колонка Тип Описание
id BIGSERIAL PK ID
name VARCHAR(200) UNIQUE Название
code VARCHAR(20) Код предмета
department_id BIGINT FK → departments Кафедра
description TEXT Описание

Аудиторный фонд

classrooms — Аудитории

Колонка Тип Описание
id BIGSERIAL PK ID
name VARCHAR(50) UNIQUE Название (напр. 101 Ленинская)
capacity INT CHECK(> 0) Вместимость
building VARCHAR(50) Корпус
floor INT Этаж
is_available BOOLEAN Доступна для назначения пар
description TEXT Описание

equipments — Оборудование

Колонка Тип Описание
id BIGSERIAL PK ID
name VARCHAR(50) UNIQUE Название
description TEXT Описание
inventory_number VARCHAR(50) Инвентарный номер

classroom_equipments — Привязка оборудования к аудиториям

Колонка Тип Описание
classroom_id BIGINT PK, FK → classrooms (CASCADE) Аудитория
equipment_id BIGINT PK, FK → equipments (CASCADE) Оборудование
quantity INT CHECK(> 0) Количество единиц
notes TEXT Примечания

Расписание

lessons — Основное расписание занятий

Колонка Тип Описание
id BIGSERIAL PK ID
teacher_id BIGINT FK → users Преподаватель
group_id BIGINT FK → student_groups Группа
subject_id BIGINT FK → subjects Дисциплина
lesson_format VARCHAR(255) Очно / Онлайн
type_lesson VARCHAR(255) Лекция / Практическая работа / Лабораторная работа
classroom_id BIGINT FK → classrooms Аудитория
day VARCHAR(255) День недели
week VARCHAR(255) Верхняя / Нижняя / Обе
time VARCHAR(255) Временной слот

lesson_types — Типы занятий (справочник)

Колонка Тип Описание
id BIGSERIAL PK ID
name VARCHAR(50) UNIQUE Название типа
color_code VARCHAR(7) HEX-цвет для UI (напр. #FF6B6B)
duration_minutes INT Длительность (по умолчанию 90)

Связи «Преподаватель ↔ Дисциплина»

teacher_subjects — Квалификация преподавателей

Колонка Тип Описание
user_id BIGINT PK, FK → users (CASCADE) Преподаватель
subject_id BIGINT PK, FK → subjects (CASCADE) Дисциплина
qualification_level VARCHAR(50) Уровень квалификации
experience_years INT Стаж

teacher_lesson_types — Типы занятий преподавателя

Колонка Тип Описание
user_id BIGINT PK, FK → users (CASCADE) Преподаватель
subject_id BIGINT PK, FK → subjects (CASCADE) Дисциплина
lesson_type_id BIGINT PK, FK → lesson_types (CASCADE) Тип занятия

schedule_data — Данные к составлению расписания

Колонка Тип Описание
id BIGSERIAL PK ID
department_id BIGINT FK → departments Кафедра
semester INT Номер семестра
group_id BIGINT FK → student_groups Группа
subjects_id BIGINT FK → subjects Дисциплина
lesson_type_id BIGINT FK → lesson_types Тип занятия
number_of_hours INT Количество часов
is_division BOOLEAN Деление на подгруппы
teacher_id BIGINT FK → users Преподаватель
semester_type VARCHAR(255) Весенний / Осенний
period VARCHAR(255) Учебный год

Flyway миграции

Правила работы

  1. Все миграции находятся в backend/src/main/resources/db/migration/
  2. Формат имени: V{номер}__{описание}.sql (напр. V1__init.sql, V2__add_departments.sql)
  3. ЗАПРЕЩЕНО изменять уже закоммиченные файлы миграций — это сломает контрольные суммы Flyway
  4. Flyway запускается программно при первом обращении к БД тенанта (TenantConfigWatcher.initDatabaseForTenant())
  5. Настройка baselineOnMigrate=true — если в БД уже есть данные, Flyway начнёт с baseline

Текущие миграции

Файл Описание
V1__init.sql Инициализация: все таблицы, тестовые данные, триггеры, комментарии
V2__editScheduleData.sql Добавление specialty_code, тестовые данные расписания, замена courseenrollment_year

Накатывание на существующих тенантов

Для применения новой миграции к уже существующим тенантам необходимо перезапустить backend:

# Kubernetes
kubectl rollout restart deployment backend -n magistr

# Docker Compose (локально)
docker compose restart backend

Полный сброс БД (локально)

docker compose down -v    # Удаляет volumes (данные)
docker compose up -d      # Пересоздаёт БД с нуля