TIMESTAMP WITH TIME ZONE을 사용하는 유효한 사용 사례는 무엇입니까?


40

차이점에 대한 길고도 명백한 답변이 있습니다.

  • TIMESTAMP WITH TIME ZONE -vs-
  • TIMESTAMP WITHOUT TIME ZONE

이 SO 게시물에서 사용할 수 있습니다 . 내가 알고 싶은 것은 : 실제로 사용하기위한 유효한 유스 케이스가 TIMESTAMP WITHOUT TIME ZONE있거나 안티 패턴으로 간주되어야합니다.


이 질문은 "주로 의견 기반"으로 폐쇄 될 위험이 있습니다. 아래 답변에서 객관적인 견해를 제시하려고했습니다.
Colin 't Hart

2
이 문제는 매우 실제적이며 각 데이터 유형은 매우 다른 의미를 갖습니다. 따라서 나는이 질문을 주로 의견에 근거한 것으로 간주하지 않을 것입니다.
Basil Bourque

답변:


29

이것은 많은 장소에 명시된 그러나 나는 우리가를 비교할 때 그 가치가 항상 언급 할 생각됩니다 timestamp with time zonetimestamp without time zone유형 : timestamp WITH time zone가게하지 않는 시간대 타임 스탬프와 함께 정보를 . 그것이하는 일은 문서에 명시된대로 UTC 시간대로 모든 데이터를 저장 하는 것입니다 .

시간대가있는 타임 스탬프의 경우 내부 저장된 값은 항상 UTC (Universal Coordinated Time, 그리니치 표준시 (GMT)라고 함)입니다. 명시 적 시간대가 지정된 입력 값은 해당 시간대에 대한 적절한 오프셋을 사용하여 UTC로 변환됩니다. 입력 문자열에 시간대가 지정되어 있지 않으면 시스템의 TimeZone 매개 변수로 표시된 시간대에있는 것으로 가정하고 시간대에 대한 오프셋을 사용하여 UTC로 변환됩니다.

timestamp WITHOUT time zone(1) 모든 것이 동일한 시간대에 있거나 (2) 애플리케이션 계층이 시간대를 처리하고 특정 시간대 (일반적으로 UTC)에 모든 것을 저장하는 상황에서 일부는 사용하기 에 유효한 것으로 간주됩니다 . 그러나 (1)에 대한 올바른 해결책은 시스템에 대해 주어진 시간대로 TimeZone 설정을 구성하고 (2)가 이미 해결되어 PostgreSQL이 이미 동일한 시간대에 모든 것을 저장하기 때문에 안티 패턴으로 간주됩니다. (UTC).

이제, 그 두 가지가 다운되면, 나는 한 가지 좋은 이유만으로 올 수있었습니다 timestamp WITHOUT time zone. 그것은 미래에 이벤트를 저장하고 싶을 때입니다. 그리고 우리가 그 시간에 도달했을 때 어떤 종류의 경고가 발생해야합니다. timestamp WITH time zone시간대에 대한 지역 법률에 의해 정의 된 규칙이 변경되지 않은 경우에만 유용 할 수 있습니다 . 변경되는 가장 일반적인 규칙은 DST (일광 절약 시간제) 채택에 관한 것입니다.

예를 들어, 2013-06-15(DST에 아직없는) 일정 (일부 DST에있을 예정)에서 일정 2013-01-15 10:00이 있고 해당 2013-06-15지역에서 DST를 채택하도록 지정 되었다고 가정 해 봅시다 . 그러나 그 후 얼마 후, 정부는 규칙을 변경하여 해당 지역에서 더 이상 DST를 사용하지 않으며 갑자기 예정된 시간이 2013-01-15 11:00(가 아닌 10:00) 사용 timestamp WITH time zone하고 TZ 구성을 최신 상태로 유지하도록합니다. 물론 관심있는 지역 / 시간대의 규칙 변경 사항을 추적하고 영향을받는 레코드를 업데이트하는 경우 이러한 사례를 표준 시간대로 처리 할 수도 있습니다.

