Кейс: история цен тарифов
Вопрос
Оператор связи меняет цены тарифов несколько раз в год. Нужно корректно выставлять счета задним числом и показывать абоненту, по какой цене он платил в каждом месяце. Как смоделируешь?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Цена не атрибут тарифа, а отдельная сущность с периодом действия (valid_from, valid_to)
Запрет пересекающихся периодов для одного тарифа (exclusion constraint или проверка)
Подключение абонента к тарифу тоже с периодом
Счёт фиксирует цену как снимок на момент начисления
Время с часовым поясом, правила для границ периода
Что могут спросить следом
- Как найти цену на конкретную дату одним запросом?
- Что если цену изменили задним числом?
Разбор
Цену выношу из тарифа в отдельную таблицу tariff_prices с периодом действия: valid_from включительно и valid_to исключительно, у текущей valid_to пустой. Для одного тарифа периоды не должны пересекаться, в PostgreSQL это делается ограничением исключения по диапазону. Подключения абонентов к тарифам тоже храню с периодами, так видно, кто на чём сидел в каждом месяце. При начислении счёт сохраняет цену и период как снимок, чтобы пересмотр прайса не менял выставленные счета. Изменение задним числом оформляется корректирующим начислением, а не правкой старого счёта. Цена на дату находится условием valid_from <= дата и (valid_to > дата или valid_to пустой).
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.