Rujukan muktamad kepada jenis data datetime. Panduan Rujukan MySQL

jenis data tarikh dan masa: MASA TARIKH, TARIKH, STAMP MASA, MASA dan TAHUN. Setiap daripada mereka mempunyai selang nilai yang boleh diterima, serta nilai "null", yang digunakan apabila pengguna memasukkan nilai yang benar-benar tidak sah. Ambil perhatian bahawa MySQL membenarkan anda menyimpan beberapa nilai tarikh yang tidak boleh dipercayai sepenuhnya, contohnya 1999-11-31. Sebabnya ialah menguruskan pengesahan tarikh adalah tanggungjawab aplikasi tertentu, bukan pelayan SQL. Untuk mempercepatkan pengesahan tarikh, MySQL hanya menyemak sama ada bulan berada dalam julat 0-12 dan hari berada dalam julat 0-31. Selang ini bermula pada 0, ini dilakukan untuk menyediakan MySQL dengan keupayaan untuk menyimpan tarikh di mana hari atau bulan berada dalam lajur DATE atau DATETIME sama dengan sifar. Ciri ini amat berguna untuk aplikasi yang memerlukan penyimpanan tarikh lahir - di sini hari atau bulan kelahiran tidak selalu diketahui. Dalam kes sedemikian, tarikh hanya disimpan sebagai 1999-00-00 atau 1999-01-00 (tetapi anda tidak sepatutnya mengharapkan fungsi DATE_SUB() atau DATE_ADD untuk mengembalikan nilai yang betul untuk tarikh tersebut).

MySQL mendapatkan semula nilai untuk jenis ini tarikh atau masa sahaja format standard, tetapi pada masa yang sama cuba mentafsir pelbagai format yang mungkin datang daripada pengguna (contohnya, apabila menentukan nilai yang harus diberikan jenis tarikh atau masa atau dibandingkan dengan nilai yang mempunyai salah satu daripada jenis ini). Walau bagaimanapun, hanya format yang diterangkan dalam bahagian berikut disokong. Pengguna dijangka memasukkan nilai yang sah untuk kuantiti, kerana menggunakan kuantiti dalam format lain mungkin menghasilkan keputusan yang tidak dapat diramalkan.

  • Walaupun MySQL cuba mentafsir nilai dalam pelbagai format, dalam semua kes adalah dijangka bahagian nilai tarikh yang mengandungi tahun akan berada di paling kiri. Tarikh mesti dinyatakan dalam pesanan tahun-bulan-hari (contohnya, "98-09-04"), dan bukan dalam urutan bulan-hari-tahun atau hari-bulan-tahun, i.e. bukan cara kami biasanya menulisnya (contohnya, "09-04-98", "04-09-98").
  • MySQL secara automatik akan menukar nilai jenis tarikh atau masa kepada nombor jika nilai yang diberi digunakan dalam konteks berangka, dan sebaliknya.
  • Nilai yang mempunyai jenis tarikh atau masa yang di luar had tetapkan selang atau tidak sah untuk jenis data ini (lihat permulaan bahagian), ditukar kepada nilai "null" untuk jenis ini. (Pengecualian adalah untuk nilai jenis TIME yang melangkaui sempadan selang yang ditetapkan, yang dipotong ke titik sempadan yang sepadan selang yang ditentukan MASA). Dalam jadual 4.3. Berikut ialah format untuk nilai "null" untuk setiap jenis lajur:
  • Nilai sifar adalah istimewa. Untuk menyimpannya atau merujuknya, anda boleh menggunakan nilai yang ditunjukkan dalam jadual secara eksplisit, atau anda boleh menggunakan "0", yang lebih mudah untuk ditulis.
Jenis data DATETIME, DATE dan TIMESTAMP

Jenis data DATETIME digunakan untuk nilai yang mengandungi kedua-dua maklumat tarikh dan masa. MySQL mendapatkan semula dan memaparkan nilai DATETIME dalam format "YYYY-MM-DD HH:MM:SS". Julat nilai yang disokong ialah daripada "1000-01-01 00:00:00" hingga "9999-12-31 23:59:59". ("disokong" bermaksud bahawa walaupun nilai dengan nilai masa awal mungkin masih berfungsi, tiada jaminan bahawa nilai tersebut akan disimpan dan dipaparkan dengan betul).

Jenis DATE digunakan untuk nilai dengan hanya maklumat tarikh, tanpa bahagian masa. MySQL mendapatkan semula dan memaparkan nilai DATE dalam format "YYYY-MM-DD". Julat nilai yang disokong ialah daripada "1000-01-01" hingga "9999-12-31".

Jenis lajur TIMESTAMP menyediakan jenis perwakilan data yang boleh digunakan untuk rakaman automatik tarikh dan masa semasa semasa menjalankan operasi INSERT atau UPDATE. Jika anda mempunyai berbilang lajur TIMESTAMP, hanya yang pertama dikemas kini secara automatik.

Untuk baki (kecuali untuk lajur pertama) jenis TIMESTAMP, anda juga boleh menetapkan nilai kepada tarikh dan masa semasa. Untuk melakukan ini, anda hanya perlu menetapkan lajur kepada NULL atau NOW() .

Mana-mana lajur TIMESTAMP (walaupun lajur pertama jenis itu) boleh ditetapkan kepada nilai selain daripada tarikh dan masa semasa. Ini dilakukan dengan menetapkannya secara eksplisit kepada nilai yang dikehendaki. Harta ini boleh digunakan, sebagai contoh, jika anda ingin menetapkan lajur TIMESTAMP kepada tarikh dan masa semasa semasa membuat baris, dan apabila anda mengemas kini baris itu kemudiannya, nilai lajur tidak seharusnya berubah.

Nilai TIMESTAMP boleh berkisar dari awal tahun 1970 hingga beberapa nilai pada tahun 2037 dengan resolusi satu saat. Kuantiti ini dikeluarkan sebagai nilai berangka.

Format data di mana MySQL mendapatkan semula dan memaparkan nilai TIMESTAMP bergantung pada bilangan aksara yang ditunjukkan. Ini digambarkan dalam Jadual 4.4. Format penuh TIMESTAMP ialah 14 tempat perpuluhan, tetapi anda boleh membuat lajur TIMESTAMP dengan rentetan keluaran yang lebih pendek:

Jadual 4.4. Format data TIMESTAMP bergantung pada bilangan digit yang diekstrak
Jenis lajur Format Output
TIMESTAMP(14) YYYYMMDDHHMMSS
TIMESTAMP(12) YYMMDDHHMMSS
TIMESTAMP(10) YYMMDDHHMM
TIMESTAMP(8) YYYYMMDD
TIMESTAMP(6) YYMMDD
TIMESTAMP(4) YYMM
TIMESTAMP(2) YY

