@adiletmurzaliev

Проектирование БД электронного журнала?

В целях саморазвития поставил себе задачу создать приложение, представляющее собой электронный журнал школы.
Реализовал большую часть задумки на Yii2, потом столкнулся с проблемой обновления оценок в базе.
Имеется следующая структура БД:
59cecbcc6fcd5012662171.png рис. 1
Соответственно таблица current_score (текущая оценка) будет заполняться следующим образом (с 1/09 по 31/05):
59cecc68b7649316325517.pngрис. 2
Моей задачей было создать журнал, который может заполняться учителем в разрезе предметов и учеников. Т.о. форма для ввода оценок будет такая:
59ceccd34137e389376823.pngрис. 3
И вот на этом моменте я остановился. Получается так, что при отправке POST запроса на обновление формы будут выполняться 3 операции с БД (таблица current_score): CREATE, UPDATE, DELETE. Иными словами, если были проставлены новые оценки - создаются соответствующие записи, если были удалены оценки из ячеек формы - данные записи удаляются, и обычное обновление.
Чтобы не обрабатывать 3 операции, я рассматривал различные варианты, такие как:
  1. При POST запросе первым делом удалять все данные по id студенту/предмету и потом записывать данные с запроса (получается 2 операции). В таком случае при неудачной записи данных, можно потерять все предыдущие данных об оценках, я думаю.
  2. Заранее создать "пустые" записи без оценок в таблице для каждой даты с 1/09 по 31/05 (учебный год, 270 дней где-то). Но возникает проблема с оптимальностью использования БД, думаю пустых ячеек с оценками не должно быть.

Искал в интернете что-то подобное, где ввод данных осуществляется в табличном виде и может обладать переменным количеством столбцов (дат). Ничего подобного не нашел.
Подскажите пожалуйста, как бы Вы реализовали ввод данных в журнал (рис. 3).
  • Вопрос задан
  • 3726 просмотров
Решения вопроса 2
@TheLostRoot
C# ASP.NET developer
Не нужно тут ничего мудрить делай 3 операции и все. Не ориентируйся на количество операций. Смотри на стоимость их выполнения.

При POST запросе первым делом удалять все данные по id студенту/предмету и потом записывать данные с запроса (получается 2 операции).

Представь сколько за год у студента будет оценок и при каждом редактировании их все удалять? А если много пользователей начнут редактировать одновременно? Ждать пока каждый удалит все свои оценки, а потом опять запишет? Имхо дурацкий подход.
Ответ написан
Wolfnsex
@Wolfnsex
Если не хочешь быть первым - не вставай в очередь!
Откровенно говоря, не совсем понятно чего Вы хотите добиться... Вернее, в чем именно проблема?

При POST запросе первым делом удалять все данные по id студенту/предмету и потом записывать данные с запроса (получается 2 операции). В таком случае при неудачной записи данных, можно потерять все предыдущие данных об оценках, я думаю.
Что бы ничего не потерялось "при записи" - есть "транзакции" (рекомендую с ними ознакомиться", но вкратце, суть такая - что либо операция будет выполнена полностью, либо она не будет выполнена вообще, т.е. произойдёт "откат" до того состояния, в котором данные были до начала транзакции).

Заранее создать "пустые" записи без оценок в таблице для каждой даты с 1/09 по 31/05 (учебный год, 270 дней где-то). Но возникает проблема с оптимальностью использования БД, думаю пустых ячеек с оценками не должно быть.
Я думаю так же (что пустых записей [про какие ячейки идёт речь - я пока не понял]) - быть не должно. Ещё я думаю, что плодить колонки в БД - тоже плохое решение, если в них нет реальной необходимости. MySQL (как и многие другие) поддерживает механизм "реляций" (по русски - "связей"), то есть позволяет связывать одни данные с другими и контролировать целостность (корректность) таких связей. То есть, Вы можете связать воедино многомерную модель данных, например студента, предмет, преподавателя, дату, оценку и так далее, при том, что предметы хранятся в одной таблице, преподаватели в другой, оценки с датами в третьей (и т.д.) а их совокупности - в N'ой (в данном случае, в 4-ой) таблице.

Как уже верно заметил г-н. TheLostRoot, не стоит ориентироваться на кол-во операций, Вы пытаетесь оптимизировать что-то, но не с той стороны. Если у Вас много данных которые вставляются (хранятся), но доступ к ним осуществляется редко - есть специальные архивные таблицы, если Вам не нужен контроль целостности, связи, транзакции и т.д., а нужна скорость - есть MyISAM таблицы, если у Вас сервер не выдерживает нагрузку - есть такая штука как "мониторинг ресурсов" с целью выявления узких в его производительности, есть репликация и так далее.

Оптимизируют обычно сложные запросы, в которых участвует множество таблиц/данных, а не простые INSERT/UPDATE/DELETE'ы. Проблема не в количестве операций как таковом (к тому же, при DELETE - физически данные с диска не удаляются, а отмечаются как "удаленные" [в MySQL и не только]), а в их "сложности" и производительности. Иными словами, не пытайтесь решить проблемы подобного рода "заранее", т.к. они возможно не настанут вообще никогда, гораздо разумнее правильно спроектировать БД, чем "нагородить огород" и "сэкономить 1 (условную) операцию". Ну и не забывайте про то, что InnoDB и его аналоги (а так же некоторые другие типы таблиц в MySQL) поддерживают транзакции.

P.S. По возможности, всегда передавайте те данные, которые реально изменились, а не всё подряд. Например, данные о добавлении/изменении/удалении какой-то оценки, это сократит и бесполезную нагрузку на БД и позволит избежать "странных" ошибок в будущем (исключения конечно тоже бывают, но это не Ваш случай).
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
DirecTwiX
@DirecTwiX
"display: flex;" уже предлагали?
Переписывать весь журнал - та ещё затея. С клиента передавать три массива - добавленные оценки, измененные, удаленные.

И не помешает научится отмечать верные ответы в качестве решения.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы