Bagaimana cara terbaik menyimpan stempel waktu di PostgreSQL?

20

Saya sedang mengerjakan desain DB PostgreSQL dan saya bertanya-tanya bagaimana cara terbaik untuk menyimpan cap waktu.

Asumsi

Pengguna di zona waktu yang berbeda akan menggunakan database untuk semua fungsi CRUD.

Saya telah melihat 2 opsi:

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

  • bigint NOT NULL DEFAULT

Karena timestampsaya akan mengirim string yang akan mewakili cap waktu yang tepat (UTC) untuk momen INSERT.

Karena bigintaku akan menyimpan hal yang sama persis, tetapi dalam format angka. (masalah zona waktu ditangani sebelum millis diserahkan ke server, jadi selalu millis dalam UTC.)

Satu keuntungan utama dengan menyimpan a bigintadalah bahwa akan lebih mudah untuk menyimpan dan mengambil, karena melewati cap waktu yang diformat dengan benar lebih kompleks daripada angka sederhana (milis sejak Unix Epoc).

Pertanyaan saya adalah mana yang akan memungkinkan untuk desain yang paling fleksibel dan apa yang bisa menjadi jebakan dari setiap pendekatan.

Bam
sumber
Ada banyak alasan mengapa cap waktu lebih baik daripada tanda besar untuk mewakili cap waktu. Saya tidak bisa memikirkan satu alasan mengapa bigint akan lebih baik daripada cap waktu.
Lennart
Alasan utama saya bisa berpikir BigInt bisa lebih mudah adalah bahwa mungkin jauh lebih mudah untuk mengambil dan menyimpannya. Saya akan memperbarui pertanyaan saya.
Bam

Jawaban:

23

Simpan cap waktu sebagai timestamp, atau lebih tepatnya timestamptz( timestamp with time zone) karena Anda berhadapan dengan beberapa zona waktu . Itu memberlakukan data yang valid dan biasanya paling efisien. Pastikan untuk memahami tipe data, ada beberapa kesalahpahaman yang beredar:

Untuk mengatasi masalah Anda:

melewati timestamp yang diformat dengan benar lebih kompleks daripada angka sederhana

Anda dapat melewati dan mengambil zaman UNIX dengan cara lain jika Anda menginginkan:

SELECT to_timestamp(1437346800)
     , extract(epoch FROM timestamptz '2015-07-20 01:00+02');

Terkait:

Jika Anda ingin menyimpan cap waktu saat ini dengan write ke DB, gunakan timestamptz kolom dengan nilai defaultnow() . Waktu sistem pada server DB biasanya jauh lebih andal dan konsisten daripada banyak klien yang memberikan pendapat masing-masing tentang jam berapa sekarang.
Untuk INSERTitu bisa sesederhana:

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

Dan jangan menulis ke kolom itu. Itu diisi secara otomatis.

Erwin Brandstetter
sumber
Ini membuat semuanya menjadi jelas. Selain fakta bahwa cap waktu disimpan sebagai bilangan bulat 8-byte, penting sama seperti menyimpan sebagai bigint, menyimpan dan mengambil dengan fungsi "to_timestamp" membuat ini pilihan yang jauh lebih sederhana. Terima kasih
Bam
8

Anda harus selalu menyimpan data dalam datatype asli sehingga Anda dapat menggunakan fungsi bawaan. Dan tipe data cap waktu jelas a timestamp.

Btw, sebuah timestamptersebut tidak disimpan sebagai string, itu disimpan sebagai integer 8-byte, persis sama dengan bigint: dokumentasi PostgreSQL .

dnoeth
sumber
Permintaan maaf saya, saya bermaksud mengatakan bahwa saya akan mengirim string untuk penyimpanan, bukan menyimpan stempel waktu. Memperbaikinya.
Bam