Nilai DATETIME , DATE dan TIMESTAMP boleh ditetapkan kepada mana-mana set standard format:

  • Sebagai rentetan dalam format "YYYY-MM-DD HH:MM:SS" atau dalam format "YY-MM-DD HH:MM:SS". Sintaks "Ringan" dibenarkan - anda boleh menggunakan sebarang tanda baca sebagai pemisah antara bahagian bahagian tarikh atau masa. Sebagai contoh, nilai "98-12-31 11:30:45", "98.12.31 11+30+45", "98/12/31 11*30*45" dan "98@12@31 11^30^ 45" adalah bersamaan.
  • Sebagai rentetan dalam format "YYYY-MM-DD" atau dalam format "YY-MM-DD". Sintaks "ringan" juga boleh diterima di sini. Sebagai contoh, nilai "98-12-31", "98.12.31", "98/12/31" dan "98@12@31" adalah setara.
  • Sebagai rentetan tanpa pembatas dalam format "YYYYMMDDHHMMSS" atau dalam format "YYMMDDHHMMSS", dengan syarat rentetan itu difahami sebagai tarikh. Sebagai contoh, nilai "19970523091528" dan "970523091528" boleh ditafsirkan sebagai "1997-05-23 09:15:28", tetapi nilai "971122129015" adalah tidak sah (nilai bahagian minit adalah tidak masuk akal) dan adalah tidak masuk akal kepada "0000-00-00 00:00:00."
  • Sebagai rentetan tanpa pembatas dalam format "YYYYMMDD" atau dalam format "YYMMDD", dengan syarat rentetan itu ditafsirkan sebagai tarikh. Sebagai contoh, nilai "19970523" dan "970523" boleh ditafsirkan sebagai "1997-05-23", tetapi nilai "971332" adalah tidak sah (nilai bahagian bulan dan hari tidak bermakna) dan ditukar kepada " 0000-00-00".
  • Sebagai nombor dalam format YYYYMMDDHHMMSS atau dalam format YYMMDDHHMMSS, dengan syarat nombor itu ditafsirkan sebagai tarikh. Sebagai contoh, nilai 19830905132800 dan 830905132800 ditafsirkan sebagai "1983-09-05 13:28:00".
  • Sebagai nombor dalam format YYYYMMDD atau dalam format YYMMDD, dengan syarat nombor itu ditafsirkan sebagai tarikh. Sebagai contoh, nilai 19830905 dan 830905 ditafsirkan sebagai "1983-09-05".
  • Hasil daripada melaksanakan fungsi yang mengembalikan nilai yang boleh diterima dalam konteks jenis data DATETIME , DATE atau TIMESTAMP (contohnya, fungsi NOW() atau CURRENT_DATE()).
jenis data TIME

MySQL mendapatkan semula dan memaparkan nilai TIME dalam format "HH:MM:SS" (atau dalam format "HHH:MM:SS" untuk nilai jam yang lebih besar). Nilai TIME boleh berbeza daripada "-838:59:59" hingga "838:59:59". Sebab bahagian "jam" sesuatu nilai boleh menjadi begitu besar ialah jenis MASA boleh digunakan bukan sahaja untuk mewakili masa dalam sehari (yang mesti kurang daripada 24 jam), tetapi juga untuk mewakili jumlah masa berlalu atau selang masa antara dua peristiwa (yang mungkin lebih lama daripada 24 jam atau bahkan negatif).

Nilai TIME boleh ditentukan dalam pelbagai format:

Sebagai rentetan dalam format "D HH:MM:SS.bahagian pecahan" (perhatikan bahawa MySQL belum lagi menyokong penyimpanan bahagian pecahan nilai dalam lajur jenis yang dipersoalkan). Anda juga boleh menggunakan salah satu daripada paparan "ringan" berikut: HH:MM:SS.bahagian pecahan, HH:MM:SS , HH:MM , D HH:MM:SS , D HH:MM , D HH atau SS . Di sini D ialah hari dari julat nilai 0-33.

  • Sebagai rentetan tanpa pembatas dalam format "HHMMSS", dengan syarat rentetan itu ditafsirkan sebagai tarikh. Sebagai contoh, nilai "101112" difahami sebagai "10:11:12", tetapi nilai "109712" akan menjadi tidak sah (nilai bahagian minit adalah tidak masuk akal) dan akan ditukar kepada "00:00:00".
  • Sebagai nombor dalam format HHMMSS, dengan syarat rentetan itu ditafsirkan sebagai tarikh. Sebagai contoh, nilai 101112 difahami sebagai "10:11:12". MySQL juga memahami perkara berikut format alternatif: SS
  • Sebagai nombor empat digit dalam julat dari 1901 hingga 2155.
  • Sebagai rentetan dua aksara dalam julat nilai dari "00" hingga "99". Nilai dalam selang dari "00" hingga "69" dan dari "70" hingga "99" kemudiannya ditukar kepada nilai YEAR dalam selang dari 2000 hingga 2069 dan dari 1970 hingga 1999, masing-masing.
  • Sebagai nombor dua digit dalam julat dari 1 hingga 99. Nilai dalam julat dari 1 hingga 69 dan dari 70 hingga 99 kemudiannya ditukar kepada nilai YEAR dalam julat dari 2001 hingga 2069 dan dari 1970 hingga 1999, masing-masing. Sila ambil perhatian bahawa jarak untuk nombor dua digit dan rentetan dua digit adalah sedikit berbeza kerana anda tidak boleh menentukan "sifar" secara langsung sebagai nombor dan mentafsirkannya sebagai 2000. Anda mesti menentukannya sebagai rentetan "0" atau "00" atau ia akan ditafsirkan seperti 0000.
  • Hasil daripada melaksanakan fungsi yang mengembalikan nilai yang boleh diterima dalam konteks jenis data YEAR (seperti NOW() ).

Nilai YEAR tidak sah ditukar kepada 0000.

Jenis DATETIME, DATE dan TIMESTAMP

