Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

SQL सर्वर में डेटाटाइम 2 बनाम स्मालडेटाटाइम:क्या अंतर है?

यह लेख datetime2 . के बीच मुख्य अंतरों की पड़ताल करता है और स्मॉलडेटटाइम SQL सर्वर में डेटा प्रकार।

दोनों डेटा प्रकार दिनांक और समय मानों को संग्रहीत करने के लिए उपयोग किए जाते हैं, हालांकि, दोनों के बीच कुछ महत्वपूर्ण अंतर हैं। ज़्यादातर मामलों में बेहतर होगा कि आप datetime2 . का उपयोग करें (Microsoft भी इसकी अनुशंसा करता है), हालाँकि कुछ ऐसे परिदृश्य हो सकते हैं जहाँ आपको smalldatetime का उपयोग करने की आवश्यकता हो .

यहां एक तालिका है जो इन दो प्रकारों के बीच महत्वपूर्ण अंतरों को रेखांकित करती है।

<वें शैली ="चौड़ाई:40%;">छोटे दिनांक समय <वें शैली="चौड़ाई:40%;">डेटाटाइम2 . तक
सुविधा
एसक्यूएल कम्प्लायंट (एएनएसआई और आईएसओ 8601) नहीं हां
तारीख सीमा 1900-01-01 से 2079-06-06 तक 0001-01-01 9999-12-31 तक
समय सीमा 00:00:00 से 23:59:5900:00:00 23:59:59.99999999 तक
चरित्र की लंबाई अधिकतम 19 स्थान न्यूनतम 19 स्थान
अधिकतम 27
भंडारण आकार 4 बाइट्स, फिक्स्ड 6 से 8 बाइट्स, सटीकता पर निर्भर करता है*

* शुद्धता को स्टोर करने के लिए प्लस 1 बाइट

सटीकता एक मिनट 100 नैनोसेकंड
आंशिक दूसरी सटीकता नहीं हां
उपयोगकर्ता द्वारा परिभाषित भिन्नात्मक दूसरी परिशुद्धता नहीं हां
समय क्षेत्र ऑफसेट कोई नहीं कोई नहीं
समय क्षेत्र ऑफसेट जागरूक और संरक्षण नहीं नहीं
डेलाइट सेविंग अवेयर नहीं नहीं

'डेटाटाइम2' के फ़ायदे

जैसा कि उपरोक्त तालिका में देखा गया है, datetime2 टाइप के स्मॉलडेटटाइम . की तुलना में कई फायदे हैं , सहित:

  • बड़ी तिथि सीमा
  • आंशिक सेकंड सटीक
  • वैकल्पिक उपयोगकर्ता-निर्दिष्ट सटीकता
  • उच्च सटीकता
  • एसक्यूएल मानकों (एएनएसआई और आईएसओ 8601) के साथ संरेखित करता है

* कुछ मामलों में datetime2 मूल्य सटीकता को संग्रहीत करने के लिए एक अतिरिक्त बाइट का उपयोग करता है, हालांकि जब डेटाबेस में संग्रहीत किया जाता है, तो सटीक को कॉलम परिभाषा में शामिल किया जाता है, इसलिए वास्तविक संग्रहीत मूल्य को अतिरिक्त बाइट की आवश्यकता नहीं होती है।

क्या मुझे 'डेटाटाइम' या 'स्मॉलडेटटाइम' का इस्तेमाल करना चाहिए?

Microsoft अनुशंसा करता है datetime2 नए काम के लिए (और ऊपर सूचीबद्ध उन्हीं कारणों से)।

इसलिए, आपको datetime2 . का उपयोग करना चाहिए , जब तक कि आपके पास न करने का कोई विशिष्ट कारण न हो (जैसे कि किसी लीगेसी सिस्टम के साथ काम करना)।

उदाहरण 1 - मूल तुलना

datetime2 . के बीच मूलभूत अंतर को प्रदर्शित करने के लिए यहां एक त्वरित उदाहरण दिया गया है और स्मॉलडेटटाइम

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

परिणाम:

+-----------------------------+---------------------+
| datetime2                   | smalldatetime       |
|-----------------------------+---------------------|
| 2025-05-21 10:15:30.5555555 | 2025-05-21 10:16:00 |
+-----------------------------+---------------------+

