2013-08-13 5 views
11

पिछले 3 सालों से डेटटाइम कॉलम और विभिन्न तिथियों (स्थानीय समय पीएसटी मूल्यों) की लगभग 100k पंक्तियों के साथ एक SQL तालिका को देखते हुए, उन कॉलम मानों को DateTimeOffset पर माइग्रेट करने के लिए सबसे अच्छी रणनीति क्या है जो अनुपलब्ध utc tz ऑफ़सेट "add" जानकारी?एसक्यूएल संग्रहीत डेटटाइम मानों को डेटटाइम ऑफसेट सर्वोत्तम अभ्यास में माइग्रेट करना?

मौजूदा डेटटाइम मान किसी भी समय क्षेत्र/यूटीसी ऑफ़सेट विवरण के बिना संग्रहीत किए गए हैं। संग्रहीत तिथियां हमेशा प्रशांत समय (-800 या -700 डेलाइट सेविंग टाइम के आधार पर) के प्रतिनिधि हैं। लक्ष्य पूर्वव्यापी प्रभाव से जोड़ने के लिए इस धारणा के साथ सभी मौजूदा डेटा उस तारीख प्रशांत समय से आया ऑफसेट TZ है (जो सही ऑफसेट पल तारीख द्वारा निर्दिष्ट पर था)

  • एसक्यूएल के भीतर क्या सबसे अच्छा अभ्यास है किसी भी डेटा को खोए बिना, या मौजूदा मूल्यों को बदलने के बिना माइग्रेशन के इस प्रकार के लिए?

  • इसे अगले चरण में ले जाना, डेटटाइम ऑफसेट कॉलम और मानों का उपयोग करने के लिए एक मध्यम आकार (~ 100gb ~ 100 तालिकाओं में ~ 100 तालिकाओं में प्रति तालिका कॉलम के साथ 100 फ़ील्ड) को माइग्रेट करने का सबसे प्रभावी तरीका क्या है?

  • पीएसटी/पीडीटी परिवर्तन तिथि पर 2 बजे के आसपास लॉग इन किए गए डेटाटाइम का क्या होता है? क्या कोई डेटा हानि होती है?

एसक्यूएल सर्वर 2008 + सी # 4.5

यदि यह सही क्षेत्र नहीं है तो कृपया मुझे सही दिशा में बात है, धन्यवाद!

संपादित करें: हाँ, बक्षीस समय।

+1

बस 'वह लड़का' होने के नाते, लेकिन मैं वास्तव में 100 जीबी को एक साधारण आकार के डीबी नहीं कहूंगा, जो वास्तव में काफी बड़ा है। –

उत्तर

5

डेलाइट बचत हमेशा एक सटीक विज्ञान नहीं है। जैसे उत्तर अमेरिका में उपयोग की जाने वाली अवधि के लिए rule change in 2007 था। इस कारण से, प्रासंगिक तिथियों के साथ एक तालिका populating सुझाव होगा। जैसे 2000-2013 के लिए:

-- Populate a table with PST daylight saving start/end times 
-- Example data for 2000-2013 - sourced from 
-- http://www.timeanddate.com/worldclock/timezone.html?n=137 
CREATE TABLE dst (start DateTime, [end] DateTime); 
INSERT INTO dst (start, [end]) VALUES ('02:00 2 Apr 2000', '02:00 29 Oct 2000'); 
INSERT INTO dst (start, [end]) VALUES ('02:00 1 Apr 2001', '02:00 28 Oct 2001'); 
INSERT INTO dst (start, [end]) VALUES ('02:00 7 Apr 2002', '02:00 27 Oct 2002'); 
INSERT INTO dst (start, [end]) VALUES ('02:00 6 Apr 2003', '02:00 26 Oct 2003'); 
INSERT INTO dst (start, [end]) VALUES ('02:00 4 Apr 2004', '02:00 31 Oct 2004'); 
INSERT INTO dst (start, [end]) VALUES ('02:00 3 Apr 2005', '02:00 30 Oct 2005'); 
INSERT INTO dst (start, [end]) VALUES ('02:00 2 Apr 2006', '02:00 29 Oct 2006'); 
INSERT INTO dst (start, [end]) VALUES ('02:00 11 Apr 2007', '02:00 4 Oct 2007'); 
INSERT INTO dst (start, [end]) VALUES ('02:00 9 Apr 2008', '02:00 2 Nov 2008'); 
INSERT INTO dst (start, [end]) VALUES ('02:00 8 Apr 2009', '02:00 1 Nov 2009'); 
INSERT INTO dst (start, [end]) VALUES ('02:00 14 Apr 2010', '02:00 7 Nov 2010'); 
INSERT INTO dst (start, [end]) VALUES ('02:00 13 Apr 2011', '02:00 6 Nov 2011'); 
INSERT INTO dst (start, [end]) VALUES ('02:00 11 Apr 2012', '02:00 4 Nov 2012'); 
INSERT INTO dst (start, [end]) VALUES ('02:00 10 Apr 2013', '02:00 3 Nov 2013'); 
बेशक

आप एक बहुत इस से अधिक आवश्यकता हो सकती है - कर रही है कि :-)

ठीक पाठक के लिए एक व्यायाम है, तो के रूप में मान लीजिए कि आप आबादी जाने छोड़ देंगे तालिका के ऊपर पूरी संभव सीमा के साथ और आपके पास dt तालिका test फ़ील्ड में दिनांक/समय है। तो फिर तुम इस तरह उपरोक्त तालिका में शामिल हो सकते हैं और जल्दी रूपांतरण:

-- Convert sample dates to PST offset with daylight saving where appropriate 
SELECT test.dt, 
     CAST(CONVERT(VARCHAR(23), test.dt, 126) + -- Convert to ISO8601 format 
      CASE WHEN dst.start IS NULL 
       THEN '-08:00' -- No record joined so not within DST period 
       ELSE '-07:00' -- DST record joined so is within DST period 
      END AS DateTimeOffset) AS dto 
FROM test 
LEFT JOIN dst -- Join on daylight savings table to find out whether DST applies 
ON test.dt >= dst.start 
AND test.dt <= dst.[end] 

यहाँ एक SQL fiddle demo है।

2

एसक्यूएल सर्वर 2016 ने इस तरह की समस्याओं को हल करने के लिए टी-एसक्यूएल सिंटैक्स AT TIME ZONE पेश किया।

तो अगर आप डेटा के समय क्षेत्र पता है, तुम भी जोड़ सकते हैं एक सरल बदलने और अद्यतन स्क्रिप्ट के रूप में नीचे दिखाया गया है का उपयोग कर ऑफसेट (यह मानते हुए आप DateTimeColumn नाम के एक datetime2 स्तंभ होने MyTable नाम के एक मेज है):

alter table MyTable 
    alter column DateTimeColumn datetimeoffset; 

update Mytable 
    set DateTimeColumn = convert(datetime2, DateTimeColumn) AT TIME ZONE 'Pacific Standard Time' 

डेलाइट सेविंग टाइम (डीएसटी) माना जाता है और कोई डेटा हानि नहीं होनी चाहिए।

(मुझे ओपी निर्दिष्ट एसक्यूएल सर्वर 2008 पता है और सवाल पूछा गया था और बहुत समय पहले जवाब दिया गया था, लेकिन उम्मीद है कि वर्तमान में किसी भी तरह की समस्या से जूझ रहे किसी भी व्यक्ति को इस उत्तर से मदद मिलेगी।)

संबंधित मुद्दे