Apakah Anda merekomendasikan menggunakan bidang datetime atau timestamp , dan mengapa (menggunakan MySQL)?
Saya bekerja dengan PHP di sisi server.
Apakah Anda merekomendasikan menggunakan bidang datetime atau timestamp , dan mengapa (menggunakan MySQL)?
Saya bekerja dengan PHP di sisi server.
Jawaban:
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.
DATETIME
mewakili tanggal (seperti yang ditemukan dalam kalender) dan waktu (seperti yang dapat diamati pada jam dinding), sementara TIMESTAMP
mewakili 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].
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 .
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.
new Date().getTime()
sudah memberi Anda nilai 64-bit.
Contoh di bawah ini menunjukkan bagaimana TIMESTAMP
tipe tanggal mengubah nilai setelah mengubah di time-zone to 'america/new_york'
mana DATETIME
tidak 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 .
DATETIME
waktu efektif berubah dengan perubahan zona waktu, TIMESTAMP
tidak berubah tetapi representasi manusia berubah.
set time_zone="america/new_york"
;
Perbedaan utama adalah bahwa DATETIME konstan sedangkan TIMESTAMP dipengaruhi oleh time_zone
pengaturan.
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.)
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.
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:
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.
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;)
TIMESTAMP adalah empat byte vs delapan byte untuk DATETIME.
Stempel waktu juga lebih ringan pada basis data dan diindeks lebih cepat.
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.
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.
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
SET time_zone = '+0:00';
untuk UTC.
Sebuah timestamp
lapangan adalah kasus khusus dari datetime
lapangan. Anda dapat membuat timestamp
kolom untuk memiliki properti khusus; itu dapat diatur untuk memperbarui dirinya sendiri baik pada pembuatan dan / atau pembaruan.
Dalam istilah basis data "lebih besar", timestamp
ada beberapa pemicu kasus khusus.
Apa yang benar tergantung sepenuhnya pada apa yang ingin Anda lakukan.
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 = ...
).
Perbandingan antara DATETIME, TIMESTAMP dan DATE
Apa itu [.fraksi]?
Sumber:
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();
.
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.
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 user
tabel dengan bidang TANGGAL REGISTRASI . Di user
tabel 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;
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 .
SET time_zone = '+0:00';
(UTC di sini) untuk memastikan apa yang Anda dapatkan / atur dari TIMESTAMP
nilai-nilai dan menghindari tergantung pada server time_zone default yang mungkin berubah.
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.
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:
Untuk semua alasan ini, saya memilih bidang UTC & timestamp mana mungkin. Dan saya menghindari sakit kepala;)
warranties.expires_at
tidak bisa menjadi timestamp MySQL hari ini.
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.
ON UPDATE CURRENT_TIMESTAMP
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 ′
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| 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. |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
Perbedaan lain antara Timestamp dan Datetime adalah di Timestamp Anda tidak dapat menetapkan nilai default ke NULL.
CREATE TABLE t2 ( ts1 TIMESTAMP NULL, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
Kolom pertama dapat menerima nilai NULL.
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.
Perbedaan utamanya adalah
lihat posting ini untuk melihat masalah dengan pengindeksan datetime
Saya berhenti menggunakan datetime
dalam aplikasi saya setelah menghadapi banyak masalah dan bug yang berkaitan dengan zona waktu. Penggunaan IMHO timestamp
lebih baik daripada datetime
di 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 datetime
plus fleksibilitas untuk menunjukkan titik waktu yang sama persis di zona waktu yang berbeda.
Berikut adalah beberapa kasus yang akan membuat Anda menyesal menggunakan datetime
dan berharap Anda menyimpan data Anda di cap waktu.
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';
Anda mengubah negara tempat Anda tinggal, dan melanjutkan pekerjaan Anda mempertahankan data sambil melihatnya di zona waktu yang berbeda (tanpa mengubah data aktual).
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 .
date
, dan bidang lain digunakan timestamp
dalam satu tabel. Saya pikir itu akan menyebabkan masalah baru karena data yang difilter oleh where
tidak sesuai dengan perubahan Zona Waktu.
date
kolom sebelum mengirim permintaan.
A TIMESTAMP
membutuhkan 4 byte, sedangkan a DATETIME
membutuhkan 8 byte.
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);