यहां, मैंने एक स्मॉलडेटटाइम . सेट किया है datetime2 . के समान मान के लिए परिवर्तनीय चर। यह मान को स्मॉलडेटटाइम . में कनवर्ट करने का कारण बनता है और फिर हम एक SELECT . का उपयोग कर सकते हैं प्रत्येक चर के मूल्य को देखने के लिए कथन।

इस मामले में, datetime2 चर 7 के पैमाने का उपयोग करता है, जिसका अर्थ है कि इसमें 7 दशमलव स्थान हैं। स्मॉलडेटटाइम दूसरी ओर, मान कोई नहीं है दशमलव स्थानों। इसके अलावा, इसके सेकंड शून्य पर सेट होते हैं, और इसके मिनट गोल किए जाते हैं।

यह अपेक्षित है, क्योंकि माइक्रोसॉफ्ट के आधिकारिक दस्तावेज में कहा गया है कि smalldatetime इसका समय 24 घंटे के दिन पर आधारित होता है, जिसमें सेकंड हमेशा शून्य (:00) और बिना आंशिक सेकंड के होते हैं .

तो हम देख सकते हैं कि datetime2 प्रकार अधिक सटीक और सटीक दिनांक/समय मान प्रदान करता है।

बेशक, आपको उन सभी भिन्नात्मक सेकंड की आवश्यकता नहीं हो सकती है। datetime2 . के बारे में अच्छी बातों में से एक यह है कि आप निर्दिष्ट कर सकते हैं कि आप कितने (यदि कोई हो) भिन्नात्मक सेकंड चाहते हैं।

उदाहरण 2 - कम दशमलव स्थानों का उपयोग करना

इस उदाहरण में मैं datetime2 . को कम करता हूं 0 के पैमाने पर:

DECLARE 
  @thedatetime2 datetime2(0), 
  @thesmalldatetime smalldatetime;
SET @thedatetime2 = '2025-05-21 10:15:30.5555555';
SET @thesmalldatetime = @thedatetime2;
SELECT 
  @thedatetime2 AS 'datetime2',
  @thesmalldatetime AS 'smalldatetime';

परिणाम:

+---------------------+---------------------+
| datetime2           | smalldatetime       |
|---------------------+---------------------|
| 2025-05-21 10:15:31 | 2025-05-21 10:16:00 |
+---------------------+---------------------+

इस मामले में, datetime2 मान में अब भिन्नात्मक भाग शामिल नहीं है। दोनों प्रकार अब समान वर्ण लंबाई (19 स्थिति) साझा करते हैं।

लेकिन अभी भी मतभेद हैं।

डेटाटाइम2 मान सेकंड मान का सम्मान करता है, हालांकि इस मामले में इसके सेकंड को गोल कर दिया गया है। जैसा कि बताया गया है, स्मॉलडेटटाइम मान का सेकंड घटक हमेशा शून्य पर सेट होता है, और इस मामले में, इसके मिनटों को गोल कर दिया गया है।

कारण datetime2 सेकंड घटक को गोल किया जाता है क्योंकि भिन्नात्मक भाग 5 या उच्चतर होता है। यदि हम भिन्नात्मक भाग को कम करते हैं, तो कोई गोलाई नहीं की जाती है:

DECLARE 
  @thedatetime2 datetime2(0), 
  @thesmalldatetime smalldatetime;
SET @thedatetime2 = '2025-05-21 10:15:30.4444444';
SET @thesmalldatetime = @thedatetime2;
SELECT 
  @thedatetime2 AS 'datetime2',
  @thesmalldatetime AS 'smalldatetime';

परिणाम:

+---------------------+---------------------+
| datetime2           | smalldatetime       |
|---------------------+---------------------|
| 2025-05-21 10:15:30 | 2025-05-21 10:16:00 |
+---------------------+---------------------+

हालांकि, स्मॉलडेटटाइम वैल्यू मिनट्स को राउंड अप करना जारी है।

उदाहरण 3 - स्ट्रिंग लिटरल्स से मान सेट करना

पिछले उदाहरणों में, स्मॉलडेटटाइम मान को datetime2 . के समान मान पर सेट करके असाइन किया गया था मूल्य। जब हम ऐसा करते हैं, तो SQL सर्वर डेटा को नए डेटा प्रकार को "फिट" करने के लिए एक अंतर्निहित रूपांतरण करता है।