Jenis DATETIME, DATE dan TIMESTAMP adalah berkaitan antara satu sama lain. Bahagian ini menerangkan ciri-ciri mereka, bagaimana mereka serupa dan bagaimana mereka berbeza.
Jenis DATETIME digunakan apabila anda perlu mempunyai nilai yang merangkumi tarikh dan masa. MySQL mendapatkan semula dan memaparkan nilai DATETIME dalam format TGGT-MM-DD HH:MM:SS". Julat nilai yang disokong untuk ini adalah daripada "1000-01-01 00:00:00" hingga "9999- 12-31 23:59 :59" (Disokong bermaksud nilai awal mungkin berfungsi, tetapi tidak dijamin.)
Jenis DATE digunakan apabila anda perlu mempunyai nilai yang merangkumi hanya tarikh, tanpa masa. MySQL mendapatkan semula dan memaparkan nilai DATETIME dalam format "YYYY-MM-DD". Julat yang disokong ialah dari CH000-01-0G hingga "9999-12-31".
Jenis lajur TIMESTAMP mempunyai beberapa sifat yang bergantung pada versi MySQL dan mod SQL di mana pelayan sedang berjalan. Sifat-sifat ini diterangkan kemudian dalam bahagian ini.
Anda boleh menentukan nilai jenis DATETIME, DATE dan TIMESTAMP menggunakan mana-mana set format yang diterima umum:

  1. Sebagai rentetan dalam format "YYYY-MM-DD HH:MM:SS" atau "YY-MM-DD HH:MM:SS. Sintaks santai dibenarkan: sebarang aksara tanda baca boleh digunakan sebagai pembatas antara tarikh dan masa. Contohnya, "98-12-31 11:30:45", "98.12.31 11+30+45", "98/12/31 11*30*45" dan "98012031 11Л30Л45" adalah setara.
  2. Sebagai rentetan dalam format "YYYY-MM-DD" atau "YY-MM-DD". Sintaks santai juga dibenarkan. Sebagai contoh, setara nilai berikut: "98-12-31","98.12.31","98/12/31" dan "98012031".
  3. Sebagai rentetan tanpa pembatas dalam format "YYYYMMDDHHMMSS" atau "YYMMDDDDHHMMSS", dengan mengandaikan bahawa rentetan itu masuk akal sebagai tarikh. Sebagai contoh, "19970523091528" dan "970523091528" ditafsirkan sebagai "1997-0 5-23 09:15:28", tetapi "971122129015" tidak betul (kerana ia mempunyai nilai minit yang tidak bermakna) dan menjadi "0-00" 00:00": 00".
  4. Sebagai rentetan tanpa had dalam format "YYYYMMDD" atau TGMMDD", dengan mengandaikan bahawa rentetan itu masuk akal sebagai tarikh. Contohnya, "19970523" dan "980523" ditafsirkan sebagai "1997-05-23", tetapi "971332" ialah tidak betul ( nilai yang salah bulan dan hari) dan menjadi "0000-00-00".
  5. Sebagai nombor dalam format YYYYMMDDDDHHMMSS atau YYMMDDDDHHMMSS, andaikan nombor itu masuk akal sebagai tarikh. Contohnya, 19830905132800 dan 830905132800 ditafsirkan sebagai "1983-09-05 13:28:00".
  6. Sebagai nombor dalam format YYYYMMDD atau YYMMDD, andaikan nombor itu masuk akal sebagai tarikh. Sebagai contoh, 19830905 dan 830905 ditafsirkan sebagai "1983-09-05".
  7. Hasil daripada fungsi yang mengembalikan nilai yang boleh diterima dalam konteks DATETIME, DATE atau TIMESTAMP, seperti NOW() atau CURRENT_DATE.

Nilai DATETIME, DATE atau TIMESTAMP yang tidak sah ditukar kepada nilai nol jenis yang sesuai ("0000-00-00 00:00:00", "0000-00-00" atau 000000000000000).
Untuk nilai yang ditentukan sebagai rentetan yang termasuk pemisah tarikh, tidak perlu menentukan dua digit untuk bulan atau hari yang kurang daripada 10. "1976-6-9" adalah sama dengan "1976-06-09" . Begitu juga, untuk nilai yang ditentukan sebagai rentetan yang merangkumi pemisah masa, anda tidak perlu menentukan dua digit untuk jam, minit dan saat yang kurang daripada 10. "1979-10-30 1:2:3" ialah sama seperti itu "1979-10-30 01:02:03".


Nilai yang ditentukan sebagai nombor mestilah 6, 8, 12, atau 14 digit panjang. Jika nombor adalah 8 atau 14 digit panjang, ia diandaikan untuk menentukan nilai dalam format YYYYMMDD atau YYYYMMDDDDHHMMSS dan tahun itu dinyatakan dalam empat digit. Jika nombor itu mempunyai panjang 6 atau 12, ia diandaikan untuk menentukan nilai dalam format YYMMDD atau YYMMDDHHMMSS dan tahun dinyatakan dalam dua digit. Nombor selain daripada 6, 8, 12, dan 14 panjangnya dilapisi dengan sifar pendahuluan kepada bilangan digit terdekat dalam siri yang ditentukan.

Nilai yang ditentukan sebagai rentetan tanpa had ditafsir menggunakan panjangnya seperti yang diterangkan di atas. Jika panjang rentetan 8 atau 14 aksara, diandaikan bahawa tahun itu dalam format 4 digit. Jika tidak, diandaikan bahawa tahun diberikan oleh dua digit pertama. Rentetan ditafsirkan dari kiri ke kanan untuk mengekstrak nilai tahun, bulan, hari, jam, minit dan saat. Ini bermakna anda tidak boleh menggunakan baris yang panjangnya kurang daripada 6 aksara. Sebagai contoh, jika anda menentukan "9903" yang bermaksud Mac 1999, anda akan mendapati bahawa MySQL akan memasukkan tarikh batal ke dalam jadual. Ini berlaku kerana nilai tahun dan bulan ialah 99 dan 03, tetapi bahagian hari hilang sepenuhnya, bermakna nilai ini tidak menetapkan tarikh yang betul. Walau bagaimanapun, pada MySQL 3.23, anda boleh menentukan dengan jelas nilai nol bulan atau hari. Sebagai contoh, anda boleh menentukan "990300" untuk memasukkan nilai "1999-03-00" ke dalam jadual.
Dalam had tertentu, anda boleh menetapkan nilai satu jenis kepada objek jenis lain. Walau bagaimanapun, beberapa herotan dengan kehilangan maklumat adalah mungkin:

  1. Jika anda menetapkan nilai jenis DATE kepada objek jenis DATETIME atau TIMESTAMP, bahagian masa bagi nilai itu diandaikan sebagai "00:00:00" kerana nilai DATE tidak mengandungi maklumat masa.
  2. Jika anda menetapkan nilai jenis DATETIME atau tiMesTAMP kepada objek jenis DATE, bahagian masa nilai itu hilang kerana DATE tidak boleh memasukkannya.
  3. Ingat, walaupun nilai DATETIME, DATE dan TIMESTAMP boleh ditentukan menggunakan set format yang sama, julat sahnya berbeza. Sebagai contoh, nilai TIMESTAMP tidak boleh lebih awal daripada 1970 atau lebih lewat daripada 2037. Ini bermakna tarikh seperti "1968-01-10", yang baik sebagai nilai DATETIME atau DATE, adalah tidak betul sebagai TIMESTAMP dan akan ditukar kepada 0 apabila ditetapkan kepada objek sedemikian.

