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

SQL डेटाबेस में वज़न संग्रहीत करने के लिए सर्वोत्तम अभ्यास?

आप दावा करते हैं कि फ्लोटिंग पॉइंट नंबरों में अंतर्निहित अशुद्धियाँ हैं। मुझे लगता है कि इसे पहले थोड़ा खोजा जाना चाहिए।

अंक प्रणाली पर निर्णय लेते समय एक संख्या का प्रतिनिधित्व करने के लिए (चाहे कागज के टुकड़े पर, कंप्यूटर सर्किट में, या कहीं और), दो अलग हैं विचार करने योग्य मुद्दे:

  1. इसका आधार; और

  2. इसका प्रारूप

आधार चुनें, कोई भी आधार...

सीमित स्थान द्वारा सीमित, कोई अनंत सेट के किसी मनमाने सदस्य का प्रतिनिधित्व नहीं कर सकता . उदाहरण के लिए:आप चाहे कितना भी कागज खरीद लें या आपकी लिखावट कितनी भी छोटी क्यों न हो, एक पूर्णांक खोजना हमेशा संभव होगा जो दिए गए स्थान में फिट नहीं होगा (आप कागज के खत्म होने तक अतिरिक्त अंक जोड़ते रह सकते हैं)। तो, पूर्णांक . के साथ , हम आम तौर पर अपने परिमित स्थान को केवल उन लोगों का प्रतिनिधित्व करने के लिए प्रतिबंधित करते हैं जो किसी विशेष अंतराल के भीतर आते हैं- उदा। यदि हमारे पास धनात्मक/ऋणात्मक चिह्न और तीन अंकों के लिए स्थान है, तो हम स्वयं को अंतराल [-999,+999] तक सीमित कर सकते हैं ।

हर गैर-रिक्त अंतराल वास्तविक संख्याओं का अनंत समुच्चय होता है। दूसरे शब्दों में, कोई फर्क नहीं पड़ता कि कोई भी अंतराल वास्तविक संख्या . पर कब्जा कर लेता है —चाहे वह [-999,+999] . हो , [0,1] , [0.000001,0.000002] या कुछ और—उस अंतराल के भीतर अभी भी वास्तविकताओं का एक अनंत सेट है (किसी को केवल (गैर-शून्य) भिन्नात्मक अंक जोड़ते रहने की आवश्यकता है)! इसलिए मनमाना वास्तविक संख्याएं हमेशा होनी चाहिए किसी ऐसी चीज़ के लिए "गोल" होना जो कर सकते हैं परिमित स्थान में प्रदर्शित किया जा सकता है।

असली संख्याओं का समुच्चय जिसे परिमित स्थान में दर्शाया जा सकता है, उपयोग की जाने वाली अंक प्रणाली पर निर्भर करता है। हमारे (परिचित) positional में आधार-10 सिस्टम, परिमित स्थान एक-आधे के लिए पर्याप्त होगा (0.510 ) लेकिन एक तिहाई के लिए नहीं (0.33333…10 ); इसके विपरीत, (कम परिचित) स्थितीय base-9 में सिस्टम, यह दूसरा तरीका है (वे समान संख्याएँ क्रमशः हैं 0.44444…9 और 0.39 ) इन सबका परिणाम यह है कि कुछ संख्याएँ जिन्हें स्थितिगत आधार-10 में केवल थोड़ी सी जगह का उपयोग करके प्रदर्शित किया जा सकता है (और इसलिए दिखाई देते हैं हम मनुष्यों के लिए बहुत "गोल" होना), उदा। दसवां, वास्तव में अनंत बाइनरी सर्किट को सटीक रूप से संग्रहीत करने की आवश्यकता होगी (और इसलिए हमारे डिजिटल मित्रों के लिए बहुत "गोल" प्रतीत नहीं होता है)! विशेष रूप से, चूंकि 2 10 का एक कारक है, वही विपरीत में सच नहीं है:कोई भी संख्या जिसे परिमित बाइनरी के साथ दर्शाया जा सकता है, उसे परिमित दशमलव के साथ भी दर्शाया जा सकता है।