일부 지역은 종종 이러한 규칙을 변경한다는 점을 언급 할 필요가 있습니다 (브라질에서와 같이 일부 국가-국가 전체가 아닌-종종 변경됨). 그러나 대부분의 경우이 규칙이 매우 일찍 변경되므로 사용자는 현재 시간

모든 말로, 나는 하나의 제안 만 더 있습니다. 다른 시간대에 사용자, 로그 또는 다른 것이있는 경우 해당 시간대를 다른 곳에 저장하고을 선택하여 사용하십시오 timestamp with time zone. 이렇게하면 (1) 시간대에 관계없이 서로 다른 소스에 대해 서로 더 근접한 교차 이벤트를 수행하고 (2) 이벤트가 발생한 원래 시간 (시계 시간)을 표시 할 수 있습니다.


"시간대에 타임 스탬프를 사용해야하는 이유는 하나뿐입니다." 그것이 오타가 아니라면 실제로 "시간대가없는 타임 스탬프"가 "시간대가있는 타임 스탬프"보다 실제로 더 적절하고 덜 이해하기 쉽다고 제안하고 있습니까? 그것은 반 직관적 인 것 같습니다.
Marcus Junius Brutus

@MarcusJuniusBrutus, 죄송합니다. 오타였습니다. 다른 방법으로 생각했습니다 ... 수정 된 답변을 확인하십시오.
MatheusOl

codeblog.jonskeet.uk/2019/03/27/… 이 같은 미래의 이벤트 룰 규칙 변경 시나리오 (동일한 결론)에 대해 자세히 설명합니다
Beni Cherniavsky-Paskin

17

예. 에 대한 사용 사례가 TIMESTAMP WITHOUT TIME ZONE있습니다.

  • 일반적인 비즈니스 앱에서이 유형은 다음 용도로만 사용됩니다.
    • 향후 약속 예약
    • 도쿄 파리에서 23 일 정오와 같은 다양한 시간대 에서 동일한 시간대를 나타냄 (두 시간 간격으로 동일한 시간대)
  • 순간 추적을 위해 타임 라인의 특정 지점은 항상을 사용하고을 사용 TIMESTAMP WITH TIME ZONE하지 않습니다 WITHOUT.

TIMESTAMP WITHOUT TIME ZONE값은 실제 순간이 아니라 타임 라인의 한 지점 이 아닙니다 . 잠재적 인 모멘트, 약 26-27 시간 범위 (전 세계 시간대 범위)에 따라 타임 라인의 가능한 지점에 대한 대략적인 아이디어를 나타냅니다 . 표준 시간대 또는 오프셋 -UTC 를 적용 할 때까지 실제 의미가 없습니다 .

예 : 크리스마스

예를 들어, 휴일 / 거룩한 날의 시작을 기록해야한다고 가정하십시오.

Table: holiday_

Column: year_         Type: SMALLINT
Column: description_  Type: VARCHAR
Column: start_        Type: TIMESTAMP WITHOUT TIME ZONE

크리스마스가 올해 12 월 25 일 자정 이후에 시작된다는 사실을 기록하려면 2016-12-25 00:00:00시간대없이 말할 필요가 있습니다. 산타의 날 초 그는 자정 직후 오클랜드 뉴질랜드를 방문합니다. 지구상에서 가장 빠른 자정 중 하나이기 때문입니다. 그런 다음 그는 다음 자정에 일어나서 곧 필리핀에 도착하여 서쪽으로 나아갑니다. 그런 다음 순록은 서부 방향으로 진행하여 자정에 인도에 도달합니다. 자정에 오클랜드 자정 몇 시간 후에 발생합니다. 훨씬 후에도 여전히 파리 FR에서 자정이며, 몬트리올 CA에서 여전히 자정입니다. 산타의 모든 방문은 다른 순간에 발생 하지만 시간 은 각 지역의 자정에 따라 자정 직후에 발생했습니다.

따라서 2016-12-25 00:00:00크리스마스가 시작될 때 시간대없이 기록 하는 것은 유익하고 합법적이지만 모호합니다. "오클랜드의 크리스마스"또는 "몬트리올의 크리스마스"라고 말할 때까지 특정 시점이 없습니다. 썰매가 닿을 때마다 실제 순간을 기록하는 TIMESTAMP WITH TIME ZONE경우 WITHOUT유형 대신에 사용 합니다.