Anda juga harus mengetahui beberapa perangkap apabila menentukan nilai tarikh:

  1. Format santai nilai yang diberikan sebagai rentetan boleh mengelirukan. Sebagai contoh, nilai seperti "10:11:12" mungkin kelihatan seperti masa kerana ia menggunakan pembatas ":", tetapi jika digunakan dalam konteks tarikh ia akan ditafsirkan sebagai "2010-11-12". Pada masa yang sama nilai "10:45:15"
    akan ditukar kepada "0000-00-00" kerana "45" bukan bulan yang sah.
  2. Pelayan MySQL hanya melaksanakan pengesahan tarikh asas: julat tahun, bulan dan hari ialah 1000 hingga 9999, 00 hingga 12 dan 00 hingga 31, masing-masing. Mana-mana tarikh yang mengandungi bahagian di luar julat ini tertakluk kepada penukaran kepada " 0000-00 -00". Harap maklum bahawa ini membolehkan anda menyimpan tarikh yang tidak sah seperti "2002-04-31". Untuk memastikan tarikh adalah betul, semak dalam permohonan.
  • Tarikh yang mengandungi tahun dua digit adalah samar-samar kerana abad itu tidak diketahui. MySQL mentafsir tahun dua digit seperti berikut: * Setahun dalam julat 00-69 ditukar kepada 2000-2069.
  • Setahun dalam julat 70-99 ditukar kepada 1970-1999.
Sifat TIMESTAMP dalam versi MySQL lebih awal daripada 4.1
TIMESTAMP ialah jenis lajur yang boleh digunakan untuk mengecop tarikh dan masa semasa secara automatik apabila melakukan operasi KEMASKINI atau INSERT. Jika terdapat beberapa lajur TIMESTAMP dalam jadual, hanya yang pertama dikemas kini secara automatik.
Lajur TIMESTAMP pertama dalam jadual dikemas kini secara automatik apabila salah satu daripada keadaan berikut berlaku:
  1. Apabila memberikannya secara eksplisit nilai NULL.
  2. Lajur tidak dinyatakan secara eksplisit dalam pernyataan INSERT atau LOAD DATA INFILE.
  3. Lajur tidak dinyatakan secara eksplisit dalam kenyataan KEMASKINI, tetapi nilai beberapa lajur lain diubah. Kenyataan KEMASKINI yang menetapkan lajur kepada nilai yang sama seperti sebelum ini tidak mengemas kini lajur TIMESTAMP. Jika anda menetapkan nilai lama, MySQL mengabaikannya atas sebab kecekapan.

Lajur TIMESTAMP juga boleh dikemas kini dengan tarikh dan masa semasa jika ia ditetapkan secara eksplisit kepada nilai yang dikehendaki. Ini benar walaupun untuk lajur TIMESTAMP yang pertama. Anda boleh menggunakan sifat ini sebagai contoh jika anda ingin menetapkan nilai lajur kepada tarikh semasa dan masa semasa membuat baris, tetapi jangan ubahnya pada kemas kini baris berikutnya:

  1. Biarkan MySQL menetapkan nilai lajur semasa membuat baris. Ini memulakannya dengan nilai tarikh dan masa semasa.
  2. Apabila melakukan kemas kini berikutnya pada lajur baris lain, tetapkan lajur TIMESTAMP kepada nilai semasanya:

KEMASKINI nama_jadual
SET kolum_ imes tamp- column_Ytestamp, other_column1 = new_value1, other_column2= baru_objection2, ...
Satu lagi cara untuk mengekalkan lajur yang merekodkan masa baris dicipta ialah menggunakan lajur DATETIME yang dimulakan kepada NOW() apabila baris dibuat dan tidak diubah suai selepas itu.
Nilai TIMESTAMP boleh berkisar dari awal tahun 1970 hingga sebahagian tahun 2037 dengan resolusi satu saat. Nilai dipaparkan sebagai nombor.
Format di mana MySQL mendapatkan semula dan memaparkan nilai TIMESTAMP bergantung pada lebar paparan, seperti yang digambarkan dalam Jadual 1. 4.3. Format TIMESTAMP penuh ialah 14 bit panjang, tetapi lajur TIMESTAMP boleh ditakrifkan dalam format paparan yang lebih pendek.

Jadual Kebergantungan format paparan pada lebar

Semua lajur TIMESTAMP mempunyai saiz storan yang sama, tanpa mengira format paparan. Format yang paling biasa digunakan ialah 6, 8, 12 dan 14 aksara. Awak boleh tanya saiz tersuai paparan semasa membuat jadual, tetapi nilai 0 dan lebih besar daripada 14 dibuang ke 14. Nilai ganjil dari 1 hingga 13 dibuang ke nombor genap terdekat.
Lajur TIMESTAMP menyimpan nilai yang sah menggunakan ketepatan penuh yang dinyatakan, tanpa mengira lebar paparan. Walau bagaimanapun, terdapat beberapa batasan yang berkaitan dengan ini:

  1. Anda hendaklah sentiasa menyatakan tahun, bulan dan hari, walaupun lajur diisytiharkan sebagai TIMESTAMP(4) atau TIMESTAMP(2). Jika tidak, nilai itu dianggap tidak betul dan disimpan pada 0.
  2. Jika anda menggunakan ALTER jadual untuk mengembangkan lajur TIMESTAMP, maklumat yang sebelumnya disembunyikan akan diserlahkan.
  3. Begitu juga, apabila anda mengecilkan lajur TIMESTAMP, tiada maklumat yang hilang, kecuali dalam erti kata bahawa kurang maklumat akan dikeluarkan berbanding sebelumnya.
  4. Walaupun lajur TIMESTAMP disimpan dengan ketepatan penuh, satu-satunya fungsi yang beroperasi pada jumlah penuh maklumat yang disimpan di dalamnya ialah UNIX_TIMESTAMP(). Semua fungsi lain beroperasi pada nilai yang diekstrak yang diformat. Ini bermakna anda tidak boleh menggunakan fungsi seperti HOUR() atau SECOND() melainkan bahagian yang sepadan disertakan dalam nilai terformat lajur. Contohnya, bahagian HH lajur TIMESTAMP tidak akan dipaparkan melainkan lebar paparannya sekurang-kurangnya 10, jadi penggunaan HOURO pada nilai TIMESTAMP yang lebih pendek akan menghasilkan hasil yang tidak bermakna.
Sifat TIMESTAMP dalam MySQL versi 4.1 dan lebih tinggi
Bermula dengan MySQL 4.1, sifat TIMESTAMP adalah berbeza daripada yang dalam keluaran sebelumnya: lajur TIMESTAMP dipaparkan dalam format yang sama seperti lajur DATETIME.
  • Lebar paparan tidak lagi disokong seperti yang diterangkan sebelum ini. Dengan kata lain, anda tidak lagi boleh menggunakan TIMESTAMP(4) atau TIMESTAMP(2). Selain itu, jika pelayan MySQL dilancarkan dalam mod MAXDB, jenis TIMESTAMP adalah sama dengan datetime. Iaitu, jika pelayan berjalan dalam mod MAXDB pada masa jadual dibuat, mana-mana lajur TIMESTAMP dibuat sebagai DATETIME. Akibatnya, lajur ini menggunakan format paparan DATETIME, mempunyai julat nilai sah yang sama dan tidak mempunyai kemas kini automatik tidak berlaku.