हम निरंतर मात्रा के लिए बेहतर कुछ नहीं कर सकते। अंततः ऐसी मात्राओं को कुछ . में एक सीमित प्रतिनिधित्व का उपयोग करना चाहिए अंक प्रणाली:यह मनमाना है कि क्या वह प्रणाली कंप्यूटर सर्किट पर, मानव उंगलियों पर, किसी और चीज़ पर आसान होती है या किसी भी चीज़ पर नहीं—जो भी प्रणाली का उपयोग किया जाता है, मान चाहिए गोल हो और इसलिए यह हमेशा "प्रतिनिधित्व त्रुटि" में परिणाम।

दूसरे शब्दों में, भले ही किसी के पास पूरी तरह से सटीक माप उपकरण हो (जो कि शारीरिक रूप से असंभव है), तो उसके द्वारा रिपोर्ट किया गया कोई भी माप पहले से ही गोल हो चुका होगा एक संख्या के लिए जो इसके प्रदर्शन पर फिट होने के लिए होता है (जिस भी आधार में यह उपयोग करता है-आमतौर पर दशमलव, स्पष्ट कारणों से)। तो, "86.2 आउंस" वास्तव में कभी नहीं होता "86.2 आउंस " बल्कि "86.1500000... oz और 86.2499999... oz के बीच कुछ का प्रतिनिधित्व करता है" "। (वास्तव में, क्योंकि वास्तव में उपकरण अपूर्ण है, हम वास्तव में केवल इतना कह सकते हैं कि हमारे पास कुछ विश्वास की डिग्री कि वास्तविक मूल्य उस अंतराल के भीतर आता है—लेकिन वह निश्चित रूप से यहां बिंदु से किसी तरह निकल रहा है)।

लेकिन हम असतत मात्रा के लिए बेहतर कर सकते हैं . ऐसे मान "मनमाने ढंग से वास्तविक संख्या" नहीं हैं और इसलिए उपरोक्त में से कोई भी उन पर लागू नहीं होता है:उन्हें बिल्कुल दर्शाया जा सकता है अंक प्रणाली में जिसमें उन्हें परिभाषित किया गया था—और वास्तव में, होना चाहिए (जैसा कि किसी अन्य अंक प्रणाली में परिवर्तित करने और एक सीमित लंबाई में कटौती करने के परिणामस्वरूप एक सटीक संख्या में गोल किया जाएगा)। कंप्यूटर एक स्ट्रिंग के रूप में संख्या का प्रतिनिधित्व करके ऐसी स्थितियों को (अक्षम रूप से) संभाल सकता है:उदा। ASCII पर विचार करें या BCD एन्कोडिंग।

प्रारूप लागू करें...

चूंकि यह अंक प्रणाली के (कुछ हद तक मनमाना) आधार का गुण है, कोई मान "गोल" प्रतीत होता है या नहीं, इसका परिशुद्धता पर कोई प्रभाव नहीं पड़ता है . यह एक वास्तव में महत्वपूर्ण अवलोकन है , जो कई लोगों के अंतर्ज्ञान के विपरीत चलता है (और यही कारण है कि मैंने ऊपर संख्यात्मक आधार को समझाने में इतना समय बिताया)।

