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

UTF-8 समर्थन, SQL सर्वर 2012 और UTF8String UDT

SQLCLR के माध्यम से एक कस्टम उपयोगकर्ता-परिभाषित प्रकार बनाना नहीं है , किसी भी तरह से, आपको किसी भी देशी प्रकार का प्रतिस्थापन दिलाने जा रहा है। विशेष डेटा को संभालने के लिए कुछ बनाने के लिए यह बहुत आसान है। लेकिन स्ट्रिंग्स, यहां तक ​​​​कि एक अलग एन्कोडिंग के भी, विशेष से बहुत दूर हैं। अपने स्ट्रिंग डेटा के लिए इस मार्ग पर जाने से आपके सिस्टम की उपयोगिता की कोई भी मात्रा नष्ट हो जाएगी, प्रदर्शन का उल्लेख नहीं करने के लिए क्योंकि आप किसी भी का उपयोग करने में सक्षम नहीं होंगे। अंतर्निहित स्ट्रिंग फ़ंक्शन।

यदि आप डिस्क स्थान पर कुछ भी बचाने में सक्षम थे, तो उन लाभों को मिटा दिया जाएगा जो आप समग्र प्रदर्शन में खो देंगे। UDT को एक VARBINARY . पर क्रमांकित करके संग्रहीत किया जाता है . तो कोई भी करने के लिए स्ट्रिंग तुलना या छँटाई, एक "बाइनरी" / "ऑर्डिनल" तुलना के बाहर, आपको अन्य सभी मानों को एक-एक करके, वापस UTF-8 में बदलना होगा, फिर स्ट्रिंग तुलना करें जो भाषाई अंतरों का हिसाब कर सकती है। और उस रूपांतरण को यूडीटी के भीतर करने की आवश्यकता होगी। इसका मतलब यह है कि, एक्सएमएल डेटाटाइप की तरह, आप एक विशेष मान रखने के लिए यूडीटी बनाएंगे, और उसके बाद तुलना करने के लिए स्ट्रिंग पैरामीटर को स्वीकार करने के लिए उस यूडीटी की एक विधि का पर्दाफाश करेंगे (यानी Utf8String.Compare(alias.field1) या, यदि प्रकार के लिए एक ऑपरेटर को परिभाषित करते हैं, तो Utf8string1 = Utf8string2 और = . है ऑपरेटर को UTF-8 एन्कोडिंग में स्ट्रिंग मिलती है और फिर CompareInfo.Compare() )।

उपरोक्त विचारों के अतिरिक्त, आपको यह भी विचार करना होगा कि SQLCLR API के माध्यम से आगे और पीछे गुजरने वाले मूल्यों की लागत है, खासकर NVARCHAR(MAX) का उपयोग करते समय या VARBINARY(MAX) NVARCHAR(1 - 4000) . के विपरीत और VARBINARY(1 - 4000) क्रमशः (SqlChars . का उपयोग करने के बारे में कुछ भी कहने के रूप में कृपया इस अंतर को भ्रमित न करें / SqlBytes बनाम SqlString / SqlBinary )।

अंत में (कम से कम यूडीटी का उपयोग करने के मामले में), कृपया इस तथ्य पर ध्यान न दें कि जिस यूडीटी के बारे में पूछताछ की जा रही है वह नमूना कोड है . नोट किया गया एकमात्र परीक्षण विशुद्ध रूप से कार्यात्मक है, स्केलेबिलिटी या "एक साल तक इसके साथ काम करने के बाद सीखे गए सबक" के आसपास कुछ भी नहीं है। कार्यात्मक परीक्षण कोड यहां निम्नलिखित कोडप्लेक्स पृष्ठ पर दिखाया गया है और इस निर्णय के साथ आगे बढ़ने से पहले इसे देखा जाना चाहिए क्योंकि इससे यह पता चलता है कि इसके साथ बातचीत करने के लिए आपको अपने प्रश्नों को कैसे लिखना होगा (जो किसी क्षेत्र के लिए ठीक है या दो, लेकिन नहीं अधिकांश/सभी स्ट्रिंग फ़ील्ड के लिए):