Dalam mod MAXDB, pelayan MySQL boleh dilancarkan bermula dari versi 4.1.1. Untuk mendayakan mod ini, nyatakan pilihan -sql-mode=MAXDB apabila memulakan pelayan, atau tetapkan nilai pembolehubah global sqljnode pada masa jalan:
mysql SET GLOBAL sql_mode=MAXDB;
Pelanggan boleh memaksa pelayan berjalan dalam mod MAXDB untuk sesi sendiri menggunakan arahan:
mysql SET SESI sql_mode=MAXDB;

Pada permulaan penerangan ringkas tentang setiap jenis:

  • TIMESTAMP - jenis data untuk menyimpan tarikh dan masa. Data disimpan sebagai bilangan saat yang telah berlalu sejak permulaan "era Unix". Julat nilai: 1970-01-01 00:00:00 - 2038-12-31 00:00:00. Menduduki 4 bait.
  • TAHUN - jenis data untuk menyimpan tahun. Julat nilai: 1901 - 2155. Menduduki 1 bait.
  • DATE ialah jenis data untuk menyimpan tarikh. Julat nilai: 1000-01-01 - 9999-12-31. Menduduki 3 bait.
  • TIME ialah jenis data untuk menyimpan masa. Julat nilai: −828:59:59 - 828:59:59. Menduduki 3 bait.
  • DATETIME ialah jenis data untuk menyimpan tarikh dan masa. Julat nilai: 1000-01-01 00:00:00 - 9999-12-31 00:00:00. Menduduki 8 bait.

Nota kepada tuan rumah. Perkara yang menarik ialah kebanyakan pengaturcara percaya bahawa konsep "cap masa" ialah masa Unix. Malah, cap masa ialah tanda yang merupakan jujukan aksara yang menunjukkan tarikh dan/atau masa apabila peristiwa tertentu berlaku. Dan "Masa Unix" (masa Unix) atau masa POSIX ialah bilangan saat yang telah berlalu sejak tengah malam 1 Januari 1970 UTC. Konsep cap masa adalah lebih luas daripada masa Unix.

Selepas menganalisis penerangan jenis yang dibentangkan di atas, anda boleh membuat hampir semua kesimpulan tentang kelebihan dan kekurangan jenis tertentu. Segala-galanya agak mudah dan jelas.

Tetapi sebelum bercakap tentang penggunaan jenis ini, saya ingin ambil perhatian bahawa dalam amalan, jenis lain sering digunakan untuk menyimpan tarikh dan masa: nilai integer (untuk menyimpan tarikh - INT (4 bait), tarikh dan masa - BIGINT (8). bait)). Perbezaan penggunaan jenis integer dari DATE dan DATETIME hanya kerana data tidak diformat semasa output, dan dalam pengiraan dengan tarikh dan masa, integer mesti ditukar kepada jenis kalendar yang sesuai. Di samping itu, tiada semakan untuk kesahihan nilai yang dibentangkan sebelum disimpan. Keupayaan pengisihan dikekalkan. Oleh itu, masuk akal untuk menggunakan INT dan BIGINT dalam kes yang sama seperti DATE dan DATETIME, untuk memaksimumkan kemudahalihan dan kebebasan daripada DBMS. Saya tidak nampak kelebihan lain; jika ada, saya cadangkan anda menunjukkannya dalam komen.

Menggunakan jenis data kalendar dalam MySQL

Mari kita mulakan dengan yang paling mudah - jenis TAHUN. Satu-satunya kelebihannya ialah saiznya yang kecil - hanya 1 bait. Tetapi kerana ini, terdapat sekatan ketat pada julat nilai yang sah (jenis hanya boleh menyimpan 255 makna yang berbeza). Saya mempunyai masa yang sukar untuk membayangkan situasi praktikal di mana seseorang mungkin mahu menyimpan tahun dengan ketat dalam julat dari 1901 hingga 2155. Selain itu, jenis SMALLINT (2 bait) memberikan julat yang mencukupi dalam kebanyakan situasi untuk menyimpan setahun. Dan menyimpan 1 bait setiap baris dalam jadual pangkalan data tidak masuk akal pada zaman kita.

Jenis TARIKH Dan MASA TARIKH boleh digabungkan menjadi satu kumpulan. Mereka menyimpan tarikh atau tarikh dan masa dengan agak julat yang luas nilai yang boleh diterima, bebas daripada zon waktu yang ditetapkan pada pelayan. Penggunaannya pasti masuk akal. Tetapi jika anda ingin menyimpan tarikh untuk peristiwa bersejarah yang melangkaui Era Biasa, anda perlu memilih jenis data lain. Jenis ini sesuai untuk menyimpan tarikh untuk acara tertentu yang mungkin berada di luar julat jenis TIMESTAMP (hari lahir, tarikh keluaran produk, pilihan raya presiden, pelancaran roket angkasa lepas, dsb.). Satu perkara yang perlu diingat apabila menggunakan jenis ini ialah nuansa penting, tetapi lebih lanjut mengenai perkara di bawah.

taip MASA boleh digunakan untuk menyimpan tempoh masa apabila ketepatan kurang daripada 1 saat tidak diperlukan, dan tempoh masa kurang daripada 829 jam. Tiada apa lagi yang perlu ditambah di sini.

Jenis yang paling menarik kekal - STAMP MASA. Ia harus dipertimbangkan berbanding dengan DATE dan DATETIME: TIMESTAMP juga direka untuk menyimpan tarikh dan/atau masa berlakunya peristiwa tertentu. Perbezaan penting di antara mereka adalah dalam julat nilai: jelas sekali, TIMESTAMP tidak sesuai untuk menyimpan peristiwa bersejarah (walaupun seperti hari lahir), tetapi sangat baik untuk menyimpan yang terkini (pengelogan, tarikh menyiarkan artikel, menambah produk, membuat pesanan) dan yang akan datang dalam acara masa hadapan yang boleh dijangka (keluaran versi baharu, kalendar dan penjadual, dsb.).

Kemudahan utama menggunakan jenis TIMESTAMP ialah untuk lajur jenis ini dalam jadual, anda boleh menetapkan nilai lalai dalam bentuk penggantian masa semasa, serta menetapkan masa semasa semasa mengemas kini rekod. Jika anda memerlukan ciri ini, maka terdapat 99% kemungkinan bahawa TIMESTAMP adalah apa yang anda perlukan. (Lihat manual untuk cara melakukan ini.)

Jangan takut perisian anda akan berhenti berfungsi apabila kami menghampiri 2038. Pertama, sebelum masa ini, perisian anda kemungkinan besar akan dihentikan penggunaannya (terutamanya versi yang sedang ditulis sekarang). Kedua, apabila tarikh ini semakin hampir, pembangun MySQL pasti akan menghasilkan sesuatu untuk mengekalkan fungsi perisian anda. Semuanya akan selesai begitu juga dengan masalah Y2K.