हालांकि, अगर हम उसी स्ट्रिंग को smalldatetime . को शाब्दिक रूप से असाइन करने का प्रयास करते हैं चर, हमें एक त्रुटि मिलती है:

DECLARE 
  @thedatetime2 datetime2(0), 
  @thesmalldatetime smalldatetime
SET @thedatetime2 = '2025-05-21 10:15:30.4444444'
SET @thesmalldatetime = '2025-05-21 10:15:30.4444444'
SELECT 
  @thedatetime2 AS 'datetime2',
  @thesmalldatetime AS 'smalldatetime';

परिणाम:

Msg 295, Level 16, State 3, Line 5
Conversion failed when converting character string to smalldatetime data type.

ऐसा इसलिए है क्योंकि स्मॉलडेटटाइम केवल स्ट्रिंग अक्षर स्वीकार करता है जिसमें 3 या उससे कम आंशिक सेकंड होते हैं।

आप उम्मीद कर सकते हैं कि यह किसी भी . के साथ स्ट्रिंग अक्षर को स्वीकार नहीं करेगा भिन्नात्मक सेकंड, यह देखते हुए कि इसमें भिन्नात्मक सेकंड शामिल नहीं हैं, लेकिन ऐसा नहीं है। यह खुशी-खुशी 3 भिन्न सेकंड स्वीकार करता है, लेकिन अब और नहीं।

इसलिए इस समस्या को दूर करने के लिए, हमें भिन्नात्मक भाग को केवल 3 (या कम) दशमलव स्थानों तक कम करने की आवश्यकता है।

DECLARE 
  @thedatetime2 datetime2(0), 
  @thesmalldatetime smalldatetime;
SET @thedatetime2 = '2025-05-21 10:15:30.4444444';
SET @thesmalldatetime = '2025-05-21 10:15:30.444';
SELECT 
  @thedatetime2 AS 'datetime2',
  @thesmalldatetime AS 'smalldatetime';

परिणाम:

+---------------------+---------------------+
| datetime2           | smalldatetime       |
|---------------------+---------------------|
| 2025-05-21 10:15:30 | 2025-05-21 10:16:00 |
+---------------------+---------------------+

डेटाटाइम2 0 के पैमाने का उपयोग करते समय भी type में यह सीमा नहीं होती है।

उदाहरण 4 - संग्रहण आकार

स्मॉलडेटटाइम डेटा प्रकार में 4 बाइट्स का एक निश्चित भंडारण आकार होता है। यह कुछ लाभों में से एक है smalldatetime datetime2 . से अधिक है ।

डेटाटाइम2 इसकी शुद्धता के आधार पर, 6, 7, या 8 बाइट्स हो सकते हैं। तो एक डेटाटाइम2 value हमेशा स्मॉलडेटटाइम . की तुलना में कम से कम 2 बाइट अधिक संग्रहण का उपयोग करेगा मूल्य।

Microsoft बताता है कि datetime2 type अपनी सटीकता को संग्रहीत करने के लिए 1 अतिरिक्त बाइट का भी उपयोग करता है, इस स्थिति में यह smalldatetime से कम से कम 3 बाइट अधिक का उपयोग करेगा। ।

हालाँकि, यह शायद इस बात पर निर्भर करता है कि हम इसे किसी तालिका या चर में संग्रहीत कर रहे हैं, और हम इसे बाइनरी स्थिरांक में परिवर्तित कर रहे हैं या नहीं।

यदि हम DATALENGTH() . का उपयोग करते हैं तो यहां क्या होता है हमारे प्रत्येक मान के लिए उपयोग किए गए बाइट्स की संख्या वापस करने के लिए कार्य करता है:

DECLARE 
  @thedatetime2 datetime2(0), 
  @thesmalldatetime smalldatetime;
SET @thedatetime2 = '2025-05-21 10:15:30';
SET @thesmalldatetime = @thedatetime2;
SELECT 
  DATALENGTH(@thedatetime2) AS 'datetime2',
  DATALENGTH(@thesmalldatetime) AS 'smalldatetime';

परिणाम

