Haruskah saya menggunakan tipe data datetime atau timestamp di MySQL?

Jawaban:

1830

Cap waktu di MySQL biasanya digunakan untuk melacak perubahan pada catatan, dan sering diperbarui setiap kali catatan diubah. Jika Anda ingin menyimpan nilai tertentu, Anda harus menggunakan bidang datetime.

Jika Anda ingin memutuskan antara menggunakan stempel waktu UNIX atau bidang datetime MySQL asli, gunakan format asli. Anda dapat melakukan perhitungan dalam MySQL dengan cara ("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)")itu dan mudah untuk mengubah format nilai menjadi cap waktu UNIX ("SELECT UNIX_TIMESTAMP(my_datetime)")ketika Anda meminta catatan jika Anda ingin mengoperasikannya dengan PHP.

Blivet
sumber
981
Perbedaan penting adalah yang DATETIMEmewakili tanggal (seperti yang ditemukan dalam kalender) dan waktu (seperti yang dapat diamati pada jam dinding), sementara TIMESTAMPmewakili titik waktu yang didefinisikan dengan baik. Ini bisa sangat penting jika aplikasi Anda menangani zona waktu. Berapa lama '2010-09-01 16:31:00'? Itu tergantung pada zona waktu Anda. Bagi saya itu hanya beberapa detik yang lalu, bagi Anda itu mungkin mewakili waktu di masa depan. Jika saya katakan 1283351460 detik sejak '1970-01-01 00:00:00 UTC', Anda tahu persis titik waktu yang saya bicarakan. (Lihat jawaban Nir yang sangat baik di bawah). [Kelemahan: rentang yang valid].
MattBianco
121
Perbedaan lain: kueri dengan datetime "asli" tidak akan di-cache, tetapi kueri dengan stempel waktu - adalah.
OZ_
39
"Stempel waktu di MySQL biasanya digunakan untuk melacak perubahan pada catatan" Jangan berpikir itu jawaban yang bagus. Timestamp jauh lebih kuat dan rumit daripada yang MattBianco dan Nir sayd. Meskipun, bagian kedua dari jawabannya sangat bagus. Memang benar apa yang dikatakan blivet, dan saran yang bagus.
santiagobasulto
10
Juga 1 catatan penting, DATETIME dan TIMESTAMP dapat menggunakan CURRENT_TIMESTAMP, SEKARANG () dengan hormat sebagai nilai default, tetapi DATE misalnya tidak bisa, karena menggunakan '0000-00-00' secara default, jadi untuk menyelesaikan masalah itu Anda harus menulis Pemicu Anda sendiri ke tabel itu, untuk memasukkan tanggal saat ini (tanpa waktu) di bidang / col dengan DATE mysql type.
Arthur Kushman
14
@DavidHarkness: Dokumentasi mengatakan "Untuk menentukan properti otomatis, gunakan klausa DEFAULT CURRENT_TIMESTAMP dan ON UPDATE CURRENT_TIMESTAMP" dev.mysql.com/doc/refman/5.0/id/timestamp-initialization.html
Plap
917

Di MySQL 5 dan di atasnya, nilai TIMESTAMP dikonversi dari zona waktu saat ini ke UTC untuk penyimpanan, dan dikonversi kembali dari UTC ke zona waktu saat ini untuk pengambilan. (Ini hanya terjadi untuk tipe data TIMESTAMP, dan bukan untuk tipe lain seperti DATETIME.)

Secara default, zona waktu saat ini untuk setiap koneksi adalah waktu server. Zona waktu dapat diatur berdasarkan per koneksi, seperti yang dijelaskan dalam Dukungan Zona Waktu Server MySQL .

Nir
sumber
11
presentasi OReilly ini sangat baik untuk topik ini (PDF maaf) cdn.oreillystatic.com/en/assets/1/event/36/…
gcb
13
Ini juga tentang sifat acara: - Konferensi video (TIMESTAMP). Semua petugas harus melihat referensi ke waktu instan absolut yang disesuaikan dengan zona waktunya. - Waktu tugas lokal (DATETIME), saya harus melakukan tugas ini pada 2014/03/31 9:00 pagi, tidak masalah jika hari itu saya bekerja di New York atau Paris. Saya akan mulai bekerja pada jam 8:00 waktu setempat tempat saya akan menjadi hari itu.
Yucer
1
Jadi jika saya MENGUBAH zona waktu server, maka nilai TIMESTAMP akan tetap sama atau apakah akan berubah juga ??
Andrew
3
@Andrew karena UTC, itu akan tetap UTC. Konversi mundur akan berubah ke zona waktu server "baru".
nembleton
@ Yucer - Saya tidak merekomendasikan berpikir seperti itu. Penggunaan paling konsisten dalam ekonomi global adalah untuk mengkonversi semua data ke UTC untuk penyimpanan. Dengan konvensi, perlakukan Datetime sebagai bidang UTC. Ini memang membebani semua tugas yang memasukkan data untuk membuat konversi ke UTC, tetapi ini adalah desain yang lebih bersih untuk jangka panjang. Tentu saja, berikan informasi kepada pengguna berdasarkan pengaturan mereka saat ini. Jika pengguna ingin memasukkan "09:00 di Paris", maka biarkan mereka mengatur waktu Paris, lalu masukkan 09:00. Maka siapa pun yang berada di New York dapat dengan mudah menemukan waktu yang mereka butuhkan untuk bangun pada waktu mereka, untuk melakukan teleconference.
ToolmakerSteve
524

Saya selalu menggunakan bidang DATETIME untuk apa pun selain metadata baris (tanggal dibuat atau dimodifikasi).

