web-dev-qa-db-ja.com

PostgreSQLにタイムスタンプを保存するにはどうすればよいですか?

私はPostgreSQL DBの設計に取り組んでおり、タイムスタンプを保存するのに最適な方法を考えています。

仮定

異なるタイムゾーンのユーザーは、すべてのCRUD関数にデータベースを使用します。

私は2つのオプションを見てきました:

  • timestamp NOT NULL DEFAULT (now() AT TIME ZONE 'UTC')

  • bigint NOT NULL DEFAULT

timestampの場合INSERTの瞬間の正確な(UTC)タイムスタンプを表す文字列を送信します。

bigintの場合、まったく同じものを数値形式で保存します。 (タイムゾーンの問題は、ミリがサーバーに渡される前に処理されるため、常にミリはUTCで表示されます。)

bigintを格納することの主な利点の1つは、正しくフォーマットされたタイムスタンプを渡すことが単純な数値(Unix Epoc以降のミリ秒)よりも複雑であるため、格納と取得が簡単になることです。

私の質問は、どちらが最も柔軟な設計を可能にするか、そして各アプローチの落とし穴は何であるかです。

23
Bam

タイムスタンプをtimestamp、またはtimestamptz(_timestamp with time zone_)として保存します複数のタイムゾーンを扱っているので。これは有効なデータを適用し、通常は最も効率的です。データ型を必ず理解してください。誤解がいくつかあります。

あなたの懸念に対処するには:

正しくフォーマットされたタイムスタンプを渡すことは、単純な数値よりも複雑です

必要に応じて、UNIXエポックを渡して取得することができます。

_SELECT to_timestamp(1437346800)
     , extract(Epoch FROM timestamptz '2015-07-20 01:00+02');
_

関連:

currentタイムスタンプをDBへの書き込みと共に保存する場合は、timestamptz列をデフォルト値now()。 DBサーバーのシステム時刻は、通常、複数のクライアントがそれぞれの時刻をそれぞれの概念で処理するよりもはるかに信頼性が高く、一貫しています。
INSERTの場合、次のように簡単にできます。

_CREATE TABLE foo (
  ... -- other columns
, created_at timestamptz NOT NULL DEFAULT now()
);
_

そして、その列には書き込まないでください。自動的に入力されます。

25

組み込み関数を使用できるように、データは常にネイティブデータ型に格納する必要があります。そして、タイムスタンプのデータ型は明らかにtimestampです。

ところで、timestampnotとして文字列として格納され、8バイト整数として格納され、bigintPostgreSQLドキュメント

9
dnoeth