#sql #performance #cassandra #schedule #scylla
#sql #Производительность #кассандра #Расписание #сцилла
Вопрос:
Как сохранить рабочее время врача в базе данных, чтобы эффективно извлекать свободные временные интервалы?
Подходы
A. Правила и исключения магазина
- врач определяет рабочее время, например, с 9 утра до 3 часов дня каждые 30 минут с перерывом 11-12
- врач определяет исключения, например, отпуск с 1/1/22 по 1/14/22
- врач определяет другие исключения, например, завтра с 8:30 утра до 12:30 вечера
- каждый раз, когда пациент хочет записаться на прием, сервер извлекает все правила для врача из базы данных, анализирует их и возвращает свободные временные интервалы (например, 9 утра, 9:30 утра, 11:30 утра).
- нам нужны приоритетные/иерархические правила и исключения (они могут перекрываться)?
B. Заполните все временные интервалы в базе данных
- врач определяет рабочее время, например, с 9 утра до 3 часов дня каждые 30 минут с перерывом 11-12
- если завтра доктор недоступен, он просто удаляет временные интервалы с завтрашнего дня
- если врач будет доступен завтра с 8:30 утра, он переместит блок временных интервалов
- каждый временной интервал = строка в базе данных
- каждый раз, когда пациент хочет записаться на прием, сервер извлекает все временные интервалы из базы данных за указанный период времени и не нуждается в анализе правил
- нам нужно отслеживать изменения, если мы хотим их отменить?
- мы не можем заполнять временные интервалы вечно — врач должен планировать расписание на определенное количество времени (например, на следующий месяц), или временные интервалы должны создаваться на основе правил (гибридный подход A B) автоматически с помощью задания cron
Примеры исключений
- отпуск
- в случае, если нам нужно сделать исключение или разделить правила на 2 отдельных (до и после отпуска)
- в B мы просто удаляем временные интервалы из базы данных для отпуска
- измените часы операции на определенный период времени, например, на следующей неделе
- в аналогичном, как описано выше, мы делаем исключение или разделяем правила
- в разделе B мы меняем временные интервалы только на следующую неделю, а остальные остаются неизменными
- измените часы операции навсегда
- в аналогичном, как описано выше, мы делаем исключение или разделяем правила
- в B мы меняем все временные интервалы до конца
- в нечетные недели врач работает: Пн, Ср, Пт; в четные недели: Вт, Чт, Сб
- в результате правила усложняются, и разбор может занять больше времени
- в B мы заполняем временные интервалы в базе данных только один раз в соответствии с заданным алгоритмом
- врач меняет время отпуска или удаляет исключение
- in A he just changes exception time period or deletes and exception
- in B we populate back time slots (system should track changes to undo them?)
- some slots may be larger (e.g. 1 hour) than others (e.g. 30 minutes), e.g. for a procedure
Schema examples
A. Rules and exceptions
create table rules ( doctor_id UUID, rule_id UUID, priority tinyint, -- example approach to solve overlapping rules base_rule UUID, -- another approach is a tree of rules time_from timestamp, -- rule is valid from this time (required) time_to timestamp, -- rule is valid until this time (null if forever) days tinyint, -- bitwise (1-Mon, 2-Tue, 4-Wed, etc) app_time tinyint, -- appointment time (in minutes, e.g. 30) start_hour tinyint, -- e.g. 8 AM (when he wants to see first patient) end_hour tinyint, -- e.g. 15 PM (when he leaves surgery / logs out) hours listlt;timegt;,-- another approach is a list with all hours (8, 8:30, 9, etc) primary key (doctor_id, rule_id) );
Мы тоже хотим исключений? Возможно, но мы также можем использовать rules
с приоритетами или деревом правил.
create table rules ( doctor_id UUID, exception_id UUID, reason TEXT, -- all fields similar as in rules table primary key (doctor_id, exception_id) );
B. Заполните все временные интервалы в базе данных
create table rules ( doctor_id UUID, patient_id UUID, -- null if free, not null if booked by a patient slot_from timestamp, -- time slot start time (required, e.g. 1/1/22 9:00) slot_to timestamp, -- time slot end time (required, e.g. 1/1/22 9:30) primary key (doctor_id, slot_from) );
Просто! Никакого анализа правил/исключений, просто извлекайте и возвращайте временные интервалы пациенту.
Подводить итоги
- Какой подход лучше всего подходит?
- Если какой — либо подход плох- почему?
- Что бы вы изменили для повышения производительности и гибкости?
- Если подход А, как наиболее эффективно обрабатывать изменения, исключения и т.д.?
- Как это реализовано в уже существующих календарях/расписаниях, системах встреч и т.д.?
Комментарии:
1. Трудно сказать, не зная, как будет запрашиваться эта таблица. Неужели это действительно будет только когда-нибудь
doctor_id
?2. @Aaron: по doctor_id в подходе A или по (doctor_id, slot_from) в подходе B. Мы всегда будем включать doctor_id в запрос. Нам нужно отобразить свободные временные интервалы на определенный период времени (например, следующие 5 дней) или на месяц.