Seperti disebutkan dalam dokumentasi MySQL:

Jenis DATETIME digunakan ketika Anda membutuhkan nilai yang berisi informasi tanggal dan waktu. MySQL mengambil dan menampilkan nilai DATETIME dalam format 'YYYY-MM-DD HH: MM: SS'. Kisaran yang didukung adalah '1000-01-01 00:00:00' hingga '9999-12-31 23:59:59'.

...

Tipe data TIMESTAMP memiliki rentang '1970-01-01 00:00:01' UTC hingga '2038-01-09 03:14:07' UTC. Ini memiliki sifat yang bervariasi, tergantung pada versi MySQL dan mode SQL yang dijalankan server.

Anda kemungkinan besar akan mencapai batas bawah pada TIMESTAMP yang digunakan secara umum - mis. Menyimpan tanggal lahir.

skronida
sumber
195
Anda juga dapat mencapai batas atas dengan mudah jika Anda berada di perbankan atau real estat ... KPR 30 tahun melampaui 2038 sekarang
Kip
16
Tentu saja, gunakan cap waktu Unix 64-bit. Misalnya, di Jawa, new Date().getTime()sudah memberi Anda nilai 64-bit.
Osa
5
+1 untuk DATETIME: Dalam aliran data kami, dari SQL Server dari Physical Store untuk pembelian dan faktur, ditransfer ke MySQL Server untuk Virtual Store di halaman web, DATETIME lebih baik untuk Modifikasi Tanggal-Waktu karena tipe data ini juga ada di Transact -SQL. Tapi TIMESTAMP berarti hal lain dalam Transact-SQL, itu adalah Biner seperti ROWVERSION, meskipun TIMESTAMP MySQL adalah DateTime serupa. Jadi kami menghindari penggunaan TIMESTAMP untuk kompatibilitas kedua DB.
jacouh
10
Tidak ada ide. Ini masalah yang jauh lebih besar daripada hanya MySQL dan tidak ada perbaikan sederhana: en.wikipedia.org/wiki/Year_2038_problem Saya tidak percaya MySQL hanya dapat menyatakan cap waktu sekarang 64-bit dan menganggap semuanya akan baik-baik saja. Mereka tidak mengontrol perangkat keras.
scronide
5
Tanggal lahir bisa menjadi DATETIME jika Anda tahu waktu kelahiran, seperti yang saya lakukan untuk saya.
Kris Craig
322

Contoh di bawah ini menunjukkan bagaimana TIMESTAMPtipe tanggal mengubah nilai setelah mengubah di time-zone to 'america/new_york'mana DATETIMEtidak berubah.

mysql> show variables like '%time_zone%';
+------------------+---------------------+
| Variable_name    | Value               |
+------------------+---------------------+
| system_time_zone | India Standard Time |
| time_zone        | Asia/Calcutta       |
+------------------+---------------------+

mysql> create table datedemo(
    -> mydatetime datetime,
    -> mytimestamp timestamp
    -> );

mysql> insert into datedemo values ((now()),(now()));

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 14:11:09 |
+---------------------+---------------------+

mysql> set time_zone="america/new_york";

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 04:41:09 |
+---------------------+---------------------+

Saya telah mengonversikan jawaban saya menjadi artikel sehingga lebih banyak orang dapat menemukan ini berguna, MySQL: Datetime Versus Timestamp Tipe Data .

mr_eclair
sumber
55
Sebenarnya DATETIMEwaktu efektif berubah dengan perubahan zona waktu, TIMESTAMPtidak berubah tetapi representasi manusia berubah.
flindeberg
3
Sepertinya perintah ini tidak berfungsi di MySQL 5.6 set time_zone="america/new_york";
Manjunath Reddy
Inilah jawaban untuk masalah time_zone yang disetel. stackoverflow.com/questions/3451847/mysql-timezone-change
Manjunath Reddy
2
Setuju dengan @flindeberg. Stempel waktu mewakili waktu yang tepat, bukan waktu, setelah perubahan zona waktu
Nitin Bansal
193

Perbedaan utama adalah bahwa DATETIME konstan sedangkan TIMESTAMP dipengaruhi oleh time_zonepengaturan.

Jadi itu hanya masalah ketika Anda memiliki - atau mungkin di masa depan - menyinkronkan cluster di zona waktu.

Dengan kata sederhana: Jika saya memiliki basis data di Australia, dan melakukan dump basis data itu untuk menyinkronkan / mengisi basis data di Amerika, maka TIMESTAMP akan memperbarui untuk mencerminkan waktu sebenarnya dari peristiwa itu di zona waktu yang baru, sementara DATETIME akan masih mencerminkan waktu acara di zona waktu au .

Contoh hebat DATETIME yang digunakan di mana TIMESTAMP seharusnya digunakan adalah di Facebook, di mana server mereka tidak pernah benar-benar yakin hal-hal waktu apa yang terjadi di seluruh zona waktu. Suatu kali saya melakukan percakapan di mana waktu mengatakan saya membalas pesan sebelum pesan itu benar-benar dikirim. (Ini, tentu saja, bisa juga disebabkan oleh terjemahan zona waktu yang buruk dalam perangkat lunak olahpesan jika waktu diposting daripada disinkronkan.)

