Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

datetime vs datetime2 di SQL Server:Apa Bedanya?

Artikel ini membahas perbedaan utama antara waktu-tanggal dan datetime2 tipe data di SQL Server.

Jika Anda tidak yakin yang mana yang akan digunakan, gunakan datetime2 (lihat kelebihannya di bawah).

Berikut tabel yang menjelaskan perbedaan utama antara kedua jenis ini.

Fitur datetime datetime2
Sesuai dengan SQL (ANSI &ISO 8601) Tidak Ya
Rentang Tanggal 1753-01-01 sampai 9999-12-31 0001-01-01 hingga 9999-12-31
Rentang Waktu 00:00:00 sampai 23:59:59,997 00:00:00 sampai 23:59:59.9999999
Panjang Karakter Minimum 19 posisi
maksimal 23
Minimum 19 posisi
maksimum 27
Ukuran Penyimpanan 8 byte 6 hingga 8 byte, tergantung pada presisi*

* Ditambah 1 byte untuk menyimpan presisi

Akurasi Dibulatkan menjadi kelipatan .000, .003, atau .007 detik 100 nanodetik
Presisi pecahan detik yang ditentukan pengguna Tidak Ya
Offset Zona Waktu Tidak ada Tidak ada
Awas dan pelestarian zona waktu Tidak Tidak
Mengingat musim panas Tidak Tidak

Keuntungan dari 'datetime2'

Seperti yang terlihat pada tabel di atas, datetime2 type memiliki banyak keunggulan dibandingkan datetime , termasuk:

  • rentang tanggal yang lebih besar
  • presisi pecahan default yang lebih besar
  • presisi yang ditentukan pengguna opsional
  • akurasi lebih tinggi, bahkan saat menggunakan jumlah tempat desimal yang sama dengan datetime (yaitu 3)
  • ukuran penyimpanan lebih kecil saat menggunakan jumlah desimal yang sama dengan waktu-tanggal , namun dengan akurasi yang lebih tinggi*
  • opsi untuk menggunakan penyimpanan 2 byte lebih sedikit daripada datetime (walaupun dengan presisi yang lebih rendah)*
  • sejajar dengan standar SQL (ANSI &ISO 8601)

* Dalam beberapa kasus datetime2 value menggunakan byte ekstra untuk menyimpan presisi, yang akan menghasilkan ukuran penyimpanan yang sama dengan datetime saat menggunakan jumlah tempat desimal yang sama. Baca terus untuk mengetahui lebih lanjut tentang ini.

Haruskah saya menggunakan 'datetime' atau 'datetime2'?

Microsoft merekomendasikan datetime2 melebihi waktu kencan untuk pekerjaan baru (dan untuk alasan yang sama seperti yang disebutkan di atas).

Oleh karena itu, Anda harus menggunakan datetime2 , kecuali Anda memiliki alasan khusus untuk tidak melakukannya (seperti bekerja dengan sistem lama).

Contoh 1 – Perbandingan Dasar

Berikut adalah contoh singkat untuk menunjukkan perbedaan mendasar antara datetime dan datetime2 .

DECLARE 
  @thedatetime2 datetime2(7), 
  @thedatetime datetime;
SET @thedatetime2 = '2025-05-21 10:15:30.5555555';
SET @thedatetime = @thedatetime2;
SELECT 
  @thedatetime2 AS 'datetime2',
  @thedatetime AS 'datetime';

Hasil:

+-----------------------------+-------------------------+
| datetime2                   | datetime                |
|-----------------------------+-------------------------|
| 2025-05-21 10:15:30.5555555 | 2025-05-21 10:15:30.557 |
+-----------------------------+-------------------------+

Di sini, saya menetapkan waktu tanggal variabel dengan nilai yang sama dengan datetime2 variabel. Hal ini menyebabkan nilai dikonversi ke datetime dan kemudian kita dapat menggunakan SELECT pernyataan untuk melihat hasilnya.