Jadi, kami menggunakan jenis TIMESTAMP untuk menyimpan tarikh dan masa peristiwa masa kita, dan DATETIME dan DATE untuk menyimpan tarikh dan masa peristiwa bersejarah, atau peristiwa masa depan yang mendalam.

Julat nilai ialah perbezaan penting antara jenis TIMESTAMP, DATETIME dan DATE, tetapi bukan perkara utama. Utama bahawa TIMESTAMP menyimpan nilai dalam UTC. Apabila menyimpan nilai, ia diterjemahkan daripada zon waktu semasa kepada UTC, dan apabila membacanya, ia diterjemahkan daripada zon waktu semasa daripada UTC. DATETIME dan DATE sentiasa menyimpan dan memaparkan masa yang sama, tanpa mengira zon waktu.

Zon waktu ditetapkan DBMS MySQL secara global atau untuk sambungan semasa.Yang terakhir boleh digunakan untuk memastikan operasi pengguna yang berbeza dalam zon waktu yang berbeza pada peringkat DBMS. Semua nilai masa akan disimpan secara fizikal dalam UTC, dan diterima daripada pelanggan dan diberikan kepada pelanggan - dalam nilai zon waktunya. Tetapi hanya apabila menggunakan jenis data TIMESTAMP. DATE dan DATETIME sentiasa menerima, menyimpan dan mengembalikan nilai yang sama.

Fungsi NOW() dan sinonimnya mengembalikan nilai masa dalam zon waktu semasa pengguna.

Memandangkan semua keadaan ini, anda mesti berhati-hati apabila menukar zon waktu dalam sambungan ke pelayan dan menggunakan jenis DATE dan DATETIME. Jika anda perlu menyimpan tarikh (contohnya, tarikh lahir), maka tidak akan ada masalah. Tarikh lahir adalah sama di mana-mana zon. Itu. jika anda dilahirkan pada 1 Januari pada 0:00 UTC/GMT+0, maka ini tidak bermakna di Amerika mereka akan menyambut hari lahir anda pada 31 Disember. Tetapi jika anda memutuskan untuk menyimpan masa peristiwa dalam lajur DATETIME, maka ia tidak akan dapat berfungsi dengan zon waktu pengguna pada peringkat DBMS. Biar saya jelaskan dengan contoh:

Pengguna X berfungsi dalam zon UTC/GMT+2, Y - dalam zon UTC/GMT+3. Untuk sambungan pengguna ke MySQL, zon waktu yang sepadan (masing-masing mempunyai sendiri) ditetapkan. Pengguna menghantar mesej di forum, kami berminat dengan tarikh mesej itu ditulis.

Pilihan 1: DATETIME. Pengguna X menulis mesej pada 14:00 UTC/GMT+2. Nilai dalam medan "tarikh" mesej digantikan sebagai hasil daripada melaksanakan fungsi NOW() - 14:00. Pengguna Y membaca masa mesej itu ditulis dan melihat 14:00 yang sama. Tetapi tetapannya ditetapkan kepada UTC/GMT+3, dan dia berpendapat bahawa mesej itu ditulis bukan sahaja sekarang, tetapi sejam yang lalu.

Pilihan 2: TIMESTAMP. Pengguna X menulis mesej pada 14:00 UTC/GMT+2. Medan "tarikh" mengandungi hasil pelaksanaan fungsi NOW() - dalam dalam kes ini- 12:00 UTC/GMT+0. UserY membaca masa mesej ditulis dan diterima (UTC/GMT+3)(12:00 UTC/GMT+0) = 15:00 UTC/GMT+3. Segala-galanya ternyata seperti yang kita mahukan. Dan yang paling penting, ia amat mudah digunakan: untuk menyokong zon waktu tersuai, anda tidak perlu menulis sebarang kod penukaran masa.

Kemungkinan untuk menggantikan masa semasa dan bekerja dengan zon waktu dalam jenis TIMESTAMP sangat berkuasa sehingga jika anda perlu menyimpan tarikh tanpa masa dalam log tertentu, anda masih harus menggunakan TIMESTAMP dan bukannya DATE, tanpa menyimpan 1 bait perbezaan antara mereka. Dalam kes ini, abaikan sahaja "00:00:00".

Jika anda tidak boleh menggunakan TIMESTAMP kerana julat nilainya yang agak kecil (biasanya 1-2 kes berbanding 10-15 dalam pangkalan data tapak), anda perlu menggunakan DATETIME dan berhati-hati melaraskan nilainya di tempat yang betul ( iaitu semasa menulis dalam medan ini, tukar tarikh kepada UTC dan semasa membaca - kepada masa dalam zon pengguna membaca). Jika anda hanya menyimpan tarikh, mungkin tidak kira zon waktu yang anda ada: Tahun Baru Semua orang menyambut 1 Januari mengikut waktu tempatan, tidak perlu menterjemah apa-apa di sini.

Tujuan artikel ini adalah untuk menerangkan spesifik bekerja dengan jenis DATETIME dalam Pelayan SQL, termasuk salah tanggapan biasa dan cadangan am untuk mengatasi mereka. Terima kasih kepada Frank Kalis, artikel ini telah diterjemahkan ke dalam bahasa Jerman.

terima kasih:

Saya ingin mengucapkan terima kasih kepada orang berikut atas cadangan dan sumbangan berharga mereka kepada artikel ini: Steve Kass, Aaron Bertrand, Jacco Schalkwijk, Klaus Oberdalhoff, Hugo Kornelis, Dan Guzman, dan Erland Sommarskog.

Versi SQL Server

Artikel ini digunakan untuk SQL Server 7.0, 2000, 2005 dan 2008 melainkan dinyatakan sebaliknya.

Jenis Tarikh dan Masa dalam SQL Server

Sebelum SQL Server 2008, SQL Server mempunyai dua jenis data untuk mengendalikan tarikh dan masa. Oleh kerana kami akan merujuk kepada jenis ini dengan kerap dalam artikel ini, kami akan memperkenalkan singkatan untuk setiap jenis dalam dua jadual di bawah (lajur SC):

Nama

Min. maksudnya

Maks. maksudnya

Ketepatan

Memori yang digunakan

smalldatetime sdt 1900-01-01 00:00:00 2079-06-06 23:59:00 minit 4 bait
masa tarikh dt 1753-01-01 00:00:00.000 9999-12-31 23:59:59.997 3.33 ms 8 bait

Sila ambil perhatian bahawa tiada jenis data di sini yang mengandungi hanya tarikh atau masa sahaja. Kedua-dua jenis data di atas terdiri daripada bahagian/segmen seperti tarikh dan masa.

Jika anda hanya menentukan bahagian tarikh, SQL Server akan menyimpan masa sebagai 00:00:00.000.
Dan jika anda menetapkan nilai kepada masa sahaja, SQL Server akan menyimpan tarikh sebagai 01/01/1900.
Ianya sangat penting. Baca sekali lagi.