ekerner
sumber
83
Saya pikir ini bukan cara berpikir yang baik. Saya hanya menyimpan dan memproses semua tanggal dalam UTC dan memastikan bahwa front-end menampilkannya sesuai dengan zona waktu yang diberikan. Pendekatan ini sederhana dan dapat diprediksi.
Kos
8
@ Ko: tidakkah menyimpan dan memproses semua tanggal di UTC persis seperti apa yang dilakukan TIMESTAMP secara internal? (Kemudian mengonversinya untuk menampilkan zona waktu lokal Anda?)
carbocation
10
zona waktu lokal saya ? Bagaimana DB Anda mengetahui zona waktu saya? ;-) Biasanya ada beberapa proses antara database dan antarmuka pengguna. Saya melakukan pelokalan hanya setelah seluruh pemrosesan.
Kos
3
@Koz: basis data saya tidak tahu zona waktu basis data Anda:! Tapi itu tahu timestamp. Basis data Anda mengetahui pengaturan zona waktunya sendiri dan menerapkannya saat menafsirkan / mewakili stempel waktu. 01:01 pada 11 Desember 2013 di Beijing Cina tidak pada saat yang sama dengan 01:01 pada 11 Desember 2013 di Sydney Australia. Google: 'zona waktu' dan 'meridian utama'.
ekerner
2
MySQL mengonversi nilai TIMESTAMP dari zona waktu saat ini ke UTC untuk penyimpanan, dan kembali dari UTC ke zona waktu saat ini untuk pengambilan. (Ini tidak terjadi untuk tipe lain seperti DATETIME.) Dev.mysql.com/doc/refman/5.5/id/datetime.html
Mahdyfo
125

Saya membuat keputusan ini berdasarkan pangkalan semantik.

Saya menggunakan stempel waktu ketika saya harus merekam (lebih atau kurang) titik waktu. Misalnya ketika catatan dimasukkan ke dalam basis data atau ketika beberapa tindakan pengguna terjadi.

Saya menggunakan bidang datetime ketika tanggal / waktu dapat diatur dan diubah secara sewenang-wenang. Misalnya saat pengguna dapat menyimpan kemudian mengubah janji temu.

MaxVT
sumber
timestamp- titik waktu tertentu, datetime Waktu Universal Terkoordinasi - relatif terhadap sudut pandang, dengan referensi waktu (misalnya zona waktu waktu lokal), bisa jadi .. Waktu Lokal Terkoordinasi?
Yucer
110

Saya sarankan menggunakan baik suatu DATETIME atau bidang TIMESTAMP. Jika Anda ingin mewakili hari tertentu secara keseluruhan (seperti ulang tahun), maka gunakan tipe DATE, tetapi jika Anda lebih spesifik dari itu, Anda mungkin tertarik untuk merekam momen aktual sebagai lawan dari unit waktu (hari, minggu, bulan, tahun). Alih-alih menggunakan DATETIME atau TIMESTAMP, gunakan BIGINT, dan cukup simpan jumlah milidetik sejak zaman (System.currentTimeMillis () jika Anda menggunakan Java). Ini memiliki beberapa keunggulan:

  1. Anda menghindari vendor lock-in. Hampir setiap database mendukung bilangan bulat dengan cara yang relatif sama. Misalkan Anda ingin pindah ke database lain. Apakah Anda ingin khawatir tentang perbedaan antara nilai DATETIME MySQL dan bagaimana Oracle mendefinisikannya? Bahkan di antara berbagai versi MySQL, TIMESTAMPS memiliki tingkat ketepatan yang berbeda. Baru-baru ini MySQL mendukung milidetik di cap waktu.
  2. Tidak ada masalah zona waktu. Ada beberapa komentar mendalam tentang apa yang terjadi dengan zona waktu dengan berbagai tipe data. Tetapi apakah ini pengetahuan umum, dan akankah rekan kerja Anda meluangkan waktu untuk mempelajarinya? Di sisi lain, cukup sulit untuk mengacaukan mengubah BigINT menjadi java.util.Date. Menggunakan BIGINT menyebabkan banyak masalah dengan zona waktu jatuh di pinggir jalan.
  3. Tidak ada kekhawatiran tentang rentang atau presisi. Anda tidak perlu khawatir tentang apa yang dipotong oleh rentang tanggal mendatang (TIMESTAMP hanya berlaku untuk 2038).
  4. Integrasi alat pihak ketiga. Dengan menggunakan integer, itu sepele untuk alat pihak ke-3 (misalnya EclipseLink) untuk berinteraksi dengan database. Tidak semua alat pihak ketiga akan memiliki pemahaman yang sama tentang "waktu" seperti halnya MySQL. Ingin mencoba dan mencari tahu di Hibernate apakah Anda harus menggunakan objek java.sql.TimeStamp atau java.util.Date jika Anda menggunakan tipe data khusus ini? Menggunakan tipe data dasar Anda gunakan dengan alat pihak ke-3 sepele.

Masalah ini berkaitan erat bagaimana Anda harus menyimpan nilai uang (yaitu $ 1,99) dalam database. Haruskah Anda menggunakan Desimal, atau tipe Uang basis data, atau yang terburuk dari semua Double? Ketiga opsi ini mengerikan, karena banyak alasan yang sama tercantum di atas. Solusinya adalah menyimpan nilai uang dalam sen menggunakan BIGINT, dan kemudian mengonversi sen menjadi dolar saat Anda menampilkan nilai kepada pengguna. Pekerjaan basis data adalah untuk menyimpan data, dan BUKAN untuk mengintrepret data itu. Semua tipe data mewah ini yang Anda lihat di basis data (terutama Oracle) menambah sedikit, dan membuat Anda di ujung jalan menuju vendor lock-in.