+-------------+-----------------+
| datetime2   | smalldatetime   |
|-------------+-----------------|
| 6           | 4               |
+-------------+-----------------+

लेकिन अगर हम उन्हें varbinary . में बदल दें , हम निम्नलिखित प्राप्त करते हैं:

DECLARE 
  @thedatetime2 datetime2(0), 
  @thesmalldatetime smalldatetime;
SET @thedatetime2 = '2025-05-21 10:15:30';
SET @thesmalldatetime = @thedatetime2;
SELECT 
  DATALENGTH(CAST(@thedatetime2 AS varbinary(10))) AS 'datetime2',
  DATALENGTH(CAST(@thesmalldatetime AS varbinary(10))) AS 'smalldatetime';

परिणाम

+-------------+-----------------+
| datetime2   | smalldatetime   |
|-------------+-----------------|
| 7           | 4               |
+-------------+-----------------+

तो डेटाटाइम2 varbinary . में परिवर्तित होने पर एक अतिरिक्त बाइट का उपयोग करता है . कई डेवलपर मानते हैं कि varbinary . में कनवर्ट करना यह प्रतिनिधि है कि SQL सर्वर वास्तव में दिनांक और समय मानों को कैसे संग्रहीत करता है।

हालांकि यह केवल आंशिक रूप से सच है। हालांकि यह सच है कि SQL सर्वर अपने दिनांक और समय मानों को हेक्साडेसिमल में संग्रहीत करता है, लेकिन उस हेक्स मान में वास्तव में सटीकता शामिल नहीं होती है। ऐसा इसलिए है क्योंकि सटीक कॉलम परिभाषा में शामिल है। लेकिन जब हम varbinary . में कनवर्ट करते हैं जैसा कि हमने पिछले उदाहरण में किया था, परिशुद्धता पहले से तैयार है, और यह एक अतिरिक्त बाइट जोड़ता है।

निम्नलिखित उदाहरण इसे प्रदर्शित करता है। यह दर्शाता है कि जब डेटा डेटाबेस कॉलम में संग्रहीत किया जाता है, तो हमें datetime2 के लिए 6 बाइट्स की लंबाई मिलती है बनाम 4 बाइट्स स्मॉलडेटटाइम . के लिए ।

उदाहरण 5 - संग्रहीत डेटा के लिए संग्रहण आकार

इस उदाहरण में, मैं एक डेटाबेस बनाता हूं और COL_LENGTH . का उपयोग करता हूं प्रत्येक कॉलम की लंबाई, बाइट्स में वापस करने के लिए। फिर मैं एक डेटाटाइम2 . सम्मिलित करता हूं और स्मॉलडेटटाइम इसमें मूल्य दें और DBCC PAGE() . का उपयोग करें पृष्ठ फ़ाइल में वास्तविक डेटा की लंबाई खोजने के लिए। यह हमें वह संग्रहण स्थान दिखाता है जिसका उपयोग प्रत्येक डेटा प्रकार डेटाबेस में संग्रहीत करते समय करता है।

एक डेटाबेस बनाएं:

CREATE DATABASE CompareTypes;

एक टेबल बनाएं:

USE CompareTypes;

CREATE TABLE Datetime2vsSmalldatetime (
    TheDateTime2 datetime2(0),
    TheSmallDateTime smalldatetime
    );

इस मामले में मैं दो कॉलम बनाता हूं - एक है datetime2(0) कॉलम और दूसरा एक छोटा डेटाटाइम . है कॉलम।

कॉलम की लंबाई जांचें

प्रत्येक कॉलम की लंबाई (बाइट्स में) जांचें:

SELECT 
  COL_LENGTH ( 'dbo.Datetime2vsSmalldatetime' , 'TheDateTime2' ) AS 'datetime2',
  COL_LENGTH ( 'dbo.Datetime2vsSmalldatetime' , 'TheSmallDateTime' ) AS 'smalldatetime';  

परिणाम:

+-------------+-----------------+
| datetime2   | smalldatetime   |
|-------------+-----------------|
| 6           | 4               |
+-------------+-----------------+

तो हम देखते हैं कि datetime2(0) स्मॉलडेटटाइम . की तुलना में कॉलम की लंबाई 6 बाइट्स है 4 बाइट्स की लंबाई।

