Godziny rezerwacji przechowywanie w bazie

0

Musze zrobić rezerwację co 30 min 1h, 1,5h itp (np. 10, 10 12:00 itp) od 7-21. Jak najlepiej to rozwiązać ? Na sztywno dodać do tabeli jako string 7:00 , 7:30, 8:00, 8:30 itp? I data wsadzić do innej tabeli i zrobić miedzy tym relację ?

1

Można modelować na różne sposoby. Jedne będą bardziej przydatne w rozwiązaniu Twoich problemów, inne mniej.

Co dla Ciebie znaczy "najlepiej"? Jak chcesz używać tych informacji?

0

Weź pod uwagę że jeżeli system jest obsługiwany w wielu krajach to musisz uwzględnić strefę czasową.

1

W bazie trzeba przechowywać czas bez uwzględnienia strefy, zaś przy wyświetleniu dodawać tą strefę.
Najprościej przechowuj liczbę minut od początku dnia czyli 7:30 = 7*60+30 natomiast do wyświetlenia pobierasz dzień wizyty godzina 00:00 do tego dodajesz ilość minut z bazy.

2
TakMaszRacje napisał(a):

Na sztywno dodać do tabeli jako string 7:00 , 7:30, 8:00, 8:30 itp?

Może zadziałą, ale pomysł nie za dobry. W postgresie masz pod to typy time/ time without time zone i time with time zone
https://www.postgresql.org/docs/current/datatype-datetime.html

2

Skąd tak koślawy pomysł na trzymanie daty/czasu jako string? Jak później będzie potrzeba np napisać zapytanie które wyjmie rekordy z przedziału to będziesz stringa parsowal na datę dla każdego rekordu?
Staraj się używać dedykowanych typów jeśli baza to wspiera.
Inna sprawa że mimo że aplikacja dzisiaj ma działać lokalnie, to o ile nie piszesz desktopowej apki, trzymanie daty/czasu w lokalnej dla serwera strefie może Ci kiedyś mocno napsuć krwi dlatego powinno się trzymać to jako UTC i stosownie przetwarzać już w aplikacji po odczycie.

1
RequiredNickname napisał(a):

Skąd tak koślawy pomysł na trzymanie daty/czasu jako string? Jak później będzie potrzeba np napisać zapytanie które wyjmie rekordy z przedziału to będziesz stringa parsowal na datę dla każdego rekordu?
Staraj się używać dedykowanych typów jeśli baza to wspiera.

+1

Inna sprawa że mimo że aplikacja dzisiaj ma działać lokalnie,
...

Podobnie jak NALEŻY przewidywać, że okienko rezerwacji nie będzie takie regularne / jednakowe

Bo właściwie, gdyby dać sobie uciąć rękę, że ZAWSZE pół godziny, to podzieli czas przez te pół godziny i zapisywać numer "slotu", bez określania końca, bo po co. Podaję jako przykład doprowadzenia tego myślenia do muru / patologii

Np typ sql datetime dla otwarcia i zakończenia, aby dało się po stronie SQL wykrywać konflikty, mieć proste i pewne sortowanie itd.
Inaczej będzie straszliwe pipkanie z danych po stronie klienta.

0

to jak rozwiązać sytutację od strony kodu. Aby api do frontu zwracało tylko godziny "pełne" 10:00 ,11:30, 12:00 itp i w drugą stronę ( chociaż to wyjdzie z tego pierwszego).

Bo jeżeli godziny będą w stringu i wiaodmo że możlwiosć rezerwacji będzie najwcześniej od 6:00 a najpożniej do 22:00. Różne usługi mogą trwać od 30min do 3h. I myślałem aby przy rezerwacji np. na godzinę 10:00 był wybór usługi która trwa 1:30h będzie blokować wartosci 10:00, 10:30, 11:00 i 11:30.
Strefy czasowe nie będą miały wpywu na to i nawet jak aplikacja bedzie działałą w róznych strefach czasowych.

0

Może zrób tabele dla bloków:

Id=1, From=6:00, To=6:30
Id=2, From=6:30, To=7:00

...
I kolejną tabele
Data, BlockId, unique key(Data, BlockId)

2

Masz przechowywać zakresy. Najprościej będzie trzymać timestampy rozpoczęcia i zakończenia tych przedziałów. Jest jeszcze kwestia przeszukiwania i to trochę zależy od bazy. Szukaj hasła r-tree.
Jeżeli nie ma jakichś specjalnych wymagań, to czas przechowuj zawsze jako jakiś typ czasu, zawsze w UTC i przeliczaj ją na UI na strefę wygodną dla użytkownika. Strefy czasowe, to niby banał, a zaskakująco szybko można się znaleźć w sytuacji, że nikt nie wie gdzie co i jak jest trzymane i jak to interpretować.
Nie wiesz teraz, czy za chwilę nie pojawią się jakieś kolejne wymagania, typu:

  • godziny nie muszą być pełne
  • trzeba wysyłać użytkownikom spotkania do kalendarza
    Lepiej zachować czystość i otwartość rozwiązania.