PILIH PELAKON (‘20041223’AS masa tarikh )

———————–
2004-12-23 00:00:00.000

PILIH PELAKON (’14:23:58′ AS masa tarikh )

———————–
1900-01-01 14:23:58.000

Dengan kemunculan SQL Server 2008, beberapa jenis data baharu yang dikaitkan dengan nilai tarikh dan masa telah diperkenalkan:

Nama

Min. maksudnya

Maks. maksudnya

Ketepatan

Memori yang digunakan

datetime2 dt2 0001-01-01 00:00:00.0000000 9999-12-31 23:59:59.9999999 100 ns 6-8 bait
Tarikh d 0001-01-01 9999-12-31 hari 3 bait
masa t 00:00:00.0000000 23:59:59.9999999 100 ns 3-5 bait
datetimeoffset dto 0001-01-01 00:00:00.0000000 9999-12-31 23:59:59.9999999 100 ns 8-10 bait
  • Seperti yang anda lihat, kami akhirnya mendapat jenis data tarikh sahaja ( Tarikh) dan hanya untuk masa ( masa).
  • Tarikh masa2 ini adalah "DATETIME yang lebih baik" untuk beberapa sebab, dan tidak mengambil lebih banyak memori daripada masa tarikh dan berpotensi lebih kurang!
  • Untuk jenis baharu yang melibatkan nilai masa, anda boleh menentukan "ketepatan saat pecahan" dengan menentukan susunan digit yang digunakan dalam saat selepas titik perpuluhan. Jadi masa(3) boleh menyimpan nilai seperti 14:23:12.567, yang apabila dimasukkan sebagai 14:23:12:5677 dibundarkan kepada 14:23:12:568.
  • Jenis baru datetimeoffset mengandungi sebahagian daripada zon waktu tempatan yang diimbangi.

Format tarikh dan masa

Salah tanggapan yang biasa ialah SQL Server menyimpan jenis data ini dalam beberapa format yang boleh dibaca khusus. Ini adalah salah. SQL Server menyimpan nilai tersebut dalam format dalamannya (contohnya, dua integer untuk masa tarikh Dan smalldatetime). Bahawa dikatakan, apabila menggunakan T-SQL untuk menetapkan nilai (contohnya dalam pernyataan INSERT) anda menyatakannya sebagai rentetan teks. Terdapat juga peraturan untuk tafsiran oleh SQL Server pelbagai format rentetan tarikh. Tetapi ambil perhatian bahawa SQL Server tidak akan mengingati format ini dalam apa jua keadaan.

Format input untuk tarikh dan masa

Terdapat banyak format yang tersedia untuk menukar nilai kepada tarikh/masa/masa tarikh. Sesetengah daripada mereka adalah "lebih baik" daripada yang lain, dan kemudian anda akan faham mengapa "lebih baik". Perlu diperhatikan bahawa semua format ini boleh digunakan untuk semua jenis. Jadi walaupun format "masa sahaja" boleh digunakan untuk jenis "tarikh sahaja", dsb. (Artikel ini mengabaikan bahagian mengimbangi zon waktu tempatan, yang hanya digunakan dalam jenis data datetimeoffset– lebih lanjut mengenainya dalam Buku Dalam Talian.)

Nama

Format

TETAPKAN DATEFORMAT pergantungan

TETAPkan pergantungan BAHASA

Berkecuali Bahasa

Tidak berpisah u ‘19980223 14:23:05’ Tidak Tidak untuk semua
Berpisah s '02/23/1998 14:23:05' untuk semua untuk semua Tidak
ANSI SQL ansisql ‘1998-12-23 14:23:05’ sdt , dt sdt , dt bukan untuk sdt Dan dt
Mengikut abjad a '23 Februari 1998 14:23:05' Tidak untuk semua orang (nama bulan) Tidak
Masa tarikh ODBC odt (ts '1998-02-23 14:23:05') Tidak Tidak untuk semua
tarikh ODBC od (d '1998-02-23') Tidak Tidak untuk semua
masa ODBC ot (t ’14:23:05′) Tidak Tidak untuk semua
ISO 8601 iso '1998-02-23T14:23:05' Tidak Tidak untuk semua
Masa t '14:23:05'
‘2:23:05 PM’
Tidak Tidak untuk semua
  • Perhatikan bahawa ANSI SQL sungguh sahaja kes istimewa format terhad Berpisah(yang dipanggil “digital”), menggunakan sengkang (-), sengkang (/) dan noktah (.) sebagai pembatas. Tetapi, kerana ini adalah satu-satunya format yang ditakrifkan dalam piawaian ANSI SQL, pada pendapat penulis ia patut disebut sebagai kes khas.
  • Kebanyakan format membenarkan anda mengalih keluar bahagian tarikh dan/atau masa, dan dalam beberapa kes ini boleh kelihatan sedikit... pelik. Nampaknya tidak munasabah untuk menentukan, sebagai contoh, '2008-08-25' sebagai jenis masa ( masa), tetapi hasil akhirnya adalah sama seperti tidak menetapkan nilai dalam rentetan masa tarikh. Pertimbangkan di bawah:
    PILIH PELAKON (AS masa )
    PILIH PELAKON (‘2008-08-25’ AS masa )

    Kedua-dua pertanyaan menghasilkan hasil yang sama (masa 00:00:00).
  • Format ODBC ( Masa tarikh ODBC, tarikh ODBC, masa ODBC) adalah berbeza kerana ia mempunyai token (jenis_literal, t, d, atau ts) yang mesti ditetapkan dengan betul bergantung pada sama ada anda mendapat tarikh dan masa, hanya tarikh atau hanya masa.
  • Untuk menggunakan format ISO 8601 segmen tarikh dan masa diperlukan.
  • SET DATEFORMAT mewarisi tetapannya daripada SET LANGUAGE (tetapi SET DATEFORMAT yang eksplisit mengatasi SET LANGUAGE kemudian). Tetapan bahasa lalai ditetapkan untuk setiap bahasa yang digunakan semasa memasuki log masuk. Bahasa log masuk lalai ditetapkan menggunakan sp_configure.
  • Peraturan mengenai pemformatan bahagian tarikh dan jenis baharu boleh mengelirukan. Microsoft komited untuk mengemas kini jenis data baharu yang berkaitan ( tarikh, datetime2 dan datetimeoffset) kurang bergantung pada tetapan dan lebih mematuhi keperluan ANSI SQL. Dan akibatnya, jenis neutral bahasa baharu untuk menyerlahkan komponen masa tarikh asalkan tahun itu didahulukan. Pelayan SQL adalah perlu untuk menentukan bahawa bahagian ini ialah tahun, dan oleh itu 4 jawatan yang membentuk tahun diperlukan (yyyy, bukan yy). Jika ya, maka rentetan itu akan ditafsirkan sebagai tahun pertama, kemudian bulan dan akhirnya hari - tanpa mengira DATEFORMAT atau tetapan bahasa. Jika bulan dinyatakan dahulu, maka DATEFORMAT dan tetapan bahasa akan "diperhatikan":
    SET BAHASA British –menggunakan dmy
    PERGI
    PILIH PELAKON ('02-23-1998 14:23:05' AS Tarikh ) –Ralat
    PERGI
    PILIH PELAKON (‘2/23/1998 14:23:05’ AS Tarikh ) –Ralat
    PERGI
    PILIH PELAKON (‘1998-02-23 14:23:05’ AS Tarikh ) -Okey
    PERGI
    PILIH PELAKON (‘1998.02.23 14:23:05’ AS Tarikh ) -Okey
    PERGI
    PILIH PELAKON (‘1998/02/23 14:23:05’ AS Tarikh) -Okey
    PERGI
    Pertama
    dua pertanyaan tidak betul kerana tahun itu tidak berada di kedudukan pertama (dan tidak ada 23 bulan pada tahun 1998). Tiada ralat dalam tiga pertanyaan seterusnya kerana keperluan dipenuhi dan tahun disenaraikan dahulu (dan kami menggunakan salah satu gaya jenis tarikh baharu). Sangat telus, bukan? 🙂