user64141
sumber
12
Saya suka solusi ini. TIMESTAMP yang kedaluwarsa pada tahun 2038 adalah masalah besar. Itu tidak terlalu jauh!
Charlie Dalsass
4
@CharlieDalsass Apakah Anda pikir perangkat lunak saat ini akan ada di sana saat itu :-P
Habeeb Perwad
13
Itu membuatnya sulit untuk meminta data berdasarkan tanggal jika disimpan dalam jumlah milidetik
Ali Saeed
4
Ini benar-benar solusi terbaik jika Anda peduli tentang portabilitas dan penanganan pengguna di beberapa zona waktu, atau database di zona waktu yang berbeda dari pengguna. TIMESTAMP bisa menjadi cara untuk pergi jika belum mendesain kekurangan. Sayang sekali bahwa solusi yang rusak mendapat lebih banyak suara karena diposkan lebih awal (tahun!).
Jerman
4
Solusi yang sangat baik! Dan Anda benar benar "terkunci". Ketika Anda terbiasa membiarkan orang lain "melakukan pekerjaan untuk Anda", maka Anda mulai kehilangan bagian-bagian yang menjadikan ANDA programmer.
fmc
98

TIMESTAMP adalah 4 byte Vs 8 byte untuk DATETIME.

http://dev.mysql.com/doc/refman/5.0/id/storage-requirements.html

Tapi seperti kata scronide, itu memang memiliki batas bawah tahun 1970. Ini bagus untuk apa pun yang mungkin terjadi di masa depan;)

Alex
sumber
186
Masa depan berakhir pada 2038-01-19 03:14:07 UTC.
MattBianco
5
Itu bodoh. Saya pikir tipe TIMESTAMP akan "siap di masa depan" karena ini relatif baru. Anda tidak dapat repot mengonversi datetime ke UTC dan kembali setiap kali ketika Anda bekerja dengan zona waktu yang berbeda. Mereka seharusnya membuat TIMESTAMP lebih besar .. setidaknya 1 byte lebih besar. itu akan menambah 68 * 255 = 17340 tahun lagi ... meskipun itu tidak akan 32 bit selaras.
NickSoft
10
Tahukah Anda mengapa TIMESTAMP berakhir pada 2038? Karena itu adalah bilangan bulat, dan bilangan bulat memiliki batas yaitu 2147483647. Saya pikir inilah alasannya. Mungkin jika mereka mengubah tipenya menjadi varchar dan mengubah cara memanipulasi, itu akan "siap di masa depan".
vinsa
6
@Vinsa, saya tidak berpikir itu akan menjadi masa depan yang siap saat itu. Masih ingat bug Y2K? 2038 akan datang.
Pacerier
2
Pada tahun 2038, MySQL (jika masih ada) hanya akan memperbarui bidang TIMESTAMP untuk menggunakan lebih dari 4 byte dan memungkinkan jangkauan yang lebih luas
the_nuts
95
  1. TIMESTAMP adalah empat byte vs delapan byte untuk DATETIME.

  2. Stempel waktu juga lebih ringan pada basis data dan diindeks lebih cepat.

  3. Jenis DATETIME digunakan ketika Anda membutuhkan nilai yang berisi informasi tanggal dan waktu. MySQL mengambil dan menampilkan nilai DATETIME dalam format 'YYYY-MM-DD HH: MM: SS'. Kisaran yang didukung adalah '1000-01-01 00:00:00 ′ hingga' 9999-12-31 23:59:59 ′.

Tipe data TIMESTAMP memiliki rentang '1970-01-01 00:00:01 ′ UTC hingga' 2038-01-09 03:14:07 ′ UTC. Ini memiliki sifat yang bervariasi, tergantung pada versi MySQL dan mode SQL yang dijalankan server.

  1. DATETIME konstan sedangkan TIMESTAMP dipengaruhi oleh pengaturan time_zone.
Vivek S
sumber
6
Anda perlu mengklarifikasi # 4: Stempel waktu yang disimpan konstan dan non-relatif (sepenuhnya agnostik) dengan zona waktu, sedangkan output yang ditampilkan saat pengambilan dipengaruhi oleh zona waktu sesi permintaan. DATETIME selalu relatif terhadap zona waktu yang dicatat, dan harus selalu dipertimbangkan dalam konteks itu, tanggung jawab yang sekarang jatuh ke dalam aplikasi.
Christopher McGowan
1
Jawaban yang bagus Untuk menambah jawaban ini, jika kami mencoba menyimpan nilai di luar '2038-01-09 03:14:07', kami mendapatkan kesalahan atau disimpan sebagai '0000-00-00 00:00:00'. Saya mendapatkan kesalahan ini untuk database saya karena memiliki nilai timeshifted (untuk keperluan enkripsi).
KarthikS
Juga, ada masalah dengan DATETIME dengan nilai DEFAULT pada versi mysql di bawah 5.5. dba.stackexchange.com/questions/132951/…
Velaro
47

Tergantung pada aplikasi, sungguh.

Pertimbangkan untuk menetapkan stempel waktu oleh pengguna ke server di New York, untuk janji temu di Sanghai. Sekarang ketika pengguna terhubung di Sanghai, ia mengakses cap waktu janji temu yang sama dari server cermin di Tokyo. Dia akan melihat penunjukan di waktu Tokyo, diimbangi dari waktu New York yang asli.

Jadi untuk nilai-nilai yang mewakili waktu pengguna seperti janji temu atau jadwal, datetime lebih baik. Ini memungkinkan pengguna untuk mengontrol tanggal dan waktu yang tepat yang diinginkan, terlepas dari pengaturan server. Waktu yang ditetapkan adalah waktu yang ditentukan, tidak terpengaruh oleh zona waktu server, zona waktu pengguna, atau oleh perubahan cara penghitungan daylight saving time (ya itu memang berubah).

