Próbuję zamodelować taką sytuację: użytkownicy mogą wskazywać konkretne daty w której są dostępni, ale również dni (wskazanie poniedziałku oznacza, że jest dostępny w każdy poniedziałek). Wymyśliłem więc coś takiego:
create table users
(
id int4,
name text NOT NULL
);
create table date_availability
(
user_id int4 NOT NULL,
from_time timestamp NOT NULL,
to_time timestamp NOT NULL
);
create table day_availability
(
user_id int4 NOT NULL,
day_of_week int4 NOT NULL,
from_time time NOT NULL,
to_time time NOT NULL
);
Teraz, żeby pozyskać listę wszystkich użytkowników dostępnych na mecz, wystarczy takie zapytanie:
/*
DOSTĘPNOŚCI DATOWE
2023.08.22 19:00 - 21:00 DAMIAN
DOSTĘPNOŚCI REKURENCYJNE
PONIEDZIAŁKI 15:00 - 18:00 DAMIAN
PONIEDZIAŁKI 16:00 - 20:00 KAROL
WTORKI 16:00 - 21:00 KAROL
MECZ JEST
2023.08.22 20:00 - 21:00
Damian jest dostępny ze względu na dostępność datową, a Karol ze względu na dostępność rekurencyjną
*/
select user_id
from date_availability
where
from_time <= '2023-08-22 20:00:00'
and to_time >= '2021-08-22 21:00:00'
union all
select user_id
from day_availability
where
day_of_week = EXTRACT(dow FROM TIMESTAMP '2023-08-22 20:00:00')
and from_time <= '2023-08-22 20:00:00'::time
and to_time >= '2023-08-22 21:00:00'::time
W zasadzie wszystko działa, ale zastanawiam się, czy nie lepiej byłoby zrezygnować z tabeli day_availability
i mieć samą date_availability
, a w momencie, gdy ktoś definiuje sobie dostępność powtarzalną, to wrzucać do bazy wszystkie możliwe daty (np. na rok w przód). Takie podejście ułatwiłoby np. pobranie listy wszystkich dostępności w ciągu roku. Nie musiałbym generować dat na podstawie dostępności rekurencyjnych. @axelbest zaproponował coś, co ja rozumiem jako nieznormalizowana baza (u mnie jest znormalizowana).
Jak myślicie, które podejście sprawdzi się lepiej?