크리스마스와 비슷한 새해 전야입니다. 뉴욕에 타임 스퀘어 볼이 떨어졌을 때 시애틀 사람들은 여전히 ​​샴페인을 식히고 파티 뿔을 준비하고 있습니다. 그러나 우리는 기록 할 것 아이디어 로 신년 순간을 2017-01-01 00:00:00A의 TIMESTAMP WITHOUT TIME ZONE. 반대로, 공이 뉴욕에서 떨어졌을 때 또는 시애틀에있는 사람들이 뿔을 날렸을 때 를 기록 하려면 대신 3 시간 간격으로 실제 순간을 기록하는 데 대신 (사용 TIMESTAMP WITH TIME ZONE하지 않음 WITHOUT)을 사용 합니다.

예 : 공장 교대

다른 예는 다양한 위치에서 벽시계 시간 과 관련된 정책을 기록하는 것일 수 있습니다 . 디트로이트, 뒤셀도르프, 델리에 공장이 있다고 가정 해 봅시다. 세 공장 모두에서 첫 번째 교대가 오전 6시 30 분에 점심 시간으로 오전 11시 30 분에 시작된다고 말하면 이는로 기록 될 수 있습니다 TIMESTAMP WITHOUT TIME ZONE. 이 정보는 모호한 방식으로 유용하지만 시간대를 적용 할 때까지 특정 시점을 나타내지는 않습니다. 동쪽에서 일찍 새로운 날이 시작됩니다. 따라서 델리 공장은 오전 6시에 처음으로 문을 열 것입니다. 몇 시간 후 뒤셀도르프 공장은 오전 6시에 작업을 시작합니다. 그러나 디트로이트 공장은 6시 이후에 오전 6 시가 될 때까지 실제로 문을 열지 않습니다.

이 개념 (공장 교대가 일반적으로 시작되는시기)과 각 공장 근로자가 특정 날짜에 교대 근무를 시작한 시점에 대한 역사적 사실과 대조하십시오. 시계는 실제 순간, 타임 라인의 실제 지점입니다. 따라서 유형이 TIMESTAMP WITH TIME ZONE아닌 유형의 열에 기록합니다 WITHOUT.

예,에 대한 합법적 인 사용 사례가 TIMESTAMP WITHOUT TIME ZONE있습니다. 그러나 비즈니스 응용 프로그램에 대한 경험에서 볼 때 상대적으로 드물습니다. 비즈니스에서는 실제 순간에 관심을 갖는 경향이 있습니다. 인보이스가 실제로 언제 도착했는지, 계약이 정확히 언제 발효되는지, 은행 거래가 어느 시점에서 실행 되었는가. 따라서 이러한 일반적인 상황에서는 TIMESTAMP WITH TIME ZONE유형이 필요합니다 .

더 설명을 참조 내 대답을 비슷한 질문에 변화를위한해야 내가 저장 UTC 타임 스탬프 또는 localtime으로

포스트그레스

Postgres는 특히 타임 스탬프를 삽입 할 때 지정된 시간대 정보를 저장 하지 않습니다 .

  • TIMESTAMP WITH TIME ZONE
    • 입력 데이터에 포함 된 지정된 시간대 또는 오프셋을 사용하여 값을 UTC로 조정하고 저장합니다. 전달 된 영역 / 오프셋 정보는 폐기됩니다. 생각 TIMESTAMP WITH TIME ZONE으로 TIMESTAMP WITH RESPECT FOR TIME ZONE.
    • 인도에서 올해 3 월 7 일 정오 12시를 입력하면 오전 5시 30 분 (오전 6시 30 분)을 빼서 UTC로 조정됩니다.
  • TIMESTAMP WITHOUT TIME ZONE
    • 입력 데이터에 포함 된 지정된 시간대 또는 오프셋은 모두 무시됩니다.
    • 인도에서 올해 3 월 7 일 12:00 정오의 입력은 조정없이 올해 3 월 7 일 12:00로 기록됩니다.

