TIMESTAMP WITHOUT TIME ZONEを使用する有効なユースケースは何ですか?


40

の違いについては、非常に解明の長い答えがあります

  • TIMESTAMP WITH TIME ZONE -対-
  • TIMESTAMP WITHOUT TIME ZONE

このSOポストで利用可能です。私が知りたいのは、実際に使用するための有効なユースケースがありますか、TIMESTAMP WITHOUT TIME ZONEそれともアンチパターンと見なされるべきですか?


この質問は、「主に意見に基づいて」閉じられるリスクを負います。以下の回答では、客観的な意見を述べようとしました。
コリン 'tハート14

2
この問題は非常に現実的であり、各データ型は非常に異なる意味を持っています。したがって、私はこの質問を主に意見に基づくものとは考えないでしょう。
バジルブルク

回答:


29

これは、多くの場所で述べたが、私たちは比較するとき、それは価値が常に言及すると思いますされtimestamp with time zonetimestamp without time zoneタイプ:保存されていない時間帯のタイムスタンプと一緒に情報を。それが行うことは、ドキュメントに記載されているように、 UTCタイムゾーンですべてのデータを保存することです:timestamp WITH time zone

タイムゾーン付きのタイムスタンプの場合、内部に格納されている値は常にUTC(協定世界時、従来はグリニッジ標準時、GMT)になっています。指定された明示的なタイムゾーンを持つ入力値は、そのタイムゾーンの適切なオフセットを使用してUTCに変換されます。入力文字列にタイムゾーンが指定されていない場合、システムのTimeZoneパラメーターで指定されたタイムゾーンにあると見なされ、タイムゾーンゾーンのオフセットを使用してUTCに変換されます。

timestamp WITHOUT time zone(1)すべてが同じタイムゾーンにある、または(2)アプリケーション層がタイムゾーンを処理し、特定のタイムゾーン(通常はUTC)にすべてを格納する状況で使用することが有効であると考えられます。しかし、(1)の正しい解決策は、システムの指定された1つのタイムゾーンにTimeZone設定を構成することであり、(2)PostgreSQLはすべてを同じタイムゾーンに既に保存しているため、アンチパターンとも見なされます(UTC)。

さて、これらの2つがダウンしているので、使用する正当な理由が1つだけありますtimestamp WITHOUT time zone。これは、将来イベントを保存したいときであり、その時間になったときに何らかのアラートをトリガーする必要があります。これはtimestamp WITH time zone、タイムゾーンに関する地域の法律で定義されているルールが変更されていない場合にのみ有効です。変更される最も一般的なルールは、夏時間(DST)の採用に関することです。

たとえば、2013-06-15(まだDSTになっていない)で2013-01-15 10:00(既にDSTにある)イベントが発生するようにスケジュールし2013-06-15、あなたの地域でDSTを採用するように指定されているとします。しかし、その後しばらくして、政府はルールを変更し、お住まいの地域でDSTが使用されなくなり、突然、予定時刻が2013-01-15 11:00(ではなく10:00)になり、を使用しtimestamp WITH time zoneてTZ構成を最新の状態に保つようになりました。もちろん、関心のある地域/タイムゾーンでルールの変更を追跡し、影響を受けるレコードを更新する場合、タイムゾーンでもそのようなケースを処理することが可能であることに気付くかもしれません。

一部の地域ではこれらのルールが頻繁に変更されることに言及する価値があります(ブラジルのように、国全体ではなく一部の州が頻繁に変更されます)が、ほとんどの場合、それは非常に早く変更されるため、ユーザーは、現在の時刻。

とはいえ、もう1つだけ提案があります。異なるタイムゾーンにユーザー、ログ、または何かがある場合は、それらがどこかから来ているタイムゾーンを保存し、を選択して使用しますtimestamp with time zone。その方法で、(1)異なるソースで互いに近くで発生するイベントを(タイムゾーンとは無関係に)交差させ、(2)イベントが発生した元の時間(クロック時間)を表示できます。


あなたは言っています:「タイムゾーンでタイムスタンプを使用する正当な理由は1つしかありません」。それがタイプミスではない場合、「タイムゾーンのないタイムスタンプ」は実際には「タイムゾーンのあるタイムスタンプ」よりも適切であり、誤解を生じにくいことを示唆していますか?それは私には直観に反しているようです。
マーカスジュニウスブルータス14