0

Jeżeli nie ma jakichś specjalnych wymagań, to czas przechowuj zawsze jako jakiś typ czasu, zawsze w UTC i przeliczaj ją na UI na strefę wygodną dla użytkownika. Strefy czasowe, to niby banał, a zaskakująco szybko można się znaleźć w sytuacji, że nikt nie wie gdzie co i jak jest trzymane i jak to interpretować.

Dokładnie - strefy czasowe to dosyć złożny temat i ja w bazie trzymałbym czas tylko np. w UTC. Najwyżej można przekształcać czas w samej aplikacji, ale model bazodanowy lepszy jest wygodniejszy i bezpieczniejszy

0
scibi_92 napisał(a):

Dokładnie - strefy czasowe to dosyć złożny temat i ja w bazie trzymałbym czas tylko np. w UTC. Najwyżej można przekształcać czas w samej aplikacji, ale model bazodanowy lepszy jest wygodniejszy i bezpieczniejszy

Czy możesz zaaprobować strukturę tabel aby nie można było zapisać dwóch pokrywających się w czasie wizyt?

0

Czy możesz zaaprobować strukturę tabel

Tak właściwie to czemu tabel?
Ja bym po prostu w modelu reservation miałbym pola:

private LocalDateTime startDate;
private LocalDateTime endDate;
4

@_13th_Dragon: Na problem nienakładania się zakresów bazy danych nie mają dobrej odpowiedzi. Można zrobić sobie tabelkę z godzinnymi przedziałami jak zaproponowałeś i nałożyć jakiś tam unique na (pokój, czas) + może jeszcze (lekarz, czas), ale to dość mocno usztywnia stronę biznesową, bo jak klient zdecyduje, że teraz będzie brał tyle samo ale za 45 zamiast 60 minut, to system przestaje działać. Można zrobić tę tabelkę z przedziałami definiowanymi luźniej, ale to oznacza jedynie przesunięcie problemu z jednego miejsca w drugie.
Jeżeli bardzo bym chciał mieć wymuszenie unikalności po stronie bazy, to skończyłoby się na pisaniu wyzwalaczy na insert/update działających na jednowymiarowym indeksie przestrzennym.

1

"aby nie można było zapisać dwóch pokrywających się w czasie wizyt" - to co podałeś bez problemy wpisujemy 10 wizyt w tym samym czasie.

Można zrobić wczesniej sprawdzić czy istnieje wiesz/dokument w bazie danych gdzie nakłada się nasz czas kiedy chcemy dokonać wizyty

0

Sprawdzenie pokrywania się przedziałów, tak normalnie, w języku programowania, nieprzygotowania intuicja podpowiada, że da się nie mniej niż w czterech porównaniach

Ale jak się wejście w temat i myśli, okazuje się że tylko dwa.
Konieczne w tym wątku zadanie ze zwykłej algorytmiki.

5

Chwilami zastanawiam się w sumie po co ta dyskusja.
Polecanie jakichś weryfikacji przedziałów na podstawie tabel, szmery bajery flesze błyski.

A wszystko można rozwiązać fajnie w kodzie jak tylko odejdzie się od myślenia encjami bazodanowym i a zacznie obiektami domenowymi które mają swoją logikę.

Tzn wiem, że dużo osób wypowiadających się w tym wątku ma tego świadomość ale z pytania o pet projekt zaczyna się tasiemiec jak gdyby miało to produkcyjnie działać. ;)

0

No tak, genialnie, przerzućmy wszystko na logikę biznesową, traktujmy tabele bazodanowe jako zwykle listy rekordów i zarzynajmy bazy danych przeglądając całą tablicę rezerwacji. I to kiedy da się to zrobić po stronie bazy w czasie O(log(log(n)))

Nikt nie pisał o "przeglądaniu całej tablicy rekordów". Bazy danych mają indeksy (nawet OracleDB) więc nie widze problemu w tym żeby beginDate i endDate miały indeksy. I tak, logiki w bazie danych powinno być jak najmniej i baza danych to lista rekordów. Nie widze tu również żadnego log(lon(n))
Kod powinien byc w 1 kolejności czytelny i łatwy w utrzymaniu, a dopiero w drugiej super efektywny.
A komentarze nie są od dyskusji na główne tematy
@TakMaszRacje: nie przejmuj się ludźmi których sposób myślenia został w latach 90 XX wieku ;)

Indeks z dwoma warunkami na to samo pole? Sprawdź jak na to reagują SQL'e - lecą po calości.