http://msftengprodsamples.codeplex.com /SourceControl/latest#Kilimanjaro_Trunk/Programmability/CLR/UTF8String/Scripts/Test.sql

जोड़े गए लगातार गणना किए गए कॉलम और इंडेक्स की संख्या को देखते हुए, क्या कोई स्थान वास्तव में सहेजा गया था?;-)

जहां स्थान (डिस्क, मेमोरी, आदि) चिंता का विषय है, आपके पास तीन विकल्प हैं:

  1. यदि आप SQL Server 2008 या नए का उपयोग कर रहे हैं, और एंटरप्राइज़ संस्करण पर हैं, तो आप डेटा संपीड़न . डेटा संपीड़न (लेकिन "हमेशा" नहीं होगा") यूनिकोड डेटा को NCHAR . में संपीड़ित कर सकता है और NVARCHAR खेत। निर्धारण कारक हैं:

    1. NCHAR(1 - 4000) और NVARCHAR(1 - 4000) यूनिकोड के लिए मानक संपीड़न योजना का उपयोग करें , लेकिन केवल SQL Server 2008 R2 में शुरू हो रहा है, और केवल IN ROW डेटा के लिए, ओवरफ्लो नहीं! यह नियमित ROW / PAGE संपीड़न एल्गोरिथम से बेहतर प्रतीत होता है।
    2. NVARCHAR(MAX) और XML (और मुझे लगता है VARBINARY(MAX) . भी , TEXT , और NTEXT ) डेटा जो ROW में है (LOB या OVERFLOW पेज में ऑफ रो नहीं) कम से कम PAGE कंप्रेस किया जा सकता है, और शायद ROW कंप्रेस्ड भी (इस आखिरी के बारे में निश्चित नहीं है)।
    3. कोई भी बंद पंक्ति डेटा, LOB या OVERLOW =आपके लिए कोई संपीड़न नहीं!
  2. यदि 2008 से पुराने संस्करण का उपयोग कर रहे हैं या एंटरप्राइज़ संस्करण पर नहीं हैं, तो आपके पास दो फ़ील्ड हो सकते हैं:एक VARCHAR और एक NVARCHAR . उदाहरण के लिए, मान लें कि आप ऐसे URL संग्रहीत कर रहे हैं जो अधिकतर ASCII वर्ण (मान 0 - 127) हैं और इसलिए VARCHAR में फिट होते हैं , लेकिन कभी-कभी यूनिकोड वर्ण होते हैं। आपकी स्कीमा में निम्नलिखित 3 फ़ील्ड शामिल हो सकते हैं:

      ...
      URLa VARCHAR(2048) NULL,
      URLu NVARCHAR(2048) NULL,
      URL AS (ISNULL(CONVERT(NVARCHAR([URLa])), [URLu])),
      CONSTRAINT [CK_TableName_OneUrlMax] CHECK (
                        ([URLa] IS NOT NULL OR [URLu] IS NOT NULL)
                    AND ([URLa] IS NULL OR [URLu] IS NULL))
    );
    

    इस मॉडल में आप केवल [URL] में से चुनें गणना कॉलम। सम्मिलित करने और अद्यतन करने के लिए, आप यह देखकर निर्धारित करते हैं कि किस क्षेत्र का उपयोग करना है, यह देखकर कि आने वाले मूल्य में परिवर्तन होता है, जो कि NVARCHAR का होना चाहिए। टाइप करें:

    INSERT INTO TableName (..., URLa, URLu)
    VALUES (...,
            IIF (CONVERT(VARCHAR(2048), @URL) = @URL, @URL, NULL),
            IIF (CONVERT(VARCHAR(2048), @URL) <> @URL, NULL, @URL)
           );
    
  3. यदि आपके पास ऐसे फ़ील्ड हैं जिनमें केवल ऐसे वर्ण होने चाहिए जो किसी विस्तारित ASCII वर्ण सेट के किसी विशेष कोड पृष्ठ में फ़िट हों, तो बस VARCHAR का उपयोग करें ।