@MarcusJuniusBrutus、申し訳ありませんが、それは確かにタイプミスであり、私は別の方法を考えました...編集された答えを確認してください。
MatheusOl 14

codeblog.jonskeet.uk/2019/03/27/…この未来のイベントルールが変わる可能性のあるシナリオ(詳細は同じ)を詳細に説明します
Beni Cherniavsky-Paskin

17

はい。のユースケースがありますTIMESTAMP WITHOUT TIME ZONE

  • 一般的なビジネスアプリでは、このタイプは以下にのみ使用されます。
    • 今後の予定を予約する
    • 東京パリの23日の正午など、さまざまなタイムゾーンで同じ時刻を表します(2つの異なる時間間隔、同じ時刻)
  • タイムライン上の特定のポイントの瞬間を追跡するTIMESTAMP WITH TIME ZONEには、常にではなくを使用しますWITHOUT

TIMESTAMP WITHOUT TIME ZONE値はタイムライン上のポイントではなく、実際の瞬間ではありません。これらは、潜在的な瞬間、約26〜27時間の範囲(世界中のタイムゾーンの範囲)に沿ったタイムライン上の可能なポイントに関する大まかなアイデアを表しています。タイムゾーンまたはoffset-from-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、タイムゾーンなしで言う必要があります。サンタの日の早い時間に、彼は真夜中の直後にオークランドNZを訪れます。これは地球上で最も早い真夜中の1つです。それから、次の真夜中が来ると、彼は西に向かって働き、すぐにフィリピンに到着します。その後、トナカイは西の方向に進み、そのオークランドの真夜中の数時間後に起こる真夜中にインドに到達します。それよりずっと後は、パリFRの真夜中であり、まだモントリオールCAの真夜中です。サンタによるこれらの訪問はすべて異なる時間に発生しますが、すべての地域の深夜ごとに、深夜直後に行われました。

したがって2016-12-25 00:00:00、クリスマスの始まりとしてタイムゾーンなしで録音することは有益であり合法ですが、あいまいです。「オークランドのクリスマス」または「モントリオールのクリスマス」と言うまで、特定の時間はありません。そりが着地するたびに実際の瞬間を記録する場合TIMESTAMP WITH TIME ZONEは、WITHOUTタイプではなく使用します。

クリスマスと同様に大New日です。タイムズスクエアボールがニューヨーク落ちたとき、シアトルの人々はまだシャンパンを冷やしてパーティーホーンを準備しています。しかし、我々は計上する考え方として、新年の瞬間のを2017-01-01 00:00:00AではTIMESTAMP WITHOUT TIME ZONE。対照的に、ボールがニューヨークに落ちたとき、またはシアトルの人々が角を吹いたときを記録したい場合、代わりにTIMESTAMP WITH TIME ZONE(ではなくWITHOUT)を使用して、実際の瞬間を3時間ごとに記録します。

例:工場シフト

別の例としては、さまざまな場所での実時間を含むポリシーの記録があります。デトロイト、デュッセルドルフ、デリーに工場があるとします。3つの工場すべてで、最初のシフトが午前6時から始まり、昼休みが午前11時30分であると言う場合、それはとして記録できますTIMESTAMP WITHOUT TIME ZONE。繰り返しますが、この情報はあいまいな方法で役立ちますが、タイムゾーンを適用するまで特定の時点を示すものではありません。新しい日は東のより早い夜明けです。したがって、デリー工場は午前6時に最初にオープンします。数時間後、デュッセルドルフの工場は午前6時に作業を開始します。しかし、デトロイトの工場は、6時間後の午前6時になってから実際に開きます。

この(工場のシフトが一般にいつ始まるのか)という考え方と、各工場の労働者が特定の日にシフトを開始するためにいつ入社したかという歴史的事実とは対照的です。出勤は実際の瞬間であり、タイムライン上の実際のポイントです。したがって、タイプTIMESTAMP WITH TIME ZONEではなくタイプの列に記録しますWITHOUT

そのため、はい、の正当なユースケースがありTIMESTAMP WITHOUT TIME ZONEます。しかし、ビジネスアプリでの私の経験では、それらは比較的まれです。ビジネスでは、実際の瞬間に注意を払う傾向があります。請求書が実際に到着したのはいつか、正確にその契約が有効になるのはいつか、銀行取引はいつ行われたのか。そのため、このような一般的な状況では、TIMESTAMP WITH TIME ZONEタイプが必要です。

