Yang mana:
adalah yang cara yang direkomendasikan untuk tanggal menyimpan dan waktu di SQL Server 2008+?
Saya menyadari perbedaan dalam presisi (dan kemungkinan ruang penyimpanan), tetapi mengabaikannya untuk saat ini, apakah ada dokumen praktik terbaik tentang kapan harus menggunakan apa, atau mungkin sebaiknya kita hanya menggunakan datetime2
saja?
DateTime2
Tipe tersebut (atau SQL Server lainnya Ketik untuk hal ini)? Lihat Kontra di 7/10/17 Jawaban saya di bawah ini untuk alasan saya bertanyaDATETIME2
memiliki rentang tanggal "0001/01/01" hingga "DATETIME
9999/12/31 " sedangkan jenisnya hanya mendukung tahun 1753-9999.Juga, jika perlu,
DATETIME2
bisa lebih tepat dalam hal waktu; DATETIME terbatas pada 3 1/3 milidetik, sementaraDATETIME2
dapat akurat hingga 100ns.Kedua jenis peta untuk
System.DateTime
di. NET - tidak ada perbedaan di sana.Jika Anda punya pilihan, saya akan merekomendasikan menggunakan
DATETIME2
sedapat mungkin. Saya tidak melihat manfaat menggunakanDATETIME
(kecuali untuk kompatibilitas mundur) - Anda akan memiliki lebih sedikit masalah (dengan tanggal di luar jangkauan dan kerumitan seperti itu).Plus: jika Anda hanya perlu tanggal (tanpa waktu), gunakan DATE - itu sama baiknya
DATETIME2
dan menghemat ruang Anda juga! :-) Hal yang sama berlaku hanya untuk waktu - gunakanTIME
. Untuk itulah jenis-jenis ini ada!sumber
Nullable<DateTime>
?datetime2 menang di sebagian besar aspek kecuali (Kompatibilitas aplikasi lama)
harap perhatikan poin-poin berikut
sumber gambar: MCTS Self-Paced Training Kit (Ujian 70-432): Microsoft® SQL Server® 2008 - Implementasi dan Pemeliharaan Bab 3: Tabel -> Pelajaran 1: Membuat Tabel -> halaman 66
sumber
datetime2
mengagumkan (Pemenang)datetime2
menggunakan ruang penyimpanan yang lebih sedikit daripadadatetime
namun menawarkan jangkauan yang lebih besar dan presisi yang lebih tinggi?Saya setuju dengan @marc_s dan @Adam_Poward - DateTime2 adalah metode yang disukai untuk bergerak maju. Ini memiliki rentang tanggal yang lebih luas, presisi lebih tinggi, dan menggunakan penyimpanan yang sama atau kurang (tergantung pada presisi).
Satu hal diskusi terjawab, namun ...
@Marc_s menyatakan:
Both types map to System.DateTime in .NET - no difference there
. Ini benar, namun, kebalikannya tidak benar ... dan itu penting ketika melakukan pencarian rentang tanggal (mis. "Temukan saya semua catatan yang diubah pada 5/5/2010").Versi .NET
Datetime
memiliki kisaran dan ketepatan yang mirip denganDateTime2
. Ketika pemetaan .net sebuahDatetime
turun ke SQL tuaDateTime
merupakan pembulatan implisit terjadi . SQL lamaDateTime
akurat hingga 3 milidetik. Ini berarti11:59:59.997
sedekat yang Anda bisa sampai pada akhir hari. Apa pun yang lebih tinggi dibulatkan ke hari berikutnya.Coba ini :
Menghindari pembulatan tersirat ini adalah alasan penting untuk pindah ke DateTime2. Pembulatan tanggal secara implisit jelas menyebabkan kebingungan:
sumber
20100505
ke5/5/2010
? Format sebelumnya akan bekerja dengan wilayah apa pun di SQL Server. Yang terakhir akan pecah:SET LANGUAGE French; SELECT Convert(datetime, '1/7/2015')
oops:2015-07-01 00:00:00.000
Hampir semua Jawaban dan Komentar berat di Pro dan ringan di Kontra. Berikut adalah ringkasan dari semua Pro dan Kontra sejauh ini ditambah beberapa Kontra penting (dalam # 2 di bawah) Saya hanya pernah melihat disebutkan sekali atau tidak sama sekali.
1.1. Lebih banyak ISO yang sesuai (ISO 8601) (walaupun saya tidak tahu bagaimana hal ini bisa dilakukan dalam praktiknya).
1.2. Lebih banyak rentang (1/1/0001 hingga 12/31/9999 vs. 1/1 / 1753-12 / 31/9999) (meskipun rentang ekstra, semua sebelum tahun 1753, kemungkinan tidak akan digunakan kecuali untuk mantan, dalam aplikasi historis, astronomi, geologi, dll.).
1.3. Persis cocok dengan rentang rentang .NET's
DateTime
Type (meskipun keduanya mengkonversi bolak-balik tanpa pengkodean khusus jika nilai-nilai berada dalam kisaran dan ketepatan jenis target kecuali untuk Con # 2.1 di bawah yang lain kesalahan / pembulatan akan terjadi).1.4. Lebih presisi (100 nanosecond alias 0,000,000,1 dtk vs 3,33 milisecond alias 0,003,33 dtk) (walaupun presisi ekstra kemungkinan tidak akan digunakan kecuali untuk mantan, dalam rekayasa / aplikasi ilmiah).
1.5. Ketika dikonfigurasi untuk serupa (seperti dalam 1 milidetik tidak "sama" (seperti dalam 3,33 milidetik) seperti yang diklaim Iman Abidi) presisi
DateTime
, menggunakan lebih sedikit ruang (7 vs 8 byte), tetapi tentu saja, Anda akan kehilangan manfaat presisi yang kemungkinan merupakan salah satu dari dua (kisaran lainnya) yang paling dipuji meskipun kemungkinan manfaat yang tidak dibutuhkan).2.1. Ketika melewati Parameter ke. NET
SqlCommand
, Anda harus menentukanSystem.Data.SqlDbType.DateTime2
apakah Anda mungkin melewati nilai di luarDateTime
rentang dan / atau presisi SQL Server , karena itu default untukSystem.Data.SqlDbType.DateTime
.2.2. Tidak dapat secara implisit / mudah dikonversi ke nilai numerik floating-point (# hari sejak min date-time) untuk melakukan hal berikut ke / dengan itu dalam ekspresi SQL Server menggunakan nilai numerik dan operator:
2.2.1. tambahkan atau kurangi # hari atau sebagian hari. Catatan: Menggunakan
DateAdd
Fungsi sebagai solusi bukanlah hal yang sepele ketika Anda perlu mempertimbangkan banyak jika tidak semua bagian dari tanggal-waktu.2.2.2. ambil perbedaan antara dua kali tanggal untuk keperluan perhitungan "usia". Catatan: Anda tidak bisa hanya menggunakan
DateDiff
Fungsi SQL Server sebagai gantinya, karena itu tidak menghitungage
seperti yang diharapkan kebanyakan orang bahwa jika dua tanggal-waktu terjadi untuk melintasi batas kalender / jam tanggal-waktu dari unit yang ditentukan jika bahkan untuk sebagian kecil dari unit itu, ia akan mengembalikan selisih 1 dari unit itu vs 0. Misalnya,DateDiff
dalamDay
dua kali tanggal hanya terpisah 1 milidetik akan mengembalikan 1 vs 0 (hari) jika waktu-waktu tersebut adalah pada hari kalender yang berbeda (yaitu "1999-12-31 23: 59: 59.9999999" dan "2000-01-01 00: 00: 00.0000000"). Perbedaan waktu yang sama 1 milidetik jika dipindahkan sehingga tidak melewati hari kalender, akan mengembalikan "DateDiff" dalamDay
0 (hari).2.2.3. ambil
Avg
tanggal-waktu (dalam Kueri Agregat) dengan hanya mengonversi ke "Float" terlebih dahulu dan kemudian kembali lagi keDateTime
.CATATAN: Untuk mengonversi
DateTime2
menjadi angka, Anda harus melakukan sesuatu seperti rumus berikut yang masih mengasumsikan nilai Anda tidak kurang dari tahun 1970 (yang berarti Anda kehilangan semua rentang tambahan ditambah 217 tahun lagi. Catatan: Anda dapat tidak dapat hanya menyesuaikan rumus untuk memungkinkan rentang tambahan karena Anda dapat mengalami masalah luapan numerik.25567 + (DATEDIFF(SECOND, {d '1970-01-01'}, @Time) + DATEPART(nanosecond, @Time) / 1.0E + 9) / 86400.0
- Sumber: " https://siderite.dev/blog/how-to-translate-t-sql-datetime2-to.html "Tentu saja, Anda bisa juga
Cast
untuk yangDateTime
pertama (dan jika perlu kembali lagi keDateTime2
), tetapi Anda akan kehilangan ketepatan dan jangkauan (semua sebelum tahun 1753) manfaatDateTime2
vsDateTime
yang merupakan 2 terbesar dan juga pada saat yang sama prolly 2 yang paling tidak mungkin diperlukan yang menimbulkan pertanyaan mengapa menggunakannya ketika Anda kehilangan konversi implisit / mudah ke angka floating-point (# hari) untuk tambahan / pengurangan / "usia" (vsDateDiff
) /Avg
manfaat calc yang merupakan hal besar dalam pengalaman saya.Btw,
Avg
tanggal-waktu adalah (atau setidaknya seharusnya ) kasus penggunaan yang penting. a) Selain digunakan dalam mendapatkan durasi rata-rata ketika tanggal-waktu (karena tanggal-waktu basis umum) digunakan untuk mewakili durasi (praktik umum), b) juga berguna untuk mendapatkan statistik tipe dasbor tentang apa yang rata-rata tanggal- waktu dalam kolom tanggal-waktu dari rentang / grup Baris. c) Standar (atau paling tidak harus standar) Permintaan ad-hoc untuk memantau / memecahkan masalah nilai-nilai dalam suatu Kolom yang mungkin tidak berlaku lagi / lebih lama dan / atau mungkin perlu dihentikan adalah mendaftar untuk setiap nilai hitungan kejadian dan (jika tersedia) perangkoMin
,Avg
danMax
tanggal-waktu yang terkait dengan nilai itu.sumber
DateTime
, semuanya terkait dengan efek pada SQL Server Queries dan pernyataan.DateTime2
telah saya sebutkan (karena kemungkinan besar meluap)). Kembali. "tidak berfungsi untuk sebagian besar jenis tanggal": Anda hanya perlu bekerja dengan satu jenis tanggal, dan sebagian besar tanggal di sebagian besar aplikasi kemungkinan tidak perlu dikonversi ke jenis tanggal lain untuk seumur hidup mereka (kecuali mungkin, seperti yang saya sebutkan juga ,DateTime2
untukDateTime
(mis. untuk melakukan "aritmatika pada tanggal"; P). Mengingat bahwa, tidak layak semua pengkodean tambahan tidak hanya diprogram tetapi juga permintaan penelitian khusus untuk menggunakan jenis tanggal ramah non-aritmatika.DateTime2 mendatangkan malapetaka jika Anda adalah seorang pengembang Access yang mencoba menulis Now () ke bidang yang dimaksud. Baru saja melakukan Access -> SQL 2008 R2 migrasi dan itu menempatkan semua bidang datetime sebagai DateTime2. Menambahkan catatan dengan Now () saat nilainya dibom. Tidak apa-apa pada 1/1/2012 14:53:04 PM, tetapi tidak pada 1/10/2012 14:53:04 PM.
Setelah karakter membuat perbedaan. Semoga ini bisa membantu seseorang.
sumber
Berikut ini adalah contoh yang akan menunjukkan kepada Anda perbedaan dalam ukuran penyimpanan (byte) dan presisi antara waktu-kecil, waktu-waktu, datetime2 (0), dan datetime2 (7):
yang kembali
Jadi jika saya ingin menyimpan informasi hingga detik - tetapi tidak ke milidetik - saya dapat menyimpan masing-masing 2 byte jika saya menggunakan datetime2 (0) alih-alih datetime atau datetime2 (7).
sumber
sementara ada peningkatan presisi dengan datetime2 , beberapa klien tidak mendukung tanggal , waktu , atau datetime2 dan memaksa Anda untuk mengonversi ke string literal. Secara khusus Microsoft menyebutkan "down level" ODBC, OLE DB, JDBC, dan SqlClient masalah dengan tipe data ini dan memiliki bagan yang menunjukkan bagaimana masing-masing dapat memetakan jenis.
Jika kompatibilitas nilai lebih dari presisi, gunakan datetime
sumber
Pertanyaan Lama ... Tapi saya ingin menambahkan sesuatu yang belum dinyatakan oleh siapa pun di sini ... (Catatan: Ini adalah pengamatan saya sendiri, jadi jangan minta referensi apa pun)
Datetime2 lebih cepat bila digunakan dalam kriteria filter.
TLDR:
Di SQL 2016 saya punya tabel dengan ratusan ribu baris dan kolom datetime ENTRY_TIME karena itu diperlukan untuk menyimpan waktu yang tepat hingga detik. Saat menjalankan kueri yang kompleks dengan banyak gabungan dan sub kueri, saat saya menggunakan klausa mana sebagai:
Awalnya permintaan baik-baik saja ketika ada ratusan baris, tetapi ketika jumlah baris meningkat, permintaan mulai memberikan kesalahan ini:
Saya menghapus klausa tempat, dan tanpa terduga, kueri dijalankan dalam 1 detik, meskipun sekarang SEMUA baris untuk semua tanggal diambil. Saya menjalankan kueri batin dengan di mana klausa, dan butuh 85 detik, dan tanpa klausa mana butuh 0,01 detik.
Saya menemukan banyak utas di sini untuk masalah ini sebagai kinerja penyaringan datetime
Saya sedikit mengoptimalkan permintaan. Tapi kecepatan sebenarnya yang saya dapatkan adalah dengan mengubah kolom datetime ke datetime2.
Sekarang permintaan yang sama yang waktunya habis sebelumnya membutuhkan waktu kurang dari satu detik.
Bersulang
sumber
Interpretasi string tanggal menjadi
datetime
dandatetime2
bisa berbeda juga, saat menggunakanDATEFORMAT
pengaturan non-AS . MisalnyaIni mengembalikan
2013-05-06
(yaitu 6 Mei) untukdatetime
, dan2013-06-05
(yaitu 5 Juni) untukdatetime2
. Namun, dengandateformat
disetel kemdy
, keduanya@d
dan@d2
kembali2013-06-05
.The
datetime
perilaku tampaknya bertentangan dengan dokumentasi MSDN dariSET DATEFORMAT
yang menyatakan: Beberapa format string karakter, misalnya ISO 8601, ditafsirkan secara independen dari pengaturan DateFormat . Jelas tidak benar!Sampai saya digigit oleh ini, saya selalu berpikir bahwa
yyyy-mm-dd
tanggal hanya akan ditangani dengan benar, terlepas dari pengaturan bahasa / lokal.sumber
SET LANGUAGE FRENCH; DECLARE @d DATETIME = '20130605'; SELECT @d;
Coba lagi dengan tanda hubung.Menurut artikel ini , jika Anda ingin memiliki ketepatan DateTime yang sama menggunakan DateTime2 Anda cukup menggunakan DateTime2 (3). Ini akan memberi Anda presisi yang sama, mengambil satu byte lebih sedikit, dan memberikan rentang yang diperluas.
sumber
Saya hanya menemukan satu keuntungan lagi untuk
DATETIME2
: ia menghindari bug dalamadodbapi
modul Python , yang meledak jikadatetime
nilai pustaka standar dilewatkan yang memiliki mikrodetik bukan nol untukDATETIME
kolom tetapi berfungsi dengan baik jika kolom didefinisikan sebagaiDATETIME2
.sumber
SQL di atas tidak akan berfungsi dengan bidang DateTime2. Ini kembali dan kesalahan "Operan tipe clash: datetime2 tidak kompatibel dengan int"
Menambahkan 1 untuk mendapatkan hari berikutnya adalah sesuatu yang telah dilakukan pengembang dengan tanggal selama bertahun-tahun. Sekarang Microsoft memiliki bidang datetime2 super baru yang tidak dapat menangani fungsi sederhana ini.
"Mari kita gunakan tipe baru ini yang lebih buruk daripada yang lama", kurasa tidak!
sumber
datetime
dandatetime2
tipe data keduanya diperkenalkan di SQL Server 2008. Anda juga mendapatkanOperand type clash: date is incompatible with int
daridate
tipe yang sudah ada sejak hari dot. Ketiga tipe data berfungsi dengan baikdateadd(dd, 1, ...)
.Saya pikir
DATETIME2
ini adalah cara yang lebih baik untuk menyimpandate
, karena memiliki efisiensi lebih dariDATETIME
. DalamSQL Server 2008
Anda dapat menggunakanDATETIME2
, menyimpan tanggal dan waktu, dibutuhkan 6-8bytes
untuk menyimpan dan memiliki presisi100 nanoseconds
. Jadi siapa pun yang membutuhkan ketepatan waktu yang lebih besar akan menginginkannyaDATETIME2
.sumber