?? jak na to samo pole. Jedno na beginDate a drugie na endDate. I dwa osobne zapytania można dac.

0
RequiredNickname napisał(a):

Chwilami zastanawiam się w sumie po co ta dyskusja.
Polecanie jakichś weryfikacji przedziałów na podstawie tabel, szmery bajery flesze błyski.

A wszystko można rozwiązać fajnie w kodzie jak tylko odejdzie się od myślenia encjami bazodanowym i a zacznie obiektami domenowymi które mają swoją logikę.

Dyskusja bierze się z prostej rzeczy - to, że przedziały nie nachodzą na siebie to nie jest logika biznesowa, ale własność modelu, więc model nie powinien dopuszczać możliwości wprowadzenia złej daty tak samo, jak tego, że nie da się umówić pacjenta na 34 grudnia.
Przy czym nie istnieje żaden powód, żeby takich problemów z modelem nie sprawdzać w trzech warstwach: w warstwie prezentacji, logiki biznesowej i modelu.

0

No imho nie.
Jak się myśli kategoriami architektury warstwowej to może i kusi pakowanie tego typu logiki do warstwy persystencji ale mamy końcówkę 2022 roku, o tym, że architektura warstwowa jest mało perspektywiczna napisał chyba każdy kto w światku it ma więcej niż 3 folowwersow.

Come on....

0
RequiredNickname napisał(a):

Jak się myśli kategoriami architektury warstwowej to może i kusi pakowanie tego typu logiki do warstwy persystencji ale mamy końcówkę 2022 roku, o tym, że architektura warstwowa jest mało perspektywiczna napisał chyba każdy kto w światku it ma więcej niż 3 folowwersow.

Nie mam pojęcia dlaczego uważasz, że tekst sprowadzający się do "przeczytałem kilka wpisów" to jakikolwiek argument. Skoro według ciebie jest to takie oczywiste to może wytłumacz, dlaczego uznajesz, że baza powinna być głupia. Jako bonus możesz wrzucić kawałek o tym, że dzielenie aplikacji na funkcjonalne warstwy jest passe i co byś zaproponował w miejsce np. architektury heksagonalnej.

2

Dlatego baza powinna być "głupia" bo pakowanie logiki biznesowej (a tym właśnie wymaganie, że np. wizyta w gabinecie ma standardowo 30min i jest on wtedy zajęty, jest) w schemat bazodanowy to relikt przeszłości uznany za antypattern. Jest na ten temat mnóstwo tekstów/prelekcji w sieci i nie chciałbym tutaj powtarzać tego typu informacji.

2
RequiredNickname napisał(a):

Dlatego baza powinna być "głupia" bo pakowanie logiki biznesowej (a tym właśnie wymaganie, że np. wizyta w gabinecie ma standardowo 30min i jest on wtedy zajęty, jest) w schemat bazodanowy to relikt przeszłości uznany za antypattern.

Mylisz model bazodanowy z wymaganiami biznesowymi, a uzyskane w ten sposób wnioski wskazujesz jako dowód na ich prawdziwość.

  1. To, ile minut trwa wizyta w gabinecie to wymaganie biznesowe.
  2. To, że przedziały czasowe na siebie nie mogą nachodzić to kwestia modelu.
1

Nie widzę sensu się jakiegoś spierania.
Dla Ciebie kwestia nakładania się rezerwacji to kwestia modelu (bo utożsamiasz encje bazodanową z encją biznesową/domenową imho) a dla mnie to jest typowe wymaganie biznesowe bo byt zwany wizyta (a wspomniane przedziały czasowe dotyczą właśnie wizyt/zabiegów/usług) bynajmniej nie musi być w ten sposób zamodelowany na poziomie db, co więcej to mogą być zupełnie różne tabele w bazie danych:

  1. gabinet w którym odbywa się wizyta
  2. pracownik który będzie wykonywał pewnego rodzaju usługę
  3. sama wizyta jako np. farba na włosy w gabinecie fryzjerskim gdzie w miedzy czasie śmiało można np. robić pedicure

Przykłady można mnożyć i tak jak napisałem wcześniej, dla mnie to myślenie jest typowo kategoriami betonowania rozwiązania gdzie core'em jest encja bazodanowa która powinna być gdzieś zupełnie z boku.

0

Aplikacja nie będzie duża i zawsze będzie to odstępy czasu co 30 min. Po stronie frontu jest wybeirana data a nastepnie przesyłana do api. W bazie bedzie godzina zapisana w formacie LocalTime. Front będzie pobierał przez api wszystkie godziny i pytanie jak:

  1. Łączyć date z godziną i zapisywać w bazie?
  2. jak sprawdzać dostępne terminy data i godziy dla tej daty ?
    Jak to powinno wyglądać wszczególności na bazie?

1 użytkowników online, w tym zalogowanych: 0, gości: 1