SQL 표준은 날짜-시간 데이터 유형 및 동작 문제에 대해서는 거의 다루지 않습니다. 데이터베이스 그래서 변화 널리 날짜 - 시간을 처리.


공장 (또는 병원) 교대와 더불어 DST 전환 일에 묘지 교대 근무를하는 사람은 시간대없이 잘못 기록 된 시간을 기록하게됩니다.
Jasen

나는 마지막 예제에 오타가 있다고 생각 : '년 3 월 7 일 12:00의 입력이 ..해야한다'로 기록 12 : 00 '(안 21:00)
TmTron

10

나는 이것에 또 다른 견해를 추가하고 싶습니다. 다른 답변에서 쓰여진 것의 많은 것에 반대합니다. 제 생각 timestamp with time zone에는 유효한 유스 케이스가 거의 없으며 timestamp without time zone일반적으로 선호되어야합니다.

먼저 "UTC everywhere"패턴을 이해해야합니다. 일반적으로 특별한 요구 사항이없는 모든 응용 프로그램에 권장됩니다. 단순히 응용 프로그램이 모든 시간 소인을 UTC로 언제 어디서나 나타내야 함을 의미합니다. 물론 현지 날짜 / 시간을 사용자에게 표시하지만 뷰를 렌더링 할 때 프로그램의 맨 끝에서이를 변환하는 것이 좋습니다. UTC 타임 스탬프 (데이터베이스에서로드했을 수 있음)와 사용자 시간대 (브라우저에서 제공되었을 수 있음)를 로컬 타임 스탬프로 결합 할 수있는 올바른 위치입니다.

이 패턴을 따르는 경우 timestamp with time zone안티 패턴입니다. 이 유형은 PostgreSQL TimeZone세션 변수를 기반으로 타임 스탬프를 읽고 쓸 때 PostgreSQL이 시간대 변환을 수행하도록합니다 . 응용 프로그램의 가장 가장자리에있는 시간대를 처리하는 대신 데이터베이스와의 통신에 중심을 두었습니다. PostgreSQL을 항상 TimeZone올바르게 구성하여 불필요한 실패 및 혼란을 야기하도록 주의를 기울여야합니다 .

그리고 무엇을 위해? UTC 어디서나 패턴을 따르는 경우 응용 프로그램에는 UTC 타임 스탬프 만 있습니다. 왜 데이터베이스에 시간대 변환을 요청합니까? timestamp without time zone열에 간단히 저장하고 항상 UTC처럼 취급 할 수 있습니다. 전환, 시간대, 합병증 없음


2
타임 스탬프의 지지자들도 "UTC everywhere"패턴을지지한다고 생각합니다. 그냥 규칙을 적용하기 위해 응용 프로그램 / API 개발자 만 의존하는 대신 데이터베이스 수준에서 규칙을 시행하는 것입니까? 그 관행을 시행 할 수 있다면 왜 안 되겠습니까? 또한 모든 postgres 연결이 시간대를 UTC로 설정하도록 강요 할 수 있습니다. 그렇지 않은 경우에도 ISO 형식에는 tz 오프셋이 포함됩니다. 그렇다면 UTC와 같은 것이 아니라 시행되고 있습니까?
iamnat

2
먼저 PostgreSQL TimeZone이 UTC 이외의 것으로 설정되어 있고 타임 스탬프를 사용하는 경우 프로그램은 비 UTC 타임 스탬프를 읽습니다. 이것은 단순히 "UTC everywhere"패턴이 아니며 클라이언트 언어에 따라 많은 합병증을 유발하거나 유발하지 않을 수 있습니다. 어느 곳에서나 UTC이거나 현지 타임 스탬프를 사용하고 있습니다.
Shay Rojansky

둘째, 응용 프로그램의 모든 곳에서 UTC 인 경우 타임 스탬프에 ISO 형식으로 보낼 tz 오프셋이 없습니다. 구체적인 내용은 언어마다 다를 수 있지만 UTC 타임 스탬프 (예 : InstanceNodaTime / JodaTime) 이외의 다른 것을 표현할 수없는 클라이언트 유형을 사용하는 것이 이상적 입니다. 당신은 기본적으로 "UTC everywhere"가 거의 뒤 따르거나 다소 뒤 따르는 상황을 설명하고 있습니다.
Shay Rojansky