Di sisi lain, untuk nilai yang mewakili waktu sistem seperti transaksi pembayaran, modifikasi tabel atau pencatatan, selalu gunakan cap waktu. Sistem tidak akan terpengaruh dengan memindahkan server ke zona waktu lain, atau saat membandingkan antara server di zona waktu yang berbeda.

Stempel waktu juga lebih ringan pada basis data dan diindeks lebih cepat.

ianaré
sumber
Aplikasi Anda tidak harus bergantung pada zona waktu server. Aplikasi harus SELALU memilih zona waktu pada sesi koneksi basis data yang digunakannya sebelum mengeluarkan pertanyaan apa pun. Jika koneksi dibagi antara beberapa pengguna (mis: webapp), gunakan UTC dan lakukan konversi zona waktu di sisi rendering.
dolmen
42

2016 + : apa yang saya sarankan adalah mengatur zona waktu Mysql Anda ke UTC dan menggunakan DATETIME:

Kerangka kerja front-end baru-baru ini (Angular 1/2, reaksi, Vue, ...) dapat dengan mudah dan otomatis mengubah waktu UTC Anda ke waktu lokal.

Selain itu:

(Kecuali jika Anda cenderung mengubah zona waktu server Anda)


Contoh dengan AngularJs

// back-end: format for angular within the sql query
SELECT DATE_FORMAT(my_datetime, "%Y-%m-%dT%TZ")...

// font-end Output the localised time
{{item.my_datetime | date :'medium' }}

Semua format waktu terlokalisasi tersedia di sini: https://docs.angularjs.org/api/ng/filter/date

Sebastien Horin
sumber
8
Data Anda tidak boleh dilampirkan ke pengaturan zona waktu server Anda. Mungkin, ini berfungsi untuk Anda jika Anda memiliki satu kotak MySql di bawah meja Anda
Jin
@ Jin UTC berarti tidak ada zona waktu seperti TIMESTAMP. Jika semua server Anda berada di UTC tidak ada masalah. Mungkin itu tidak berfungsi untuk Anda jika Anda memiliki konfigurasi 2000-an.
Sebastien Horin
TIMESTAMP dapat ditingkatkan ke nilai 64 bit di masa mendatang. Maka tidak ada masalah lagi.
twicejr
Memuat seluruh pustaka pihak ketiga untuk menangkap sesuatu seperti ini juga tidak bisa sehebat itu untuk kinerja, bukan? Mengingat sisi klien dan tidak memengaruhi basis data Anda ... Namun, apa pun yang Anda lakukan front-end AKAN memerlukan pemeriksaan sisi server. Jadi, memikirkan gambaran lengkapnya , apakah itu benar-benar membantu masalah kecepatan? - Tolong, tolok ukur itu agak aneh. Menggunakan string dalam kueri untuk membandingkan bidang cap waktu juga terasa aneh. Itu juga harus merusak kinerja, bukan?
NoobishPro
1
Jangan mengandalkan aplikasi Anda pada zona waktu server. Alih-alih tentukan time_zone untuk digunakan pada setiap koneksi basis data: SET time_zone = '+0:00';untuk UTC.
dolmen
37

Sebuah timestamplapangan adalah kasus khusus dari datetimelapangan. Anda dapat membuat timestampkolom untuk memiliki properti khusus; itu dapat diatur untuk memperbarui dirinya sendiri baik pada pembuatan dan / atau pembaruan.

Dalam istilah basis data "lebih besar", timestampada beberapa pemicu kasus khusus.

Apa yang benar tergantung sepenuhnya pada apa yang ingin Anda lakukan.

Jeff Warnica
sumber
6
Tidak, perbedaannya bukan hanya "kasus khusus". Karena zona waktu sesi yang menetapkan / kueri nilai terlibat secara berbeda.
dolmen
Saya senang Anda memasukkan, "Apa yang benar tergantung sepenuhnya pada apa yang ingin Anda lakukan." Ada terlalu banyak jawaban pada SE yang menyatakan, tanpa cukup pembenaran, "Anda tidak boleh melakukan X" atau "Anda harus selalu melakukan Y".
Agi Hammerthief
37

TIMESTAMP selalu dalam UTC (yaitu, detik berlalu sejak 1970-01-01, dalam UTC), dan server MySQL Anda secara otomatis mengonversinya ke tanggal / waktu untuk zona waktu koneksi. Dalam jangka panjang, TIMESTAMP adalah cara untuk pergi karena Anda tahu data temporal Anda akan selalu berada di UTC. Misalnya, Anda tidak akan mengacaukan tanggal Anda jika Anda bermigrasi ke server yang berbeda atau jika Anda mengubah pengaturan zona waktu di server Anda.

Catatan: zona waktu koneksi default adalah zona waktu server, tetapi ini dapat (harus) diubah per sesi (lihat SET time_zone = ...).

Isak
sumber
29

Perbandingan antara DATETIME, TIMESTAMP dan DATE

masukkan deskripsi gambar di sini

Apa itu [.fraksi]?

  • Nilai DATETIME atau TIMESTAMP dapat menyertakan bagian detik pecahan tambahan hingga presisi mikrodetik (6 digit). Secara khusus, setiap bagian fraksional dalam nilai yang dimasukkan ke kolom DATETIME atau TIMESTAMP disimpan daripada dibuang. Ini tentu saja opsional.

Sumber:

Dehan de Croos
sumber
24

Saya akan selalu menggunakan cap waktu Unix saat bekerja dengan MySQL dan PHP. Alasan utama untuk ini adalah metode tanggal default di PHP menggunakan timestamp sebagai parameter, sehingga tidak akan ada penguraian yang diperlukan.

