Istnieje długa i dość wyjaśniająca odpowiedź na temat różnic między nimi
TIMESTAMP WITH TIME ZONE
-vs-TIMESTAMP WITHOUT TIME ZONE
dostępne w tym poście SO . Chciałbym wiedzieć: czy istnieją jakieś ważne przypadki użycia do faktycznego użycia, TIMESTAMP WITHOUT TIME ZONE
czy też należy to uznać za anty-wzór.
postgresql
Marcus Junius Brutus
źródło
źródło
Odpowiedzi:
Zasada ta jest zawarta w wielu miejscach, ale myślę, że warto wspomnieć, zawsze gdy porównamy
timestamp with time zone
ztimestamp without time zone
rodzajów: nie przechowuje strefy czasowej informacji wraz ze znacznikiem czasu . To, co robi, to przechowywanie wszystkich danych w strefie czasowej UTC, jak stwierdzono w dokumentach :timestamp WITH time zone
Uważa się, że niektóre z nich mogą być używane
timestamp WITHOUT time zone
w sytuacjach, w których (1) wszystko znajduje się w tej samej strefie czasowej lub (2) warstwa aplikacji obsługuje strefę czasową i po prostu przechowuje wszystko w określonej strefie czasowej (zwykle UTC). Ale jest również uważany za anty-wzorzec, prosty, ponieważ poprawnym rozwiązaniem dla (1) jest skonfigurowanie ustawienia strefy czasowej na podaną jedną strefę czasową dla systemu, a (2) jest już rozwiązane, ponieważ PostgreSQL przechowuje już wszystko w tej samej strefie czasowej (UTC).Teraz, gdy te dwa są na dole, mogę przyjść tylko z jednego dobrego powodu, aby użyć
timestamp WITHOUT time zone
. Właśnie wtedy chcesz przechowywać zdarzenia w przyszłości, a kiedy dotrzemy do tego czasu, musi zostać uruchomiony jakiś alarm. Może to być dobre,timestamp WITH time zone
jeśli i tylko wtedy, gdy reguły określone przez regionalne przepisy dotyczące strefy czasowej nigdy się nie zmienią. Najczęstszą regułą, która się zmienia, jest przyjęcie lub brak czasu letniego (DST).Na przykład wyobraź sobie, że planujesz, powiedzmy,
2013-06-15
(jeszcze nie w czasie letnim) zaplanować jakieś wydarzenie w2013-01-15 10:00
(które byłoby już w czasie letnim), a2013-06-15
twój region został wyznaczony do przyjęcia czasu letniego; ale jakiś czas później rząd zmienił regułę i powiedział, że twój region nie będzie już używać DST, i nagle twój planowany czas staje się2013-01-15 11:00
(zamiast10:00
), że jeśli użyjesztimestamp WITH time zone
i będziesz aktualizować konfiguracje TZ. Oczywiście możesz również zauważyć, że takie przypadki można traktować również w strefie czasowej, jeśli śledzisz zmiany reguł w regionach / strefach czasowych, które Cię interesują, i aktualizujesz dane, których to dotyczy.Warto wspomnieć, że niektóre regiony często zmieniają te zasady (jak w Brazylii, niektóre stany - nie cały kraj - często się zmieniają), ale w większości przypadków zmienia to bardzo wcześniej, więc na użytkowników będą miały wpływ tylko wydarzenia zaplanowane bardzo daleko od aktualny czas.
Biorąc to wszystko pod uwagę, mam tylko jedną sugestię. Jeśli masz użytkowników, dzienniki lub cokolwiek innego w różnych strefach czasowych, zapisz strefę czasową, z której pochodzą, i wybierz i użyj
timestamp with time zone
. W ten sposób możesz (1) krzyżować zdarzenia zachodzące bliżej siebie dla różnych źródeł (niezależnie od ich stref czasowych) i (2) pokazywać pierwotny czas (czas zegarowy), w którym zdarzenie miało miejsce.źródło
Tak. Istnieją przypadki użycia dla
TIMESTAMP WITHOUT TIME ZONE
.TIMESTAMP WITH TIME ZONE
, a nieWITHOUT
.TIMESTAMP WITHOUT TIME ZONE
wartości nie są punktem na osi czasu, a nie faktycznymi momentami. Przedstawiają przybliżone wyobrażenie o potencjalnych momentach, możliwych punktach na osi czasu w zakresie około 26-27 godzin (zakres stref czasowych na całym świecie). Nie mają one żadnego rzeczywistego znaczenia, dopóki nie zastosujesz strefy czasowej lub nie uwzględnisz UTC .Np .: Boże Narodzenie
Na przykład powiedz, że musisz zarejestrować początek wakacji / dni świętych.
Aby odnotować fakt, że Boże Narodzenie rozpoczyna się po północy 25 grudnia tego roku, musimy powiedzieć
2016-12-25 00:00:00
bez żadnej strefy czasowej. Na początku Świętego Mikołaja odwiedza Auckland NZ tuż po północy, ponieważ jest to jedna z najwcześniejszych północy na świecie. Potem idzie w kierunku zachodnim, gdy nadejdzie kolejna północ, wkrótce docierając do Filipin. Następnie renifery idą w kierunku zachodnim, docierając do Indii o północy, co zdarza się kilka godzin po tej północy w Auckland. Znacznie później jest jeszcze północ w Paryżu FR, a jeszcze później północ w Montrealu CA. Wszystkie te wizyty Świętego Mikołaja zdarzają się w różnych momentach , jednak wszystkie odbywają się wkrótce po północy, o północy każdej miejscowości.Nagrywanie
2016-12-25 00:00:00
bez żadnej strefy czasowej jako początku świąt Bożego Narodzenia jest pouczające i zgodne z prawem, ale tylko niejasno. Dopóki nie powiesz „Boże Narodzenie w Auckland” lub „Boże Narodzenie w Montrealu”, nie mamy określonego momentu. Jeśli rejestrujesz faktyczny moment za każdym razem, gdy sanie lądują, użyjTIMESTAMP WITH TIME ZONE
raczej niżWITHOUT
typu.Podobnie jak Boże Narodzenie jest Sylwester. Kiedy piłka Times Square spada w Nowym Jorku , ludzie w Seattle nadal chłodzą szampana i przygotowują imprezowe rogi . Nagrywalibyśmy jednak ideę noworocznego momentu jak
2017-01-01 00:00:00
wTIMESTAMP WITHOUT TIME ZONE
. W przeciwieństwie do tego, jeśli chcemy nagrywać, kiedy piłka spadła w Nowym Jorku lub gdy mieszkańcy Seattle rozwalili rogi, zamiast tego użylibyśmyTIMESTAMP WITH TIME ZONE
(nieWITHOUT
) nagrania tych faktycznych chwil, co trzy godziny od siebie.Np .: Zmiany fabryczne
Innym przykładem może być rejestrowanie polityki, która obejmuje czas naścienny w różnych lokalizacjach. Załóżmy, że mamy fabryki w Detroit, Düsseldorfie i Delhi. Jeśli powiemy, że we wszystkich trzech fabrykach pierwsza zmiana zaczyna się o 6 rano z przerwą na lunch o 11:30, którą można zapisać jako
TIMESTAMP WITHOUT TIME ZONE
. Ponownie, ta informacja jest użyteczna w sposób niejasny, ale nie wskazuje określonego momentu w czasie, dopóki nie zastosujemy strefy czasowej. Na wschodzie zaczyna się nowy dzień. Tak więc fabryka w Delhi zostanie otwarta jako pierwsza o szóstej rano. Kilka godzin później fabryka w Düsseldorfie rozpoczyna pracę o 6 rano. Ale fabryka w Detroit otworzy się dopiero po sześciu godzinach, kiedy nastąpi 6 rano.Porównaj ten pomysł (kiedy zazwyczaj zaczyna się zmiana fabryki) z faktem historycznym, kiedy każdy pracownik fabryki zarejestrował się, aby rozpocząć zmianę w danym dniu. Wejście w to prawdziwy moment, rzeczywisty punkt na osi czasu. Nagrywalibyśmy to w kolumnie typu,
TIMESTAMP WITH TIME ZONE
a nieWITHOUT
typu.Tak, istnieją uzasadnione przypadki użycia
TIMESTAMP WITHOUT TIME ZONE
. Ale z mojego doświadczenia z aplikacjami biznesowymi są stosunkowo rzadkie. W biznesie zależy nam na faktycznych momentach: kiedy faktura rzeczywiście dotarła, kiedy dokładnie umowa wchodzi w życie, w którym momencie wykonano tę transakcję bankową. Więc w takich typowych sytuacjach chcemy tegoTIMESTAMP WITH TIME ZONE
typu.Aby uzyskać więcej dyskusji, zobacz moją odpowiedź na podobne pytanie, czy powinienem przechowywać znaczniki czasu UTC lub czas lokalny dla zmian
Postgres
Pamiętaj, że Postgres nigdy nie zapisuje informacji o strefie czasowej określonych podczas wstawiania znacznika czasu.
TIMESTAMP WITH TIME ZONE
TIMESTAMP WITH TIME ZONE
jakTIMESTAMP WITH RESPECT FOR TIME ZONE
.TIMESTAMP WITHOUT TIME ZONE
Standard SQL ledwo dotyka kwestii typów danych i zachowania w czasie. Baza danych różni się więc znacznie pod względem obsługi daty i godziny.
źródło
21:00
)Chciałbym dodać do tego inny widok, który jest sprzeczny z większością tego, co napisano w innych odpowiedziach. Moim zdaniem
timestamp with time zone
ma bardzo mało ważnych przypadków użycia itimestamp without time zone
ogólnie powinien być preferowany.Po pierwsze, musisz zrozumieć wzorzec „UTC wszędzie”, który jest ogólnie zalecany dla wszystkich aplikacji, które nie mają specjalnych wymagań. Oznacza to po prostu, że Twoja aplikacja powinna reprezentować wszystkie swoje znaczniki czasu w UTC, wszędzie i przez cały czas. Oczywiście będziesz pokazywał użytkownikom lokalną datę / godzinę, ale pomysł polega na przekonwertowaniu ich na samym brzegu programu podczas renderowania widoku. To właściwe miejsce, aby połączyć znacznik czasu UTC (który mógł zostać załadowany z bazy danych) i strefę czasową użytkownika (która mogła pochodzić z przeglądarki) w lokalny znacznik czasu.
Jeśli podążasz za tym wzorem, to
timestamp with time zone
jest to anty-wzór. Wszystko to sprawia, że PostgreSQL wykonuje konwersje strefy czasowej podczas odczytu i zapisu znaczników czasu, w oparciu oTimeZone
zmienną sesyjną PostgreSQL . Zamiast zajmować się strefami czasowymi na samym skraju aplikacji, wprowadziłeś je w samo serce, w samą komunikację z bazą danych. Musisz zawsze zadbać o to, aby PostgreSQL był zawszeTimeZone
odpowiednio skonfigurowany, dodając kolejny niepotrzebny punkt awarii i zamieszania.I po co? Jeśli podążasz za wzorcem UTC wszędzie, twoja aplikacja i tak ma tylko znaczniki czasu UTC; więc po co prosić bazę danych o przeprowadzanie na nich konwersji stref czasowych? Możesz po prostu przechowywać je w
timestamp without time zone
kolumnie i traktować jak zawsze UTC. Bez konwersji, bez stref czasowych, bez komplikacji.źródło
Instance
W NodaTime / JodaTime). Zasadniczotimestamptz
. Celem tego typu jest wykonywanie konwersji stref czasowych jako wartości odczytanych i zapisanych w PostgreSQL (wewnętrznie w bazie danych znacznik czasu jest zawsze zapisywany jako UTC). Zawsze ustawiając strefę czasową sesji na UTC, skutecznie wyłącza te konwersje, więc potimestamptz
co w ogóle korzystać? Innymi słowy, jeśli wartości w bazie danych to UTC, a wartości przychodzące i wychodzące z bazy danych są zawsze UTC, to po co w ogóle mieć świadomość strefy czasowej w bazie danych?date
Datownik również nie zawiera informacji czasowej, jednak wiele osób z niego korzystać.Oczywiście samo to nie jest odpowiedzią.
Można go używać
timestamp
idate
dla dowolnych znaczników czasu i dat, które zawsze znajdują się w tej samej strefie czasowej lub są przechowywane względem pewnej znanej strefy czasowej.Jeśli strefa czasowa jest zawsze taka sama lub niejawna, to raczej antypattern ma ją przechowywać, niż nie przechowywać (informacje redundantne).
Znaczniki czasu mogą być również używane do przechowywania informacji technicznych, takich jak używane w dziennikach aplikacji lub do pomiarów wydajności. W takim przypadku strefa czasowa może być również nieistotna.
I odwrotnie, jeśli projektujesz lub pracujesz w systemie rozproszonym lub w dowolnym systemie, w którym części systemu będą dystrybuowane w różnych strefach czasowych, może to być uważane za anty-wzorzec, którego nie należy używać
timestamp with timezone
, chociaż niektóre systemy mogą być zaprojektowane do działania w jednej strefie czasowej, np. UTC. W takim przypadku logika strefy czasowej może być wpychana do warstwy aplikacji - ale tak, uważam to za anty-wzór.źródło
timestamp without timezone
, ale czy kiedykolwiek coś mi kupuje? W przeciwnym razie dlaczego miałbym się przejmować, jeślitimestamp with timezone data
typ jest zawsze jednakowy lub bardziej odpowiedni?timestamp without timezone
byłaby szybsza, ale jest to prawdopodobnie ważne tylko wtedy, gdy przetwarzasz miliardy wierszy ...timestamp
itimestamptz
oba są przechowywane w ten sam sposób. Informacje o strefie czasowej nie są przechowywane wtimestamptz
, ale zamiast tego są konwertowane na UTC w celu przechowywania. Powiedziałbym, zawsze używaj,timestamptz
gdy znaczniki czasu oznaczają czas bezwzględny . To wszystko cotimestamptz
znaczy. Pisałem o tym tutaj .Przechowywanie i przetwarzanie dat / godzin w czasie lokalnym może wydawać się kuszące, jeśli twoja aplikacja jest ograniczona do jednej strefy czasowej, ale uważam, że to pomyłka.
Po przełączeniu z czasu letniego na standardowy czas powtarza się godzinę w czasie lokalnym (przy założeniu, że różnica wynosi godzinę). Tam, gdzie mieszkam, dzieje się to zwykle około 2 nad ranem, więc czas lokalny biegnie 01:58, 01:59, 01:00 i przesuwa się do 02:00 pod koniec powtarzanej godziny.
Jeśli spróbujesz uporządkować zdarzenia według czasu lokalnego, oznacza to, że zdarzenia z dwóch oddzielnych godzin zostaną zmieszane razem i nie pojawią się w kolejności, w której faktycznie się wydarzyły.
Dla porównania UTC nie ma tego problemu i porządkuje. Tak więc, nawet jeśli pracujesz tylko z jedną strefą czasową, chcesz, aby DB przechowywał i przetwarzał czasy w UTC i konwertował na / z czasu lokalnego dla wprowadzania / wyświetlania. Takie jest zachowanie TIMESTAMP ZE STREFĄ CZASOWĄ.
źródło