Dalam hal ini, datetime2 variabel menggunakan skala 7, yang berarti 7 tempat desimal. waktu kencan sebaliknya, hanya menggunakan 3 tempat desimal, dan digit pecahan terakhirnya dibulatkan ke atas (karena tipe data ini membulatkan pecahan detik menjadi kelipatan .000, .003, atau .007 detik).

Contoh 2 – Menggunakan 3 Tempat Desimal

Jika saya mengurangi datetime2 skala ke 3 (untuk mencocokkan tanggal waktu ), inilah yang terjadi.

DECLARE 
  @thedatetime2 datetime2(3), 
  @thedatetime datetime;
SET @thedatetime2 = '2025-05-21 10:15:30.5555555';
SET @thedatetime = @thedatetime2;
SELECT 
  @thedatetime2 AS 'datetime2',
  @thedatetime AS 'datetime';

Hasil:

+-------------------------+-------------------------+
| datetime2               | datetime                |
|-------------------------+-------------------------|
| 2025-05-21 10:15:30.556 | 2025-05-21 10:15:30.557 |
+-------------------------+-------------------------+

Jadi datetime2 nilai juga dibulatkan dalam kasus ini. Namun, hanya dibulatkan menjadi 556 – tidak melompat ke 557 seperti waktu kencan nilai tidak.

Tentu saja, satu-satunya alasan datetime2 nilai dibulatkan ke atas karena angka berikut adalah 5 atau lebih tinggi. Jika kita mengurangi angka berikut, tidak ada pembulatan yang dilakukan:

DECLARE 
  @thedatetime2 datetime2(3), 
  @thedatetime datetime;
SET @thedatetime2 = '2025-05-21 10:15:30.5554444';
SET @thedatetime = @thedatetime2;
SELECT 
  @thedatetime2 AS 'datetime2',
  @thedatetime AS 'datetime';

Hasil:

+-------------------------+-------------------------+
| datetime2               | datetime                |
|-------------------------+-------------------------|
| 2025-05-21 10:15:30.555 | 2025-05-21 10:15:30.557 |
+-------------------------+-------------------------+

Namun, waktu tanggal nilainya terus dibulatkan.

Contoh 3 – Menetapkan Nilai dari Literal String

Pada contoh sebelumnya, tanggal waktu nilai ditetapkan dengan menyetelnya ke nilai yang sama dengan datetime2 nilai. Ketika kami melakukannya, SQL Server melakukan konversi implisit agar data "sesuai" dengan tipe data baru.

Namun, jika kami mencoba menetapkan literal string yang sama ke datetime variabel yang kami tetapkan ke datetime2 , kami mendapatkan kesalahan:

DECLARE 
  @thedatetime2 datetime2(3), 
  @thedatetime datetime;
SET @thedatetime2 = '2025-05-21 10:15:30.5554444';
SET @thedatetime = '2025-05-21 10:15:30.5554444';
SELECT 
  @thedatetime2 AS 'datetime2',
  @thedatetime AS 'datetime';

Hasil:

Msg 241, Level 16, State 1, Line 5
Conversion failed when converting date and/or time from character string.

Ini karena waktu kencan hanya menerima literal string yang memiliki 3 detik pecahan atau kurang.

Jadi untuk mengatasi masalah ini, kita perlu mengurangi bagian pecahan menjadi hanya 3 (atau kurang) tempat desimal.

DECLARE 
  @thedatetime2 datetime2(3), 
  @thedatetime datetime;
SET @thedatetime2 = '2025-05-21 10:15:30.5554444';
SET @thedatetime = '2025-05-21 10:15:30.555';
SELECT 
  @thedatetime2 AS 'datetime2',
  @thedatetime AS 'datetime';

Hasil:

+-------------------------+-------------------------+
| datetime2               | datetime                |
|-------------------------+-------------------------|
| 2025-05-21 10:15:30.555 | 2025-05-21 10:15:30.557 |
+-------------------------+-------------------------+

datetime2 type tidak memiliki batasan ini, bahkan saat menggunakan skala 3.

Contoh 4 – Ukuran Penyimpanan

waktu kencan tipe data memiliki ukuran penyimpanan tetap 8 byte.

datetime2 di sisi lain, dapat berupa 6, 7, atau 8 byte, tergantung pada presisinya.