Untuk mendapatkan cap waktu Unix saat ini di PHP, cukup lakukan time();
dan lakukan di MySQL SELECT UNIX_TIMESTAMP();.

Mark Davidson
sumber
6
-1 Saya benar-benar berpikir jawaban di bawah ini lebih baik - menggunakan datetime memungkinkan Anda untuk mendorong lebih banyak logika untuk memproses tanggal ke dalam MySQL itu sendiri, yang bisa sangat berguna.
Toby Hede
Belum ada tolok ukur yang menunjukkan bahwa pengurutan di MySQL lebih lambat daripada di php?
sdkfasldf
baik itu tergantung, kadang-kadang baik untuk menggunakannya ketika kita ingin tidak menggunakan strtotime. (php5.3 dep)
Adam Ramadhan
Anda dapat mendorong logika ke mysql dengan hanya menggunakan FROM_UNIXTIME jika diperlukan
inarilo
Saya dulu menggunakan semua cap waktu Unix di aplikasi PHP saya dan di MySQL, namun saya merasa jauh lebih nyaman untuk menyimpan tanggal dan waktu di MySQL sebagai tipe tanggal / waktu asli. Ini sangat berguna untuk tujuan pelaporan dan hanya menjelajahi set data. Seiring waktu ketika saya merasa frustrasi harus menyalin / melewati cap waktu Unix saya mulai beralih. Saya cukup yakin ada kinerja dan pro / kontra lainnya, tetapi tergantung pada kenyamanan use case Anda bisa lebih penting daripada cukup optimasi mikro.
DavidScherer
24

Perlu dicatat di MySQL Anda dapat menggunakan sesuatu di sepanjang baris di bawah ini saat membuat kolom tabel Anda:

on update CURRENT_TIMESTAMP

Ini akan memperbarui waktu di setiap instance Anda memodifikasi baris dan kadang-kadang sangat membantu untuk menyimpan informasi edit terakhir. Ini hanya bekerja dengan stempel waktu, bukan datetime.

Leejmurphy
sumber
17

Dari pengalaman saya, jika Anda ingin bidang tanggal di mana penyisipan terjadi hanya sekali dan Anda tidak ingin memiliki pembaruan atau tindakan apa pun di bidang tertentu, ikuti waktu tanggal .

Misalnya, pertimbangkan usertabel dengan bidang TANGGAL REGISTRASI . Di usertabel itu, jika Anda ingin mengetahui waktu login terakhir dari pengguna tertentu, pergi dengan bidang tipe timestamp sehingga bidang diperbarui.

Jika Anda membuat tabel dari phpMyAdmin , pengaturan default akan memperbarui bidang cap waktu ketika terjadi pembaruan baris. Jika stempel waktu yang diajukan tidak diperbarui dengan pembaruan baris, Anda dapat menggunakan kueri berikut untuk membuat bidang stempel waktu diperbarui secara otomatis.

ALTER TABLE your_table
      MODIFY COLUMN ts_activity TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
Kannan Prasad
sumber
15

Jenis data timestamp menyimpan tanggal dan waktu, tetapi dalam format UTC, bukan dalam format zona waktu saat ini seperti yang dilakukan datetime. Dan ketika Anda mengambil data, stempel waktu lagi mengonversinya menjadi waktu zona waktu saat ini.

Jadi misalkan Anda berada di AS dan mendapatkan data dari server yang memiliki zona waktu AS. Maka Anda akan mendapatkan tanggal dan waktu sesuai dengan zona waktu AS. Kolom tipe data timestamp selalu diperbarui secara otomatis ketika barisnya diperbarui. Jadi bisa berguna untuk melacak ketika baris tertentu diperbarui terakhir kali.

Untuk lebih jelasnya Anda dapat membaca posting blog Timestamp Vs Datetime .

Arvind
sumber
Anda dapat (harus) selalu menentukan zona waktu di tingkat sesi dengan SET time_zone = '+0:00';(UTC di sini) untuk memastikan apa yang Anda dapatkan / atur dari TIMESTAMPnilai-nilai dan menghindari tergantung pada server time_zone default yang mungkin berubah.
dolmen
14

Saya selalu menggunakan cap waktu Unix, hanya untuk menjaga kewarasan ketika berhadapan dengan banyak informasi waktu data, terutama ketika melakukan penyesuaian untuk zona waktu, menambah / mengurangi tanggal, dan sejenisnya. Saat membandingkan cap waktu, ini tidak termasuk faktor-faktor zona waktu yang rumit dan memungkinkan Anda untuk menyisihkan sumber daya di pemrosesan sisi server Anda (Baik itu kode aplikasi atau permintaan basis data) di mana Anda menggunakan aritmatika ringan daripada menambah-mengurangi waktu-waktu. fungsi.

Hal lain yang patut dipertimbangkan:

Jika Anda membuat aplikasi, Anda tidak pernah tahu bagaimana data Anda harus digunakan di telepon. Jika Anda akhirnya harus, katakan, membandingkan banyak catatan dalam kumpulan data Anda, dengan, katakanlah, banyak item dari API pihak ketiga, dan berkata, letakkan dalam urutan kronologis, Anda akan senang memiliki Unix cap waktu untuk baris Anda. Bahkan jika Anda memutuskan untuk menggunakan stempel waktu MySQL, simpan stempel waktu Unix sebagai asuransi.

Oliver Holmberg
sumber
14

Dalam kasus saya, saya menetapkan UTC sebagai zona waktu untuk segalanya: sistem, server database, dll. Setiap kali saya bisa. Jika pelanggan saya membutuhkan zona waktu lain, maka saya mengkonfigurasinya di aplikasi.

