Informacje o dacie i godzinie możemy przechowywać na kilka sposobów. Jakie jest najlepsze podejście do przechowywania informacji DateTime?
Przechowywanie daty i godziny w 2 osobnych kolumnach lub jednej kolumnie przy użyciu DateTime ?
Czy możesz wyjaśnić, dlaczego to podejście jest lepsze?
(Link do dokumentacji MySQL w celach informacyjnych, pytanie jest ogólne, nie dotyczy MySQL)
Typy daty i godziny : Data i godzina
database-design
datetime
juliański
źródło
źródło
date,time
z,group by date
ale nie dla indeksudatetime
z,group by cast(datetime as date)
nawet jeśli zapewniłaby pożądaną kolejność.Odpowiedzi:
Przechowywanie danych w jednej kolumnie jest preferowanym sposobem, ponieważ są one nierozerwalnie połączone. Punkt w czasie to jedna informacja, a nie dwie.
Powszechnym sposobem przechowywania danych daty / godziny, stosowanym „za kulisami” przez wiele produktów, jest konwersja ich na wartość dziesiętną, gdzie „data” jest całkowitą częścią wartości dziesiętnej, a „czas” jest ułamkiem wartość. Tak więc 1900-01-01 00:00:00 jest przechowywany jako 0,0, a 20 września 2016 09:34:00 jest przechowywany jako 42631.39861. 42631 to liczba dni od 1900-01-01. .39861 to część czasu, która upłynęła od północy. Nie używaj do tego bezpośrednio typu dziesiętnego, użyj jawnego typu daty / godziny; mój punkt tutaj jest tylko ilustracją.
Przechowywanie danych w dwóch osobnych kolumnach oznacza, że będziesz musiał połączyć obie wartości kolumn za każdym razem, gdy chcesz sprawdzić, czy dany punkt w czasie jest wcześniejszy czy późniejszy niż zapisana wartość.
Jeśli przechowujesz wartości osobno, niezmiennie napotkasz „trudne” błędy, które są trudne do wykrycia. Weźmy na przykład:
W powyższym kodzie tworzymy tabelę testową, zapełniając ją dwiema wartościami, a następnie wykonując proste zapytanie względem tych danych. Pierwszy
SELECT
zwraca oba wiersze, jednak drugiSELECT
zwraca tylko jeden wiersz, co może nie być pożądanym rezultatem:Prawidłowy sposób filtrowania zakresu dat / godzin, w którym wartości znajdują się w osobnych kolumnach, jak wskazał @ypercube w komentarzach, to:
Jeśli potrzebujesz komponentu czasu oddzielonego do celów analizy , możesz rozważyć dodanie obliczonej, utrwalonej kolumny dla części czasowej wartości:
Utrwalona kolumna może być następnie zaindeksowana, umożliwiając szybkie sortowanie itp. Według pory dnia.
Jeśli zastanawiasz się nad podzieleniem daty i godziny na dwa pola do celów wyświetlania, powinieneś zdawać sobie sprawę, że formatowanie powinno być wykonywane na kliencie, a nie na serwerze.
źródło
Zamierzam przedstawić odmienne zdanie na temat innych odpowiedzi.
Jeśli oba elementy daty i godziny są wymagane razem, tj. Wpis jest niepoprawny, jeśli zawiera jeden, ale nie drugi (lub ma wartość NULL w jednej, ale nie drugiej), wówczas przechowywanie go w jednej kolumnie ma sens z powodów podanych w innych odpowiedzi
Może się jednak zdarzyć, że jeden lub oba komponenty są indywidualnie opcjonalne. W takim przypadku niewłaściwe byłoby przechowywanie go w jednej kolumnie. Takie postępowanie zmusiłoby Cię do przedstawienia wartości NULL w dowolny sposób, np. Zapisanie czasu jako 00:00:00.
Oto kilka przykładów:
Rejestrujesz przejazdy pojazdów w celu odliczenia podatku za przebieg. Przydałaby się znajomość dokładnej godziny podróży, ale jeśli pracownik nie zanotował jej i zapomniał, data powinna być nadal zapisywana sama (wymagana data, opcjonalny czas).
Przeprowadzasz ankietę, aby dowiedzieć się, o której godzinie ludzie jedzą lunch, i prosisz uczestników o wypełnienie formularza próbką swoich porcji obiadowych, w tym dat. Niektórzy nie zawracają sobie głowy wpisaniem daty i nie chcesz odrzucić danych, ponieważ są to chwile, na których naprawdę Ci zależy (opcjonalna data, wymagany czas).
Zobacz to powiązane pytanie dotyczące alternatywnych podejść.
źródło
Zawsze wolę przechowywać to jako pojedynczą kolumnę, chyba że istnieje określone zapotrzebowanie biznesowe / aplikacji. Poniżej moje punkty -
źródło
W SQL Server najlepiej przechowywać DataTime jako jedno pole. Jeśli utworzysz indeks w kolumnie DataTime, można go użyć jako wyszukiwania daty i wyszukiwania daty. Dlatego jeśli chcesz ograniczyć wszystkie rekordy istniejące dla określonej daty, możesz nadal korzystać z indeksu bez konieczności robienia czegokolwiek specjalnego. Jeśli chcesz zapytać o porcję czasu, nie będziesz w stanie użyć tego samego indeksu, a zatem jeśli masz przypadek biznesowy, w którym zależy Ci bardziej na czasie niż na DateTime, powinieneś przechowywać go osobno, ponieważ będziesz musiał utworzyć indeks na nim i poprawić wydajność.
źródło
Rzeczywiście szkoda, że nie ma w tym celu standardowego typu cross-DBMS (np. INT i VARCHAR są liczbami całkowitymi i ciągami znaków). 2 podejścia, które do tej pory spotkałem w wielu bazach danych, wykorzystują kolumny VARCHAR / CHAR do przechowywania wartości DataTime jako ciągów sformatowanych zgodnie z normą ISO 8601 (wygodniej, czytelny dla człowieka) i użycie BIGINT do przechowywania ich jako znaczników czasu POSIX (przechowywanych więcej wydajnie, szybciej, łatwiej manipulować matematycznie).
źródło
timestamp
tak definiuje standard SQL. Przechowywanie znaczników czasu jako ciągów to bardzo zła radaPo przeczytaniu wielu rzeczy, czas UTC Unix w BIGINT wydaje się optymalnym rozwiązaniem. Identyfikator czasu TZDB w VARCHAR do przechowywania strefy czasowej w razie potrzeby. Kilka argumentów:
TIMESTAMP i DATETIME wykonują kilka chwytliwych konwersji w tle, które wydają się złożone i niejasne. Serwer czasami przełącza się z czasu lokalnego na UTC lub na czas serwera iz powrotem. Kilka ukrytych kosztów ogólnych dla każdej funkcji.
BIGINT (8kb) jest co najmniej tak lekki lub lżejszy niż DECIMAL wymagany do przechowywania w formacie xxxxxx.xxxxxx, który jest praktycznie przechowywany przez MySQL jako dwie INT + coś . I wystarczy przechowywać stulecia przed nami.
Prawie wszystkie główne języki programowania mają biblioteki standardowych funkcji do pracy z czasem uniksowym.
Operacje matematyczne z BIGINT powinny być tak szybkie lub szybsze niż cokolwiek innego na jakimkolwiek sprzęcie.
Oczywiście wszystkie powyższe dotyczą dużych, międzynarodowych projektów. W przypadku czegoś małego wybór domyślnego formatu wybranego frameworka wydaje się wystarczający.
źródło
timestamp
kolumny nie występują „sztuczne konwersje” (w warstwie bazy danych), a dlatimestamp with time zone
tego jest to dobrze udokumentowane i wyjaśnione w instrukcjach (przynajmniej dla Oracle i Postgres)