Saat menggunakan 3 tempat desimal, datetime2 hanya menggunakan 7 byte, yang berarti menggunakan lebih sedikit ruang penyimpanan daripada datetime (dengan lebih akurat).

Namun, Microsoft menyatakan bahwa datetime2 type juga menggunakan 1 byte tambahan untuk menyimpan presisinya. Jadi dalam hal ini, itu akan menggunakan 8 byte. Oleh karena itu, kita dapat merevisi pernyataan sebelumnya dengan mengatakan bahwa pernyataan tersebut menggunakan 7, 8, atau 9 byte.

Namun, ini mungkin tergantung pada apakah kita menyimpannya dalam tabel atau variabel, dan apakah kita mengonversinya menjadi konstanta biner atau tidak.

Inilah yang terjadi jika kita menggunakan DATALENGTH() fungsi untuk mengembalikan jumlah byte yang digunakan untuk setiap nilai kita:

DECLARE 
  @thedatetime2 datetime2(3), 
  @thedatetime datetime;
SET @thedatetime2 = '2025-05-21 10:15:30.5554444';
SET @thedatetime = @thedatetime2;
SELECT 
  DATALENGTH(@thedatetime2) AS 'datetime2',
  DATALENGTH(@thedatetime) AS 'datetime';

Hasil

+-------------+------------+
| datetime2   | datetime   |
|-------------+------------|
| 7           | 8          |
+-------------+------------+

Tetapi jika kita mengonversinya menjadi varbinary , kita mendapatkan yang berikut:

DECLARE 
  @thedatetime2 datetime2(3), 
  @thedatetime datetime;
SET @thedatetime2 = '2025-05-21 10:15:30.5554444';
SET @thedatetime = @thedatetime2;
SELECT 
  DATALENGTH(CONVERT(VARBINARY(16),@thedatetime2)) AS 'datetime2',
  DATALENGTH(CONVERT(VARBINARY(16),@thedatetime)) AS 'datetime';

Hasil

+-------------+------------+
| datetime2   | datetime   |
|-------------+------------|
| 8           | 8          |
+-------------+------------+

Jadi datetime2 menggunakan byte ekstra saat dikonversi ke varbinary , sehingga membawanya ke ukuran penyimpanan yang sama dengan datetime .

Namun, contoh berikut menunjukkan bahwa ketika data disimpan dalam kolom database, kita mendapatkan panjang 7 byte untuk datetime2 dan 8 byte untuk datetime .

Saat menyimpan datetime2 nilai dalam database, definisi kolom mencakup presisi. Dalam hal ini nilai di setiap baris tidak memerlukan byte tambahan untuk menyimpan presisi, dan kita dapat mengatakan bahwa datetime2 menggunakan lebih sedikit ruang penyimpanan daripada datetime saat menggunakan jumlah detik pecahan yang sama.

Contoh 5 – Ukuran Penyimpanan untuk Data Tersimpan

Dalam contoh ini, saya membuat database dan menggunakan COL_LENGTH untuk mengembalikan panjang setiap kolom, dalam byte. Saya kemudian memasukkan datetime2 dan waktu kencan nilai ke dalamnya dan gunakan DBCC PAGE() untuk menemukan panjang data aktual dalam file halaman. Ini menunjukkan kepada kita ruang penyimpanan yang digunakan setiap tipe data saat disimpan dalam database.

Buat basis data:

CREATE DATABASE CompareTypes;

Buat tabel:

USE CompareTypes;

CREATE TABLE Datetime2vsDatetime (
    TheDateTime datetime,
    TheDateTime2 datetime2(3)
    );

Dalam hal ini saya membuat dua kolom – satu adalah datetime kolom dan yang lainnya adalah datetime2 kolom.

Periksa Panjang Kolom

Periksa panjang (dalam byte) setiap kolom:

SELECT 
  COL_LENGTH ( 'dbo.Datetime2vsDatetime' , 'TheDateTime2' ) AS 'datetime2',
  COL_LENGTH ( 'dbo.Datetime2vsDatetime' , 'TheDateTime' ) AS 'datetime';  