Saya hampir selalu lebih suka stempel waktu daripada bidang datetime, karena stempel waktu menyertakan zona waktu secara implisit. Jadi, sejak saat aplikasi akan diakses dari pengguna dari zona waktu yang berbeda dan Anda ingin mereka melihat tanggal dan waktu di zona waktu lokal mereka, jenis bidang ini membuatnya cukup mudah untuk dilakukan daripada jika data disimpan di bidang waktu lama .

Sebagai nilai tambah, dalam kasus migrasi basis data ke sistem dengan zona waktu lain, saya akan merasa lebih percaya diri menggunakan cap waktu. Belum lagi masalah yang mungkin terjadi ketika menghitung perbedaan antara dua momen dengan waktu sumer berubah di antara dan membutuhkan ketelitian 1 jam atau kurang.

Jadi, untuk meringkas, saya menghargai kelebihan cap waktu ini:

  • siap digunakan pada aplikasi internasional (zona multi waktu)
  • migrasi mudah antar zona waktu
  • cukup mudah untuk menghitung perbedaan (cukup kurangi kedua cap waktu)
  • tidak khawatir tentang tanggal masuk / keluar periode waktu musim panas

Untuk semua alasan ini, saya memilih bidang UTC & timestamp mana mungkin. Dan saya menghindari sakit kepala;)

Roger Campanera
sumber
data timestamp akan menyenangkan bagi orang yang mendukung aplikasi Anda ketika 20 Januari 2038 tiba. tick tock tick tock
Wilson Hauck
Jenis cap waktu kemudian dapat ditingkatkan sedikit dan gandakan nilai yang mungkin.
Roger Campanera
Uji teori Anda untuk 'meningkat sedikit' dan lihat apakah Anda berhasil menyimpan 1 Februari 2038 dan mengambilnya dengan MySQL. Mari kita lihat definisi tabel Anda ketika selesai. Anda mungkin akan memiliki banyak kenalan masa lalu yang tidak bahagia di bulan Februari 2038.
Wilson Hauck
1
@ WillsonHauck Anda harus memperbarui versi MySQL jauh sebelum 2038. Dan TIMESTAMP yang diperpanjang itu akan ditangani oleh migrasi. Juga, beberapa aplikasi selain menangani hipotek benar-benar perlu peduli 2038 sekarang.
dolmen
@dolmen, banyak alat dan bahan kelas profesional memiliki garansi 20+ tahun. Jadi sesuatu seperti warranties.expires_attidak bisa menjadi timestamp MySQL hari ini.
alexw
13

Waspadalah terhadap perubahan stempel waktu saat Anda melakukan pernyataan UPDATE di atas meja. Jika Anda memiliki tabel dengan kolom 'Nama' (varchar), 'Usia' (int), dan 'Date_Added' (timestamp) dan Anda menjalankan pernyataan DML berikut

UPDATE table
SET age = 30

maka setiap nilai tunggal dalam kolom 'Date_Added' Anda akan diubah ke cap waktu saat ini.

Lloyd Banks
sumber
3
berdasarkan bagaimana Anda mengatur meja Anda, Anda dapat mengontrol perilaku ini. lihat dev.mysql.com/doc/refman/5.5/id/timestamp-initialization.html
Charles
5
@CharlesFaiga Perilaku default adalah untuk cap waktu untuk memperbarui ketika kolom lain diperbarui. Anda harus mematikan ini secara eksplisit jika Anda ingin cap waktu mempertahankan nilai aslinya
Lloyd Banks
Apa itu ?! Anda harus mengatur kolom stempel waktu keON UPDATE CURRENT_TIMESTAMP
Akuntan
Ini adalah fitur yang harus Anda aktifkan secara eksplisit saat membuat tabel.
dolmen
13

Referensi yang diambil dari Artikel ini:

Perbedaan utama:

TIMESTAMP digunakan untuk melacak perubahan pada catatan, dan memperbarui setiap kali ketika catatan diubah. DATETIME digunakan untuk menyimpan nilai spesifik dan statis yang tidak terpengaruh oleh perubahan apa pun dalam catatan.

TIMESTAMP juga dipengaruhi oleh pengaturan TIME ZONE yang berbeda. DATETIME adalah konstan.

TIMESTAMP dikonversi secara internal zona waktu saat ini ke UTC untuk penyimpanan, dan selama pengambilan dikonversi kembali ke zona waktu saat ini. DATETIME tidak dapat melakukan ini.

Kisaran yang didukung TIMESTAMP: '1970-01-01 00:00:01 ′ UTC hingga' 2038-01-19 03:14:07 ′ Kisaran DATETIME UTC yang didukung: '1000-01-01 00:00:00 ′ hingga' 9999 -12-31 23:59:59 ′

Landasan
sumber
11
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
|                                       TIMESTAMP                                       |                                 DATETIME                                 |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| TIMESTAMP requires 4 bytes.                                                           | DATETIME requires 8 bytes.                                               |
| Timestamp is the number of seconds that have elapsed since January 1, 1970 00:00 UTC. | DATETIME is a text displays 'YYYY-MM-DD HH:MM:SS' format.                |
| TIMESTAMP supported range: 1970-01-01 00:00:01 UTC to 2038-01-19 03:14:07 UTC.    | DATETIME supported range: 1000-01-01 00:00:00 to 9999-12-31 23:59:59 |
| TIMESTAMP during retrieval converted back to the current time zone.                   | DATETIME can not do this.                                                |
| TIMESTAMP is used mostly for metadata i.e. row created/modified and audit purpose.    | DATETIME is used mostly for user-data.                                   |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
Premraj
sumber
10