पी.एस. स्पष्टता के लिए यह कहने के लिए:नया _SC SQL सर्वर 2012 में पेश किए गए कोलाज केवल इसके लिए अनुमति देते हैं:

  • सप्लीमेंट्री कैरेक्टर / सरोगेट पेयर को ठीक से हैंडल करने के लिए बिल्ट-इन फंक्शन, और
  • सप्लीमेंट्री कैरेक्टर के लिए भाषाई नियम जिनका इस्तेमाल ऑर्डर देने और तुलना करने के लिए किया जाता है

लेकिन, नए _SC के बिना भी Collations, आप अभी भी किसी भी यूनिकोड वर्ण को XML या N . में संग्रहीत कर सकते हैं -prefixed प्रकार, और इसे बिना किसी डेटा हानि के पुनर्प्राप्त करें। हालाँकि, पुराने Collations (अर्थात नाम में कोई संस्करण संख्या नहीं) का उपयोग करते समय, सभी पूरक वर्ण एक दूसरे के समान होते हैं। आपको _90 . का उपयोग करना होगा और _100 Collations जो आपको कम से कम बाइनरी/कोड पॉइंट तुलना और सॉर्टिंग प्राप्त करते हैं; वे भाषाई नियमों को ध्यान में नहीं रख सकते क्योंकि उनके पास पूरक वर्णों की कोई विशेष मैपिंग नहीं है (और इसलिए कोई वज़न या सामान्यीकरण नियम नहीं हैं)।

निम्न का प्रयास करें:

IF (N'𤪆' = N'𤪆') SELECT N'𤪆' AS [TheLiteral], NCHAR(150150) AS [Generated];
IF (N'𤪆' = N'𤪇') SELECT N'𤪇' AS [TheLiteral], NCHAR(150151) AS [Generated];
IF (N'𤪆' COLLATE Tatar_90_CI_AI = N'𤪇' COLLATE Tatar_90_CI_AI)
       SELECT N'𤪇 COLLATE Tatar_90_CI_AI' AS [TheLiteral], NCHAR(150151) AS [Generated];
IF (N'𤪆' = N'?') SELECT N'?';

एक डीबी में _SC . में समाप्त होने वाला डिफ़ॉल्ट संयोजन होता है , केवल पहला IF स्टेटमेंट एक परिणाम सेट लौटाएगा, और "जेनरेट" फ़ील्ड वर्णों को सही ढंग से दिखाएगा।

लेकिन, अगर डीबी में _SC . में समाप्त होने वाला डिफ़ॉल्ट संयोजन नहीं है , और संयोजन एक _90 नहीं है या _100 श्रृंखला संयोजन, फिर पहले दो IF स्टेटमेंट रिटर्न रिजल्ट सेट जिसमें "जेनरेटेड" फील्ड NULL लौटाएगा , और "शाब्दिक" फ़ील्ड सही ढंग से दिखाई देता है।

यूनिकोड डेटा के लिए, Collation का भौतिक संग्रहण पर कोई प्रभाव नहीं पड़ता है।

अद्यतन 2018-10-02

हालांकि यह अभी तक एक व्यवहार्य विकल्प नहीं है, SQL सर्वर 2019 VARCHAR में UTF-8 के लिए मूल समर्थन पेश करता है / CHAR डेटा के प्रकार। वर्तमान में इसके उपयोग के लिए इसके साथ बहुत अधिक बग हैं, लेकिन यदि उन्हें ठीक कर दिया गया है, तो यह कुछ के लिए एक विकल्प है। परिदृश्य कृपया मेरी पोस्ट देखें, "मूल UTF-8 SQL सर्वर 2019 में समर्थन:उद्धारकर्ता या झूठा पैगंबर? ", इस नई सुविधा के विस्तृत विश्लेषण के लिए।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ExecuteNonQuery रिटर्न -1

  2. पैरामीटरयुक्त गतिशील एसक्यूएल क्वेरी

  3. SQL सर्वर में पिछली पंक्ति के साथ वर्तमान पंक्ति की तुलना करें

  4. समय प्रारूप hhmm से hh:mm sql सर्वर 2005

  5. एमएस एक्सेस वीबीए ट्रैपिंग एसक्यूएल सर्वर कनेक्शन त्रुटि