|
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
|
||||||
.NET 4.x Как опитмально поступить в передаче состояния у наследников (foreignkey)03.06.2021, 08:59. Показов 3998. Ответов 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? Как посмотреть наследников класса Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование
. \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json>
Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом.
# Check if. . .
|
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так:
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347
Основана на STM32F303RBT6.
На борту пять. . .
|
Символьное дифференцирование
igorrr37 13.02.2026
/ *
Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет
значение производной при заданном х
Логарифм записывается как: (x-2)log(x^2+2) -. . .
|
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
|
|
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу,
и светлой Луне.
В мире
покоя нет
и люди
не могут жить в тишине.
А жить им немного лет.
|
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила»
«Время-Деньги»
«Деньги -Пуля»
|
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога
Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
|
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога
Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
|