詳細については、同様の質問への回答を参照しください。シフトのUTCタイムスタンプまたは現地時間を保存する必要があります

ポストグレス

Postgresは、タイムスタンプの挿入時に指定されたタイムゾーン情報を保存しないことに注意してください。

  • TIMESTAMP WITH TIME ZONE
    • 入力データに含まれる指定されたタイムゾーンまたはオフセットは、値をUTCに調整して保存するために使用されます。渡されたゾーン/オフセット情報は破棄されます。考えるTIMESTAMP WITH TIME ZONEようにTIMESTAMP WITH RESPECT FOR TIME ZONE
    • 今年3月7日正午のインドでの入力では、時刻をUTCに調整するために、5時間半(6:30 AM)が差し引かれます。
  • TIMESTAMP WITHOUT TIME ZONE
    • 入力データに含まれる指定されたタイムゾーンまたはオフセットは完全に無視されます。
    • 今年3月7日正午のインドでの入力は、調整なしで今年3月7日の12:00として記録されます。

SQL標準は、日時データ型と動作の問題にほとんど触れていません。そのため、データベースは日時の処理が大きく異なります。


さらに工場(または病院)のシフトで、DST切り替えの日に墓地シフトを働いて誰もが自分の時間が誤ってそれがタイムゾーンなしで記録年代の記録があります...
Jasen