डेटा डालें

अब वास्तविक दिनांक और समय मानों के संग्रहण आकार को देखते हैं जब वे SQL सर्वर में संग्रहीत होते हैं। हम DBCC PAGE() use का उपयोग कर सकते हैं डेटा फ़ाइल में वास्तविक पृष्ठ का निरीक्षण करने के लिए।

लेकिन पहले, हमें अपने कॉलम में डेटा डालने की जरूरत है।

डेटा डालें:

DECLARE @thedatetime2 datetime2 = '2025-05-21 10:15:30';
INSERT INTO Datetime2vsSmalldatetime ( TheSmallDateTime, TheDateTime2 )
SELECT @thedatetime2, @thedatetime2;

डेटा चुनें (बस इसे जांचने के लिए):

SELECT * FROM Datetime2vsSmalldatetime;

परिणाम:

+---------------------+---------------------+
| TheDateTime2        | TheSmallDateTime    |
|---------------------+---------------------|
| 2025-05-21 10:15:30 | 2025-05-21 10:16:00 |
+---------------------+---------------------+

डीबीसीसी पेज का उपयोग करना()

यहां हम DBCC PAGE() का उपयोग करते हैं डेटा फ़ाइल में वास्तविक पृष्ठ का निरीक्षण करने के लिए।

सबसे पहले, हम DBCC IND() का उपयोग करेंगे पेजपीआईडी ​​खोजने के लिए:

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

परिणाम (ऊर्ध्वाधर आउटपुट का उपयोग करके):

-[ RECORD 1 ]-------------------------
PageFID         | 1
PagePID         | 308
IAMFID          | NULL
IAMPID          | NULL
ObjectID        | 1205579333
IndexID         | 0
PartitionNumber | 1
PartitionID     | 72057594043039744
iam_chain_type  | In-row data
PageType        | 10
IndexLevel      | NULL
NextPageFID     | 0
NextPagePID     | 0
PrevPageFID     | 0
PrevPagePID     | 0
-[ RECORD 2 ]-------------------------
PageFID         | 1
PagePID         | 344
IAMFID          | 1
IAMPID          | 308
ObjectID        | 1205579333
IndexID         | 0
PartitionNumber | 1
PartitionID     | 72057594043039744
iam_chain_type  | In-row data
PageType        | 1
IndexLevel      | 0
NextPageFID     | 0
NextPagePID     | 0
PrevPageFID     | 0
PrevPagePID     | 0

यह दो रिकॉर्ड देता है। हम 1 के पेज टाइप (दूसरा रिकॉर्ड) में रुचि रखते हैं। हम उस रिकॉर्ड से PagePID चाहते हैं। इस मामले में पेजपीआईडी ​​ 344 . है ।

अब हम उस पेजपीआईडी ​​को ले सकते हैं और इसे निम्नलिखित में उपयोग कर सकते हैं:

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

यह बहुत अधिक डेटा उत्पन्न करता है, लेकिन हम मुख्य रूप से निम्नलिखित भाग में रुचि रखते हैं:

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

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

Slot 0 Column 2 Offset 0xa Length 4 Length (physical) 4

TheSmallDateTime = 2025-05-21 10:16:00.000                                          

इससे पता चलता है कि स्मॉलडेटटाइम 4 बाइट्स की लंबाई है और datetime2(0) डेटाबेस में संग्रहीत होने पर इसमें 6 बाइट्स होते हैं।

तो इस मामले में, केवल 2 बाइट का अंतर है, लेकिन datetime2(0) अधिक सटीक है और एएनएसआई और आईएसओ 8601 मानकों का पालन करता है।


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL सर्वर इंस्टेंस पर सभी डेटाबेस से प्राथमिक कुंजी बाधा की सूची कैसे प्राप्त करें - SQL सर्वर / TSQL ट्यूटोरियल भाग 60

  2. SQL सर्वर में टूटी हुई वस्तुओं का पता लगाएं

  3. जांचें कि क्या तालिका में OBJECTPROPERTY () के साथ SQL सर्वर में एक विदेशी कुंजी है

  4. SQL सर्वर में परिणाम सेट का प्रतिशत लौटाएं

  5. varbinary डेटा को डिस्क में सहेजने के लिए स्क्रिप्ट