इसके बजाय सटीकता का निर्धारण कितने महत्वपूर्ण आंकड़ों द्वारा किया जाता है एक प्रतिनिधित्व है . हमें एक भंडारण प्रारूप की आवश्यकता है जो हमारे मूल्यों को कम से कम . तक रिकॉर्ड करने में सक्षम हो उतने ही महत्वपूर्ण आंकड़े जितना हम उन्हें सही मानते हैं . उदाहरण मानों के रूप में लेते हुए जिन्हें हम 86.2 . के रूप में बताए जाने पर सही मानते हैं और 0.0000862 , दो सबसे आम विकल्प हैं:

  • निश्चित बिंदु , जहां महत्वपूर्ण अंकों की संख्या परिमाण पर निर्भर करती है :जैसे निश्चित 5-दशमलव-बिंदु प्रतिनिधित्व में, हमारे मान 86.20000 . के रूप में संग्रहीत किए जाएंगे और 0.00009 (और इसलिए क्रमशः 7 और 1 महत्वपूर्ण सटीकता के आंकड़े हैं)। इस उदाहरण में, परिशुद्धता खो गई है बाद के मूल्य में (और वास्तव में, हमें कुछ भी का प्रतिनिधित्व करने में पूरी तरह से असमर्थ होने में अधिक समय नहीं लगेगा। महत्व का); और पिछला मान झूठी सटीकता संगृहीत किया गया , जो हमारे सीमित स्थान की बर्बादी है (और वास्तव में, मूल्य को इतना बड़ा होने में अधिक समय नहीं लगेगा कि यह भंडारण क्षमता को ओवरफ्लो कर दे)।

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

  • फ़्लोटिंग पॉइंट , जहां महत्वपूर्ण आंकड़ों की संख्या परिमाण के बावजूद स्थिर है :जैसे 5-महत्वपूर्ण-आंकड़ा दशमलव प्रतिनिधित्व में, हमारे मान 86.200 . के रूप में संग्रहीत किए जाएंगे और 0.000086200 (और, परिभाषा के अनुसार, दोनों बार सटीकता के 5 महत्वपूर्ण आंकड़े हैं)। इस उदाहरण में, दोनों मानों को बिना किसी सटीकता के नुकसान के संग्रहित किया गया है; और उन दोनों के पास समान राशि . भी है झूठी सटीकता, जो कम बेकार है (और इसलिए हम अपने सीमित स्थान का उपयोग मूल्यों की एक बड़ी श्रेणी का प्रतिनिधित्व करने के लिए कर सकते हैं-बड़े और छोटे दोनों)।

    यह प्रारूप कब उपयुक्त हो सकता है इसका एक सामान्य उदाहरण किसी भी वास्तविक विश्व माप . को रिकॉर्ड करने के लिए है :माप उपकरणों की सटीकता (जो सभी systematic दोनों से ग्रस्त हैं और random त्रुटियों) पैमाने के बावजूद काफी स्थिर है, इसलिए पर्याप्त महत्वपूर्ण आंकड़े (आमतौर पर लगभग 3 या 4 अंक) को देखते हुए, बिल्कुल कोई सटीकता नहीं खोती है भले ही आधार के परिवर्तन के परिणामस्वरूप एक अलग संख्या में गोल हो

    लेकिन फ़्लोटिंग पॉइंट संग्रहण प्रारूप कितने सटीक हैं हमारे कंप्यूटर द्वारा उपयोग किया जाता है?

    • एक IEEE754 एकल सटीक (बाइनरी32) फ़्लोटिंग पॉइंट संख्या में 24 बिट होते हैं, या log10(2) (7 से अधिक अंक, महत्व के-अर्थात। इसकी सहनशीलता ±0.000006% . से कम है . दूसरे शब्दों में, यह "86.20000 ." कहने से कहीं अधिक सटीक है ".

    • एक IEEE754 डबल प्रिसिजन (बाइनरी64) फ्लोटिंग पॉइंट संख्या में 53 बिट हैं, या log10(2) (लगभग 16) अंक, महत्व के—अर्थात। इसकी सहनशीलता केवल ±0.00000000000001% . से अधिक है . दूसरे शब्दों में, यह कहने से कहीं अधिक सटीक है "86.2000000000000 ".

    समझने वाली सबसे महत्वपूर्ण बात यह है कि ये प्रारूप क्रमशः दस हजार . से अधिक हैं और एक ट्रिलियन . से अधिक बार अधिक सटीक "86.2" कहने के बजाय—भले ही बाइनरी के दशमलव में सटीक रूपांतरण में गलत असत्य सटीकता शामिल हो (जिसे हमें अनदेखा करना चाहिए:इस पर जल्द ही और अधिक)!

यह भी ध्यान दें कि दोनों निश्चित और फ़्लोटिंग पॉइंट प्रारूपों के परिणामस्वरूप सटीकता का नुकसान होगा जब किसी मान को प्रारूप के समर्थन से अधिक सटीक रूप से जाना जाता है। ऐसी राउंडिंग त्रुटियां स्पष्ट रूप से गलत परिणाम प्राप्त करने के लिए अंकगणितीय परिचालनों में प्रचारित कर सकते हैं (जो निस्संदेह फ़्लोटिंग पॉइंट नंबरों की "अंतर्निहित अशुद्धियों" के संदर्भ में आपके संदर्भ की व्याख्या करता है):उदाहरण के लिए, 3 × 3000 5-स्थान निश्चित बिंदु में 999.99000 उत्पन्न होगा के बजाय 1000.00000; और 7 − ⁄50 5-महत्वपूर्ण फिगर में फ्लोटिंग पॉइंट 0.0028600 उत्पन्न करेगा के बजाय 0.0028571

संख्यात्मक विश्लेषण का क्षेत्र इन प्रभावों को समझने के लिए समर्पित है, लेकिन यह महसूस करना महत्वपूर्ण है कि कोई भी उपयोग करने योग्य प्रणाली (यहां तक ​​कि आपके दिमाग में गणना करना भी) ऐसी समस्याओं के प्रति संवेदनशील है क्योंकि गणना की कोई भी विधि जिसे समाप्त करने की गारंटी नहीं है, वह कभी भी अनंत सटीकता प्रदान नहीं कर सकती है :उदाहरण के लिए, एक वृत्त के क्षेत्रफल की गणना करने के तरीके पर विचार करें— necessarily के लिए उपयोग किए गए मान में आवश्यक रूप से सटीकता का नुकसान होगा, जो परिणाम में प्रसारित होगा।

निष्कर्ष

  1. वास्तविक विश्व मापन में बाइनरी फ़्लोटिंग पॉइंट का उपयोग करना चाहिए :यह तेज़, कॉम्पैक्ट, अत्यंत सटीक और किसी भी चीज़ से भी बदतर नहीं है (दशमलव संस्करण सहित, जिससे आपने शुरुआत की थी)। चूंकि MySQL के फ़्लोटिंग-पॉइंट डेटाटाइप IEEE754 हैं, यह वही है जो वे प्रदान करते हैं।

  2. मुद्रा एप्लिकेशन को डेनरी फिक्स्ड पॉइंट का उपयोग करना चाहिए :जबकि यह धीमा है और स्मृति को बर्बाद करता है, यह सुनिश्चित करता है कि मूल्यों को सटीक मात्रा में गोल नहीं किया जाता है और बड़ी मौद्रिक रकम पर पैसा नहीं खोया जाता है। चूंकि MySQL के फिक्स्ड-पॉइंट डेटाटाइप बीसीडी-एन्कोडेड स्ट्रिंग हैं, यह वही है जो वे पेश करते हैं।

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

इस मामले में कौन सा विकल्प सबसे अच्छा है?

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

आपके प्रश्न के लिए:विकल्प 3 के ऊपर विकल्प 1 या 2 चुनें—यह तुलना को आसान बनाता है (उदाहरण के लिए, अधिकतम द्रव्यमान खोजने के लिए, कोई केवल MAX(mass) का उपयोग कर सकता है। , जबकि इसे दो स्तंभों में कुशलतापूर्वक करने के लिए कुछ नेस्टिंग की आवश्यकता होगी)।

उन दोनों के बीच, इससे कोई फर्क नहीं पड़ता कि कौन सा चयन करता है—फ्लोटिंग पॉइंट नंबर लगातार महत्वपूर्ण बिट्स के साथ संग्रहीत किए जाते हैं उनके पैमाने के बावजूद

इसके अलावा, सामान्य स्थिति में ऐसा हो सकता है कि कुछ मान द्विआधारी संख्याओं के लिए गोल होते हैं जो विकल्प 1 का उपयोग करके उनके मूल दशमलव प्रतिनिधित्व के करीब होते हैं, साथ ही साथ अन्य द्विआधारी संख्याओं के लिए गोल होते हैं जो विकल्प 2 का उपयोग करके उनके मूल दशमलव प्रतिनिधित्व के करीब होते हैं, जैसा कि हम जल्द ही ऐसी प्रतिनिधित्व त्रुटियों को केवल झूठी सटीकता के भीतर प्रकट होते देखेंगे जिन्हें हमेशा अनदेखा किया जाना चाहिए।

हालांकि, इस . में मामला, क्योंकि ऐसा होता है कि 16 औंस से 1 पाउंड (और 16 2 की शक्ति है), दो दृष्टिकोणों का उपयोग करके मूल दशमलव मानों और संग्रहीत बाइनरी संख्याओं के बीच सापेक्ष अंतर समान है :

  1. 5.387510 (नहीं 5.3367187510 जैसा कि आपके प्रश्न में बताया गया है) एक बाइनरी 32 फ्लोट में 101.0110001100110011001102 (जो 5.3874998092651367187510 ):यह 0.0000036% . है मूल मूल्य से (लेकिन, जैसा कि ऊपर चर्चा की गई है, "मूल मूल्य" पहले से ही उस भौतिक मात्रा का एक बहुत ही घटिया प्रतिनिधित्व था जिसका वह प्रतिनिधित्व करता है)।

    यह जानते हुए कि एक बाइनरी32 फ्लोट सटीकता के केवल 7 दशमलव अंक संग्रहीत करता है, हमारा कंपाइलर निश्चित रूप से . जानता है कि 8वें अंक से सब कुछ निश्चित रूप से है झूठी सटीकता और इसलिए जरूरी हर . में नज़रअंदाज़ किया जाए मामला—इस प्रकार, बशर्ते कि हमारे इनपुट मान को उससे अधिक सटीकता की आवश्यकता न हो (और अगर ऐसा होता है, तो बाइनरी32 स्पष्ट रूप से प्रारूप का गलत विकल्प था), यह गारंटी देता है एक दशमलव मान पर वापसी जो ठीक उसी तरह गोल दिखती है जिससे हमने शुरुआत की थी:5.38750010 . हालांकि, हमें वास्तव में डोमेन ज्ञान लागू करना चाहिए। इस बिंदु पर (जैसा कि हमें किसी भी भंडारण प्रारूप के साथ होना चाहिए) किसी भी अन्य झूठी सटीकता को त्यागने के लिए जो मौजूद हो सकती है, जैसे कि दो अनुगामी शून्य।

  2. 86.210 एक बाइनरी 32 फ्लोट में 1010110.001100110011001102 (जो 86.199996948242187510 ):यह भी 0.0000036% . है मूल मूल्य से। पहले की तरह, हम फिर अपने मूल इनपुट पर लौटने के लिए झूठी सटीकता को अनदेखा कर देते हैं।

ध्यान दें कि रेडिक्स पॉइंट के स्थान को छोड़कर, संख्याओं के बाइनरी निरूपण समान हैं। (जो चार बिट अलग है):

101.0110 00110011001100110
101 0110.00110011001100110

ऐसा इसलिए है क्योंकि 5.3875 × 2 =86.2।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. mysql क्वेरी में सीरियल नंबर जेनरेट करें

  2. मैं इस सरणी संरचना को HTML रूप में कैसे बनाऊंगा?

  3. PHP में बिट फ़्लैग के लिए सर्वोत्तम अभ्यास

  4. टेक्स्ट/ब्लॉब को एक ही टेबल में स्टोर करें या नहीं?

  5. mysql के डिफ़ॉल्ट पोर्ट को 3306 से 3360 . में कैसे बदलें