記録「する必要があります。.. 3月7日正午の入力『:私は最後の例にタイプミスがあると思います12:00』(ない21:00
TmTron

11

これに別のビューを追加したいと思います。これは、他の回答に書かれている内容の多くに反します。私の意見でtimestamp with time zoneは、有効なユースケースはほとんどなくtimestamp without time zone、一般的には優先されるべきです。

最初に、「UTC everywhere」パターンを理解する必要があります。これは、通常、特別な要件を持たないすべてのアプリケーションに推奨されます。これは、アプリケーションがすべてのタイムスタンプをいつでもどこでもUTCで表す必要があることを意味します。もちろん、ユーザーにローカルの日付/時刻を表示しますが、ビューをレンダリングするときに、プログラムの端でこれらを変換することを考えています。これは、UTCタイムスタンプ(データベースからロードした可能性があります)とユーザーのタイムゾーン(ブラウザーから取得した可能性があります)をローカルタイムスタンプに結合する適切な場所です。

このパターンに従っている場合timestamp with time zoneは、アンチパターンです。このタイプのすべては、PostgreSQL TimeZoneセッション変数に基づいて、タイムスタンプを読み書きするときにPostgreSQLにタイムゾーン変換を実行させることです。アプリケーションのエッジでタイムゾーンを処理する代わりに、それらをその中心部、つまりデータベースとのまさにコミュニケーションに導入しました。PostgreSQLを常にTimeZone適切に構成し、不必要な障害点と混乱を追加するように常に注意する必要があります。

そして何のために?UTC Everywhereパターンに従っている場合、アプリケーションにはとにかくUTCタイムスタンプしかありません。なぜあなたのデータベースにタイムゾーン変換をするよう頼むのですか?それらをtimestamp without time zone列に保存するだけで、常にUTCのように扱うことができます。変換、タイムゾーン、合併​​症はありません。


2
timestamptzの支持者も「UTC Everywhere」パターンをサポートしていると思います。ルールは、アプリ/ API開発者のみに依存するのではなく、データベースレベルで強制されるだけです。あなたがその慣行を実施することができるなら、なぜですか?また、すべてのpostgres接続がタイムゾーンをUTCに設定するように強制できます。含まれていなくても、ISO形式にはtzオフセットが含まれます。それはどこでもUTCと同じことではありませんが強制されていますか?
iamnat

3
まず、PostgreSQL TimeZoneがUTC以外に設定され、timestamptzを使用している場合、プログラムは非UTCタイムスタンプを読み取ります。これは単に「どこでもUTC」パターンではなく、クライアントの言語に応じて、多くの複雑な問題が発生する場合と発生しない場合があります。どちらかどこでも、またはローカルタイムスタンプを使用しているしているUTC ....
シェイRojansky

次に、アプリケーションのどこでもUTCである場合、タイムスタンプにISO形式で送信するtzオフセットはありません。詳細は言語によって異なりますが、理想的には、UTCタイムスタンプ以外を表すことができないクライアントタイプを使用する必要があります(例:InstanceNodaTime / JodaTime)。あなたは、基本的には...「UTCはどこでも」ほとんどの後、またはちょっと続いている状況を説明している
シェイRojanskyを

繰り返しますが、新しいPostgreSQLインスタンスが何らかのサーバーにセットアップされ、デフォルトで設定されているローカルマシンのタイムゾーンを誤って保持することは非常に簡単です。アプリケーションはこのサーバーから読み取り、完全に任意のタイムゾーン(サーバーがたまたま入っている)でローカルタイムスタンプを取得します。なぜこの追加の複雑化が必要なのでしょうか?
シェイロヤンスキー

1
それは可能ですが、それを使用することはさらに意味がありませんtimestamptz。このタイプの全体的なポイントは、PostgreSQLに読み書きされる値としてタイムゾーン変換を実行することです(データベース内では、タイムスタンプは常にUTCとして保存されます)。セッションのタイムゾーンを常にUTCに設定すると、これらの変換が事実上無効timestamptzになります。なぜ使用するのですか?別の言い方をすれば、データベース内の値がUTCであり、データベースに出入りする値が常にUTCである場合、なぜデータベースにタイムゾーンが認識されるのでしょうか。
シェイロ

2

dateタイムスタンプはまた、タイムゾーン情報が含まれていない、まだ多くの人がそれを使用しています。

もちろん、それ自体は答えではありません。

これは、使用に有効だtimestampdate同じ時間帯に常にある任意のタイムスタンプと日付のために、またはいくつかの既知の時間帯に比べて保存されています。

タイムゾーンが常に同じまたは暗黙的である場合、保存しない(冗長な情報)よりも保存する方がアンチパターンです。

タイムスタンプは、アプリケーションログやパフォーマンス測定で使用されるような技術情報の保存にも使用できます。この場合、タイムゾーンも重要ではありません。


逆に、分散システム、またはシステムの一部が異なるタイムゾーンに分散されるシステムで設計または作業している場合timestamp with timezone、使用しないアンチパターンと見なされる場合がありますが、一部のシステムは実行するように設計されている場合があります1つのタイムゾーン(UTCなど)で。この場合、タイムゾーンロジックはアプリケーションレイヤーにプッシュされる可能性がありますが、これはアンチパターンと考えています。


特定のケースではを使用しても害はないことを理解していますがtimestamp without timezone、何か購入することはありますか?それ以外の場合、timestamp with timezone dataタイプが常に同等またはより適切である場合、なぜ気にする必要がありますか?
マーカスジュニウスブルータス14

冗長な情報を保存しないことが私の主な議論です。私は上の日付計算を推定timestamp without timezoneあなたが数十億行を処理している場合は、あまりにも、より高速になりますが、それはおそらく唯一重要です...
コリン・「ハートトン

1
@ Colin'tHart timestamptimestamptz同じ方法で保存されます。に保存されるタイムゾーン情報はありませんtimestamptzが、代わりに保存のためにUTCに変換されます。私はtimestamptz、問題のタイムスタンプが絶対時間を示すときに常に使用すると言います。それがすべてのtimestamptz意味です。ここでこれについて書い
fphilipe

2

アプリケーションが単一のタイムゾーンに制限されている場合、現地時間で日付と時刻を保存および処理するのは魅力的かもしれませんが、これは間違いだと思います。

夏時間から標準時間に切り替えると、現地時間で1時間繰り返されます(差が1時間であると仮定)。私が住んでいる場所では、これは通常午前2時頃に発生するため、現地時間は01:58、01:59、01:00であり、繰り返される時間の終わりに02:00までしか進みません。

現地時間を使用して時間順にイベントを並べようとすると、2時間のイベントが混在し、実際に発生した順序で表示されません。

比較すると、UTCにはこの問題はなく、きれいに注文します。そのため、1つのタイムゾーンだけで作業している場合でも、DBにUTCで時刻を保存および処理し、入力/表示のためにローカル時刻との間で変換する必要があります。これはTIMESTAMP WITH TIME ZONEの動作です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.