Hasil:

+-------------+------------+
| datetime2   | datetime   |
|-------------+------------|
| 7           | 8          |
+-------------+------------+

Jadi kita melihat bahwa datetime2 kolom memiliki panjang 7 byte, dibandingkan dengan datetime panjangnya 8 byte.

Sisipkan Data

Sekarang mari kita lihat ukuran penyimpanan dari nilai tanggal dan waktu aktual saat disimpan di SQL Server. Kita dapat menggunakan DBCC PAGE() untuk memeriksa halaman sebenarnya dalam file data.

Tapi pertama-tama, kita perlu memasukkan data ke dalam kolom kita.

Masukkan data:

DECLARE @thedatetime2 datetime2 = '2025-05-21 10:15:30.5554444';
INSERT INTO Datetime2vsDatetime ( TheDateTime, TheDateTime2 )
SELECT @thedatetime2, @thedatetime2;

Pilih data (hanya untuk memeriksanya):

SELECT * FROM Datetime2vsDatetime;

Hasil:

+-------------------------+-------------------------+
| TheDateTime             | TheDateTime2            |
|-------------------------+-------------------------|
| 2025-05-21 10:15:30.557 | 2025-05-21 10:15:30.555 |
+-------------------------+-------------------------+

Menggunakan DBCC PAGE()

Di sinilah kami menggunakan DBCC PAGE() untuk memeriksa halaman sebenarnya dalam file data.

Pertama, kita akan menggunakan DBCC IND() untuk menemukan PagePID:

DBCC IND('CompareTypes', 'dbo.Datetime2vsDatetime', 0);

Hasil (menggunakan keluaran vertikal):

-[ RECORD 1 ]-------------------------
PageFID         | 1
PagePID         | 307
IAMFID          | NULL
IAMPID          | NULL
ObjectID        | 885578193
IndexID         | 0
PartitionNumber | 1
PartitionID     | 72057594042974208
iam_chain_type  | In-row data
PageType        | 10
IndexLevel      | NULL
NextPageFID     | 0
NextPagePID     | 0
PrevPageFID     | 0
PrevPagePID     | 0
-[ RECORD 2 ]-------------------------
PageFID         | 1
PagePID         | 320
IAMFID          | 1
IAMPID          | 307
ObjectID        | 885578193
IndexID         | 0
PartitionNumber | 1
PartitionID     | 72057594042974208
iam_chain_type  | In-row data
PageType        | 1
IndexLevel      | 0
NextPageFID     | 0
NextPagePID     | 0
PrevPageFID     | 0
PrevPagePID     | 0

Ini mengembalikan dua catatan. Kami tertarik dengan PageType dari 1 (catatan ke-2). Kami ingin PagePID dari catatan itu. Dalam hal ini PagePID adalah 320 .

Sekarang kita dapat mengambil PagePID itu dan menggunakannya sebagai berikut:

DBCC TRACEON(3604, -1);
DBCC PAGE(CompareTypes, 1, 320, 3);

Ini menghasilkan banyak data, tetapi kami terutama tertarik pada bagian berikut:

Slot 0 Column 1 Offset 0x4 Length 8 Length (physical) 8

TheDateTime = 2025-05-21 10:15:30.557                                    

Slot 0 Column 2 Offset 0xc Length 7 Length (physical) 7

TheDateTime2 = 2025-05-21 10:15:30.555                                    

Ini menunjukkan bahwa waktu-tanggal menggunakan panjang 8 byte dan datetime2(3) menggunakan 7 byte saat disimpan dalam database.

Jadi ini memperkuat kasus untuk menggunakan datetime2 melebihi waktu kencan saat merancang database baru, terutama jika ukuran penyimpanan menjadi perhatian.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apa tipe data SYSNAME di SQL Server?

  2. Cara Memasukkan String ke String lain di SQL Server menggunakan STUFF()

  3. Urutan Bersyarat T-SQL Oleh

  4. Tipe data untuk menyimpan alamat ip di SQL Server

  5. Bisakah SQL Server mengirim permintaan web?