Penerangan tentang format yang tersedia tersedia dalam Buku Dalam Talian, jadi tidak ada gunanya untuk menerangkan secara terperinci untuk setiap format.

Membangunkan Aplikasi Pangkalan Data Berasaskan Masa dalam SQL oleh Richard T. Snodgrass: mengandungi banyak maklumat tentang mewakili maklumat berasaskan masa dalam model data. Dan, sudah tentu, adalah mungkin untuk menggunakan maklumat tambahan (sejarah) ini dalam anda pertanyaan SQL. Buku ini tidak dicetak, tetapi di tapak web rasmi Richard (www.cs.arizona.edu/people/rts), anda boleh memuat turunnya secara percuma dalam format PDF.

Terjemahan: Vinchik Evgeniy

Saya tidak mengesyorkan menggunakan tidak juga Medan DATETIME atau TIMESTAMP. Jika anda ingin mewakili hari tertentu secara umum (seperti hari lahir), gunakan jenis DATE, tetapi jika anda lebih khusus, anda mungkin berminat untuk merakam detik sebenar dan bukannya unit masa (hari, minggu, bulan, tahun). Daripada menggunakan DATETIME atau TIMESTAMP, gunakan BIGINT dan simpan sahaja bilangan milisaat sejak zaman itu (System.currentTimeMillis() jika anda menggunakan Java). Ini mempunyai beberapa kelebihan:

  1. Anda mengelakkan penguncian vendor. Hampir setiap pangkalan data menyokong integer dengan cara yang agak serupa. Katakan anda ingin berpindah ke pangkalan data lain. Adakah anda ingin bimbang tentang perbezaan antara nilai MySQL DATETIME dan bagaimana Oracle menentukannya? Malah antara yang berbeza versi MySQL, TIMESTAMPS mempunyai tahap berbeza ketepatan. Baru-baru ini, MySQL menyokong milisaat dalam cap masa.
  2. Tiada masalah zon waktu. Terdapat beberapa ulasan bernas di sini tentang perkara yang berlaku dengan zon waktu sejak itu jenis yang berbeza data. Tetapi adakah ini pengetahuan am, dan rakan sekerja anda akan mempelajari perkara ini sepanjang masa? Sebaliknya, agak sukar untuk mencampurkan BigINT dalam java.util.Date. Menggunakan BIGINT membawa kepada banyak isu zon waktu yang hilang di tepi jalan.
  3. Jangan risau tentang julat atau ketepatan. Anda tidak perlu risau tentang dipenggal oleh julat tarikh akan datang (TIMESTAMP ialah 2038 sahaja).
  4. Penyepaduan alatan pihak ketiga. Menggunakan integer adalah remeh untuk alatan pihak ketiga (seperti EclipseLink) untuk berinteraksi dengan pangkalan data. Tidak setiap alat pihak ketiga akan mempunyai pemahaman yang sama tentang "datetime" seperti yang dilakukan oleh MySQL. Ingin mencuba dalam Hibernate sama ada anda perlu menggunakan objek java.sql.TimeStamp atau java.util.Date jika anda menggunakan jenis data tersuai ini? Penggunaan jenis asas data menggunakan alat pihak ketiga remeh.

Masalah ini berkait rapat dengan cara anda harus menyimpan nilai kewangan (iaitu $1.99) dalam pangkalan data. Sekiranya anda menggunakan Decimal atau jenis wang dalam pangkalan data, atau yang paling teruk, Double? Kesemua 3 pilihan ini adalah buruk, kerana banyak sebab yang disenaraikan di atas. Penyelesaiannya adalah untuk menyimpan nilai wang dalam sen menggunakan BIGINT dan kemudian menukar sen kepada dolar apabila anda memaparkan nilai kepada pengguna. Tugas pangkalan data adalah untuk menyimpan data dan BUKAN mengumpul data. Semua jenis data mewah yang anda lihat dalam pangkalan data (terutama Oracle) menambah sedikit dan memulakan anda ke laluan ke kunci vendor.

2018-12-04T00:00Z

TIMESTAMP ialah 4 bait dengan 8 bait untuk DATETIME.

Tetapi seperti yang dikatakan skronid ia mempunyai had yang lebih rendah iaitu 1970. Ini bagus untuk apa-apa yang mungkin berlaku pada masa hadapan walaupun;)

11-12-2018T00:00Z

Perbezaan utama ialah DATETIME adalah malar, manakala TIMESTAMP bergantung pada tetapan zon_masa.

Jadi ini hanya penting apabila anda telah - atau mungkin pada masa hadapan telah - menyegerakkan kelompok dalam zon waktu.

Dalam lebih dalam kata mudah: Jika saya mempunyai pangkalan data di Australia dan saya membuang pangkalan data itu untuk menyegerakkan/mengisi pangkalan data di Amerika, maka TIMESTAMP akan dikemas kini untuk mencerminkan masa sebenar peristiwa dalam zon waktu baharu, manakala DATETIME masih mencerminkan masa acara dalam zon waktu.

Contoh yang sangat baik DATETIME yang digunakan di mana TIMESTAMP sepatutnya digunakan ialah Facebook, di mana pelayan mereka tidak dapat memastikan perkara yang berlaku semasa zon waktu. Saya pernah berbual di mana masa memberitahu saya bahawa saya sedang membalas mesej sebelum mesej itu benar-benar dihantar. (Ini, sudah tentu, juga boleh disebabkan oleh terjemahan yang salah dalam zon waktu dalam perisian untuk pemesejan jika masa dihantar dan tidak disegerakkan).

18-12-2018T00:00Z

Saya sentiasa menggunakan medan DATETIME untuk apa-apa selain metadata baris (tarikh dibuat atau diubah suai).