|
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
|
||||||
.NET 4.x Как опитмально поступить в передаче состояния у наследников (foreignkey)03.06.2021, 08:59. Показов 3905. Ответов 55
Всем доброе утро!!!
Представим вот такую задачу. Есть некая онлайн школа допустим программирования. В ней есть несколько курсов по разным ЯП (таблица Course). Есть студенты (таблица Student), которые могут состоять ТОЛЬКО в одном курсе. То есть ТОЛЬКО один язык. В кажом курсе может быть до 1000 студентов. Есть структура базы
У каждого студента есть свой статус/состояние учёбы в этом курсе. Статусов ограниченное количество, поэтому они вынесены в код C# в enum, а в базу передаётся только число этого enum для оптимизации работы БД. Допустим Принят = 0, Сдал = 1, Должник = 2, Не Сдал = 3, Отсутствовал = 4, Так вот задача. В таблицу Course нужно передавать статус от всех студентов. Вот что я имею в виду: Есть курс "Программирование C#". Есть 2 студента в этом курсе. Вася со статусом "Не Сдал" = 3 Петя со статусом "Сдал" = 1 Нужно установить статус курсу, по самому безотвественному студенту, так как курс не может быть закрыт/закончен (со статусом "Сдал" = 1) до тех пор пока хоть один студент находится в другом состоянии. Логика должна быть примерно такая: Если в курсе есть хоть один студент (Student.Status) который в статусе Отсутствовал = 4, то и в Course.Status должно быть Отсутствовал = 4. Если есть хоть один Student.Status Не Сдал = 3, то и в Course.Status должно быть Не Сдал = 3. Если есть хоть один Student.Status Должник = 2, то и в Course.Status должно быть Должник = 2. Если есть хоть один Student.Status Сдал = 1, то и в Course.Status должно быть Сдал = 1. Если есть хоть один Student.Status Принят = 0, то и в Course.Status должно быть Принят = 0. Данные в таблице по студентам обновляются каждый час. То есть каждый час, после обновления таблицы Student нужно проверять статусы наследников, и устанавливать новые статусы в таблицу Course. Данных в таблице (Student) будет более 10млн. И данных в таблице (Course) будет больше 1млн. Как это сделать с минимальной выгрузкой всех данных в программу? Или ещё лучше как сформировать запрос SQL чтобы это всё происходило на стороне СУБД, без получения данных в программу. Или может SQL запрос который получает полуобработанные данные вида: CourseId - Status(уже проверенный) Или может уже существует подход к такой задаче. p.s. Используется MySQL база и библиотека linq2db.
0
|
||||||
| 03.06.2021, 08:59 | |
|
Ответы с готовыми решениями:
55
Фильтрация ForeignKey поля по другому ForeignKey полю в админке Как добавить ключ FOREIGNKEY в таблицу?
|
|
Модератор
|
||||||||
| 03.06.2021, 10:23 | ||||||||
|
Но в этом я ничего вам подсказать не могу. Изучал его лет тридцать назад - уже всё забыл. Добавлено через 14 минут На Шарпе это будет без больших проблем. Что-то в таком духе:
В разделе, думаю, смогут подсказать как правильно это сделать на стороне сервера.
1
|
||||||||
|
800 / 583 / 207
Регистрация: 21.02.2019
Сообщений: 2,095
|
||||||
| 03.06.2021, 10:28 | ||||||
|
BeginnerCoderCS,
.. ваша логика не совсем понятна ... если статус курса устанавливается по "самому безответственному", т.е. прогульщику со статусом 4, то тогда можно что-то типа
2
|
||||||
|
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
|
|||
| 03.06.2021, 10:39 [ТС] | |||
|
Но в любом случае спасибо за отклик. Добавлено через 8 минут В примере так получилось случайно. Нельзя привязываться к возростанию порядкового номера. Допустим важность статуса должна быть в таком порядке Принят = 0 Отсутствовал = 4 Должник = 2 Не Сдал = 3 Сдал = 1 Если есть хоть один студент со статусом Принят = 0, то курсу установим Принят = 0, Если есть хоть один студент со статусом Отсутствовал = 4 то курсу установим Отсутствовал = 4 и т.д. Так как в будущем может измениться логика наследования статуса, и порядок важности статусов будет другим. То есть без привязки возрастания числа.
0
|
|||
|
Модератор
|
||
| 03.06.2021, 10:48 | ||
|
BeginnerCoderCS, дополнение к ответу от carrotik.
Наверное, имеет смысл в таблице Студентов задать дополнительную индексацию по сочетанию ключей CourseId и Status. В таком случае необходимо для минимального/максимального Статуса выбрать только одну первую/последнюю запись по этому индексу. Добавлено через 8 минут Как запрос должен определить приоритеты статусов? Он же не может "залезть в голову" и догадаться какой из них выше - какой ниже. Приоритет должен быть либо неявно задан значением самого Статуса. Либо необходима ещё одна дополнительная таблица, по которой определяется приоритетность Статусов.
1
|
||
|
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
|
|||
| 03.06.2021, 10:56 [ТС] | |||
|
Это не частая задача, но это будет, так как будут добавляться новые статусы, и они могут быть как выше, так и ниже в приоритете.
0
|
|||
|
800 / 583 / 207
Регистрация: 21.02.2019
Сообщений: 2,095
|
||
| 03.06.2021, 10:56 | ||
|
..но в любом случае можно использовать where status <> 3 or .....
1
|
||
|
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
|
|||||||
| 03.06.2021, 11:54 [ТС] | |||||||
|
Если учесть что приоритет вот такой. Чем выше тем важнее. Принят = 0 Отсутствовал = 4 Должник = 2 Не Сдал = 3 Сдал = 1 Пример 1: В курсе "C#" 100 студентов. Из них 50 студентов Сдал = 1 49 студентов Должник = 2 1 студент Отсутствовал = 4 Значит Курсу "C#" присвоить статус Отсутствовал = 4, так как статус Отсутствовал = 4 из всех имеющихся в курсе выше всего в приоритете. Пример 2: В курсе "Java" 1000 студентов. Из них 500 студентов Сдал = 1 450 студентов Принят = 0 49 студентов Не Сдал 1 студент Отсутствовал = 4 Значит Курсу "Java" присвоить статус Принят = 0, так как статус Принят = 0 из всех имеющихся в курсе выше всего в приоритете. Пример 3: В курсе "SQL" 100 студентов. Из них 99 студентов Сдал = 1 1 студент Не Сдал = 3 Значит Курсу "SQL" присвоить статус Не Сдал = 3, так как статус Не Сдал = 3 из всех имеющихся в курсе выше всего в приоритете. Желательно не смотрите на логику самого статуса (принят или сдал), а просто на последовательность важности. Это сделано для примера. Добавлено через 29 минут carrotik, накидал простенький пример, как это сделать на C#. Надеюсь будет понятнее.
0
|
|||||||
|
785 / 616 / 273
Регистрация: 04.08.2015
Сообщений: 1,713
|
|
| 03.06.2021, 12:20 | |
|
BeginnerCoderCS, добавьте в таблицу статусов приоритет и получайте не статус, а макс или мин приоритет.
1
|
|
|
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
|
|
| 03.06.2021, 13:23 [ТС] | |
|
0
|
|
|
Модератор
|
||||||||
| 03.06.2021, 13:31 | ||||||||
|
Поскольку по другому невозможно будет выполнить на стороне сервера. У сервера должна быть вся необходимая информация. Добавлено через 3 минуты
1
|
||||||||
|
785 / 616 / 273
Регистрация: 04.08.2015
Сообщений: 1,713
|
|||||||
| 03.06.2021, 14:39 | |||||||
|
Тогда запрос будет выглядеть так:
1
|
|||||||
|
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
|
|
| 03.06.2021, 15:36 | |
|
На таблицу студентов вешается триггер AfterUpdate, в котором вызывается хранимка, в котрой
вычисляется минимальный статус по курсу, где студент. Этот минимальный статус записывается в поле статуса курса так, как было указано выше. При любом изменении любого студента автоматом в курс пишется новый статус. Никаких "почасовых" проверок-изменений не нужно, никакой таблицы статусов тоже. Все делается на сервере, ничего никуда не тянется. Все дела
2
|
|
|
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
|
||
| 03.06.2021, 16:50 [ТС] | ||
|
Частота изменения студентов планируется один раз в час, если были изменения. То есть грубо в таблице студентов 10млн строк. И каждый час будет меняться значения ~ от 10 000 до 500 000 студентов Это не положит субд?
0
|
||
|
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
|
||
| 03.06.2021, 17:35 | ||
![]() Мне трудно представить не веб систему, в которой одновременно работают десятки тысяч реальных юзеров.
1
|
||
|
Модератор
|
||
| 03.06.2021, 17:38 | ||
|
Если изменения частые и единичные, то вариант MsGuns предпочтительнее. Добавлено через 1 минуту BeginnerCoderCS, просто такое обновление (очень редкое и большими пакетами) довольно не типично и несклоько ставит в тупик, как уже заметил MsGuns.
1
|
||
|
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
|
|
| 03.06.2021, 17:43 | |
|
Не положит по двум причинам.
Во-первых триггеры сами по себе работают ну ооочень быстро. 1млн срабатываний займет несколько сек. Во вторых, хранимка выполняет два действия: 1. вычисление min по единственной таблице, к тому же по "короткому" полю - это работает мгновенно даже на миллионе записей. 2. Update единственной записи (по Id) - это доли мс + проходит далеко не всегда - если новый статус ниже вычисленного. Итого, как правило, все ограничится лишь выборкой без апдейта. Т.е. вся транзакция будет занимать макс. 1-2 милисекунды.
2
|
|
|
785 / 616 / 273
Регистрация: 04.08.2015
Сообщений: 1,713
|
|||
| 03.06.2021, 17:53 | |||
|
Пара советов. 1.Используйте триггеры только тогда, когда без них не обойтись. 2.Храните в таблице вычисляемое поле только тогда, когда логика его вычисления затратна по времени.
1
|
|||
|
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
|
||||
| 03.06.2021, 18:03 | ||||
|
Если утверждение о сотнях тысяч в час изменений в БД (в чем я сильно сомневаюсь, разве что речь идет об автоматических процессах) верно и "тормоза" все же появятся, то с ними (тормозами) опять же можно успешно побороться, навесив на поле минимального статуса в таблице курсов вторичный индекс. При условии длинных текстов в остальных полях таблицы курсов это даст ускорение выборки в разы, а то и на порядок.
Добавлено через 4 минуты Добавлено через 1 минуту Поправка: вторичный индекс вешается на таблицу студентов, конечно же,- ведь именно из нее определяется минимальный статус
1
|
||||
|
785 / 616 / 273
Регистрация: 04.08.2015
Сообщений: 1,713
|
|
| 03.06.2021, 18:26 | |
|
MsGuns, в 6 ТС объяснил, почему одного поля статус недостаточно. А на троллинг я не ведусь
1
|
|
| 03.06.2021, 18:26 | |
|
Помогаю со студенческими работами здесь
20
Как правильно отлавливать Constraint ForeignKey в DAO? Как изменить отображение текста ForeignKey в моделе Как шифровать файлы при передаче на сервер и дешефровать при передаче с сервера на клиент Как сделать каскадный вызов элементов ForeignKey в одной view в Django? Как посмотреть наследников класса Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
|
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма).
На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
|
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ *
Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам
Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
|
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым.
Но восстановить их можно так.
Для этого понадобится консольная утилита. . .
|
|
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
|
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11
— это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
|
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11
Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
|
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
|