다시 한 번, 일부 서버에 새 PostgreSQL 인스턴스가 설정되어 실수로 기본적으로 구성된 로컬 시스템 시간대가 유지되는 것을 상상하기가 매우 쉽습니다. 응용 프로그램은이 서버에서 읽고 완전히 임의의 시간대 (서버가있는 시간대)에서 로컬 타임 스탬프를 가져옵니다. 추가 합병증이 필요한 이유는 무엇입니까?
Shay Rojansky

응용 프로그램이 set time zone to 'utc'연결될 때 어떻게 수행되지 않습니까?
Jasen

2

date타임 스탬프는 시간대 정보를 포함하지 않는, 아직 많은 사람들이 그것을 사용할 수 있습니다.

물론 그 자체로는 답이 아닙니다.

그것은 사용하기 유효한의 timestampdate같은 시간대에 항상 또는 일부 알려진 시간대를 기준으로 저장되는 모든 타임 스탬프와 날짜를.

시간대가 항상 동일하거나 암시적인 경우 시간대를 저장하지 않는 것 (중복 정보)보다 반 패턴이 더 중요합니다.

타임 스탬프는 응용 프로그램 로그 또는 성능 측정에 사용되는 기술 정보를 저장하는 데에도 사용할 수 있습니다. 이 경우 시간대도 중요하지 않을 수 있습니다.


반대로, 분산 시스템 또는 시스템의 일부가 다른 시간대에 분산되어있는 시스템에서 설계 또는 작업하는 경우 timestamp with timezone일부 시스템은 실행되도록 설계 될 수 있지만 사용하지 않는 반 패턴으로 간주 될 수 있습니다. 한 시간대 (예 : UTC) 이 경우 표준 시간대 논리가 응용 프로그램 계층으로 푸시 될 수 있습니다.하지만 이것을 반 패턴으로 간주합니다.


어떤 경우에는 사용하기가 아프지 timestamp without timezone않지만 나에게 아무것도 사지 않는다는 것을 알고 있습니다. 그렇지 않으면 timestamp with timezone data유형이 항상 동일하거나 더 적합한 지 왜 신경 써야 합니까?
Marcus Junius Brutus

중복 정보를 저장하지 않는 것이 저의 주요 논거입니다. 날짜 계산 timestamp without timezone도 빠르다고 생각하지만 수십억 행을 처리하는 경우에만 중요합니다.
Colin 't Hart

1
@ Colin'tHart timestamptimestamptz같은 방식으로 저장됩니다. 에 저장된 표준 시간대 정보가 timestamptz없지만 대신 저장을 위해 UTC로 변환됩니다. timestamptz문제의 타임 스탬프가 절대 시간을 나타내는 경우 항상 사용 하십시오 . 그게 다 무슨 timestamptz의미. 나는 이것에 대해 여기에 썼다 .
fphilipe 2016 년

2

응용 프로그램이 단일 시간대로 제한되어 있으면 날짜 / 시간을 현지 시간으로 저장하고 처리하는 것이 유혹적인 것처럼 보일 수 있지만 이것이 실수라고 생각합니다.

일광 절약 시간에서 표준 시간으로 다시 전환하면 현지 시간으로 1 시간이 반복됩니다 (차가 1 시간이라고 가정). 내가 사는 곳은 일반적으로 오전 2 시경에 발생하므로 현지 시간은 01:58, 01:59, 01:00이며 반복 시간이 끝날 때만 02:00으로 진행됩니다.

현지 시간을 사용하여 시간별로 이벤트를 주문하려고하면 두 개의 개별 시간의 이벤트가 함께 혼합되어 실제로 발생한 순서대로 나타나지 않습니다.

이에 비해 UTC에는이 문제가없고 깨끗하게 주문합니다. 따라서 하나의 표준 시간대로 작업하는 경우에도 DB가 시간을 UTC로 저장 및 처리하고 현지 시간으로 입력 / 표시를 변환하기를 원합니다. 이것은 TIMESTAMP WITH TIME ZONE의 동작입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.