Perbedaan lain antara Timestamp dan Datetime adalah di Timestamp Anda tidak dapat menetapkan nilai default ke NULL.

ecleel
sumber
8
Jelas salah. Berikut ini sebuah contoh: CREATE TABLE t2 ( ts1 TIMESTAMP NULL, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); Kolom pertama dapat menerima nilai NULL.
Ormoz
10

Saya menemukan kegunaan tak tertandingi dalam kemampuan TIMESTAMP untuk memperbarui sendiri secara otomatis berdasarkan waktu saat ini tanpa menggunakan pemicu yang tidak perlu. Itu hanya saya, meskipun TIMESTAMP adalah UTC seperti yang dikatakan.

Ini dapat melacak di berbagai zona waktu, jadi jika Anda perlu menampilkan waktu relatif misalnya, waktu UTC adalah yang Anda inginkan.

Marc DiMillo
sumber
9

Perbedaan utamanya adalah

  • sebuah INDEX di Timestamp - berfungsi
  • sebuah INDEX di Datetime - Tidak berfungsi

lihat posting ini untuk melihat masalah dengan pengindeksan datetime

Charles Faiga
sumber
6
Keduanya memiliki masalah yang sama jika Anda memilih dengan fungsi berdasarkan nilai kolom, dan keduanya dapat diindeks.
Marcus Adams
4
Indeks berfungsi pada stempel waktu dan tidak berfungsi pada datetime? Anda menarik kesimpulan yang salah dari pos-pos itu.
Salman A
9

Saya berhenti menggunakan datetimedalam aplikasi saya setelah menghadapi banyak masalah dan bug yang berkaitan dengan zona waktu. Penggunaan IMHO timestamplebih baik daripada datetimedi sebagian besar kasus .

Ketika Anda bertanya jam berapa sekarang? dan jawabannya datang sebagai sesuatu seperti '2019-02-05 21:18:30', itu tidak selesai, tidak didefinisikan jawaban karena tidak memiliki bagian lain, di zona waktu mana? Washington? Moskow? Beijing?

Menggunakan data tanpa zona waktu berarti bahwa aplikasi Anda hanya berurusan dengan 1 zona waktu, namun stempel waktu memberi Anda manfaat datetimeplus fleksibilitas untuk menunjukkan titik waktu yang sama persis di zona waktu yang berbeda.

Berikut adalah beberapa kasus yang akan membuat Anda menyesal menggunakan datetimedan berharap Anda menyimpan data Anda di cap waktu.

  1. Untuk kenyamanan klien Anda, Anda ingin menunjukkan waktu berdasarkan zona waktu pilihan mereka tanpa membuat mereka melakukan perhitungan dan mengubah waktu menjadi zona waktu yang berarti. yang Anda butuhkan hanyalah mengubah zona waktu dan semua kode aplikasi Anda akan sama. (Sebenarnya Anda harus selalu menentukan zona waktu di awal aplikasi, atau meminta pemrosesan dalam kasus aplikasi PHP)

    SET time_zone = '+2:00';
  2. Anda mengubah negara tempat Anda tinggal, dan melanjutkan pekerjaan Anda mempertahankan data sambil melihatnya di zona waktu yang berbeda (tanpa mengubah data aktual).

  3. Anda menerima data dari klien yang berbeda di seluruh dunia, masing-masing memasukkan waktu di zona waktunya.

Pendeknya

datetime = aplikasi mendukung 1 zona waktu (untuk menyisipkan dan memilih)

timestamp = aplikasi mendukung zona waktu apa pun (untuk menyisipkan dan memilih)


Jawaban ini hanya untuk menyoroti beberapa fleksibilitas dan kemudahan cap waktu ketika datang ke zona waktu, itu tidak mencakup perbedaan lain seperti ukuran kolom atau rentang atau fraksi .

Akuntan م
sumber
bagaimana jika ada bidang yang digunakan date, dan bidang lain digunakan timestampdalam satu tabel. Saya pikir itu akan menyebabkan masalah baru karena data yang difilter oleh wheretidak sesuai dengan perubahan Zona Waktu.
Erlang P
@ErlangP Dalam hal ini aplikasi Anda harus memperbaiki masalah zona waktu pada datekolom sebelum mengirim permintaan.
Akuntan
7

Saya lebih suka menggunakan stempel waktu untuk menyimpan semuanya dalam satu format mentah yang umum dan memformat data dalam kode PHP atau dalam kueri SQL Anda. Ada beberapa contoh yang berguna dalam kode Anda untuk menyimpan semuanya dalam hitungan detik.

Hans
sumber
7

A TIMESTAMPmembutuhkan 4 byte, sedangkan a DATETIMEmembutuhkan 8 byte.

Mwangi Thiga
sumber
6

Saya suka cap waktu Unix, karena Anda dapat mengonversi ke angka dan hanya khawatir tentang jumlahnya. Plus Anda menambah / mengurangi dan mendapatkan jangka waktu, dll. Kemudian, ubah hasilnya menjadi Tanggal dalam format apa pun. Kode ini mengetahui berapa banyak waktu dalam menit yang berlalu antara stempel waktu dari dokumen, dan waktu saat ini.

$date  = $item['pubdate']; (etc ...)
$unix_now = time();
$result = strtotime($date, $unix_now);
$unix_diff_min = (($unix_now  - $result) / 60);
$min = round($unix_diff_min);
pengguna723220
sumber
4
Atau, gunakan datetime MySQL yang dapat digunakan kembali dan asli, dan gunakan fungsi MySQL asli untuk menambah / mengurangi datetimes.
Julien Palard