आप SQL सर्वर में पैसा या DECIMAL (x, y) डेटाटाइप चुनना चाहिए?


442

मैं इस बारे में उत्सुक हूं कि क्या moneyडेटाटाइप और कुछ के बीच वास्तविक अंतर है decimal(19,4)( जैसे कि पैसा आंतरिक रूप से उपयोग करता है, मुझे विश्वास है)।

मुझे पता है कि moneySQL सर्वर के लिए विशिष्ट है। मैं जानना चाहता हूं कि क्या किसी को एक दूसरे को चुनने के लिए मजबूर करना है; अधिकांश SQL सर्वर नमूने (जैसे AdventureWorks डेटाबेस) मूल्य जानकारी जैसी चीजों के लिए उपयोग करते हैं moneyऔर नहीं decimal

क्या मुझे सिर्फ पैसे के डेटाटाइप का उपयोग करना जारी रखना चाहिए, या क्या इसके बजाय दशमलव का उपयोग करने का कोई लाभ है? पैसा टाइप करने के लिए कम वर्ण हैं, लेकिन यह एक वैध कारण नहीं है :)


12
DECIMAL(19, 4) है एक लोकप्रिय विकल्प जाँच इस भी जाँच यहाँ विश्व मुद्रा का प्रयोग करना है कि कितने दशमलव स्थानों तय करने के लिए, आशा में मदद करता है।
शैजुत

मैंने सोचा कि क्यों मनी डेटा के प्रकार में 4 दशमलव है .. और 2 नहीं। यानी एक डॉलर में 100 सेंट तो केवल 2 दशमलव स्थानों की आवश्यकता है? $ 9999.99 से कम धनराशि के रिकॉर्ड को संग्रहीत करने के लिए, मैं एक डेटा प्रकार के दशमलव (6,2) के साथ जाने वाला था। मैं फूट डालो या बहुगुणित गणनाओं के बारे में चिंतित नहीं हो, सिर्फ भंडारण और योग ..
एलन एफ

जवाबों:


326

कभी भी आपको पैसे का इस्तेमाल नहीं करना चाहिए। यह सटीक नहीं है, और यह शुद्ध कचरा है; हमेशा दशमलव / संख्यात्मक का उपयोग करें।

इसका मतलब यह देखने के लिए चलाएं:

DECLARE
    @mon1 MONEY,
    @mon2 MONEY,
    @mon3 MONEY,
    @mon4 MONEY,
    @num1 DECIMAL(19,4),
    @num2 DECIMAL(19,4),
    @num3 DECIMAL(19,4),
    @num4 DECIMAL(19,4)

    SELECT
    @mon1 = 100, @mon2 = 339, @mon3 = 10000,
    @num1 = 100, @num2 = 339, @num3 = 10000

    SET @mon4 = @mon1/@mon2*@mon3
    SET @num4 = @num1/@num2*@num3

    SELECT @mon4 AS moneyresult,
    @num4 AS numericresult

आउटपुट: 2949.0000 2949.8525

कुछ लोगों ने कहा कि आप पैसे से पैसे नहीं बांटते हैं:

यहाँ सहसंबंधों की गणना करने के लिए मेरे प्रश्नों में से एक है, और इसे पैसे में बदलना गलत परिणाम देता है।

select t1.index_id,t2.index_id,(avg(t1.monret*t2.monret)
    -(avg(t1.monret) * avg(t2.monret)))
            /((sqrt(avg(square(t1.monret)) - square(avg(t1.monret))))
            *(sqrt(avg(square(t2.monret)) - square(avg(t2.monret))))),
current_timestamp,@MaxDate
            from Table1 t1  join Table1 t2  on t1.Date = traDate
            group by t1.index_id,t2.index_id

61
"कभी नहीं" एक मजबूत शब्द है। "मनी" परिणाम के लिए उस प्रकार के कास्टिंग के लिए उपयोगी है जो उपयोगकर्ता के लिए संस्कृति-संवेदनशील तरीके से प्रदर्शित होता है, लेकिन आप सही हैं कि गणना के लिए इसका उपयोग करना बहुत बुरा है।
जोएल कोएहॉर्न

36
आपका उदाहरण सार्थक नहीं है, क्योंकि कोई भी कभी भी टाइप के पैसे की दो वस्तुओं को गुणा नहीं करेगा। यदि आप अपनी बात को साबित करना चाहते हैं, तो आपको एक दशमलव द्वारा दशमलव को गुणा करके पैसे को गुणा करने की तुलना करने की आवश्यकता है।
ब्रायन

27
.. लेकिन यह अभी भी हैरान कर रहा है कि क्यों पैसे * पैसे की सटीकता नहीं होगी।
सीखना

4
@ लर्निंग: इसमें पैसे की शुद्धता है। हालाँकि, आप अभी भी राउंडिंग त्रुटियों के साथ समाप्त होते हैं जो समय के साथ जमा हो सकते हैं। दशमलव प्रकार बाइनरी अंकगणित का उपयोग नहीं करता है: यह गारंटी देता है कि यह एक ही आधार 10 परिणाम प्राप्त करता है जो आप इसे कागज पर कर रहे हैं।
जोएल कोएहॉर्न

55
गुणन और विभाजन moneyके ऊपर moneyएक तरफ, इस 'चित्रण' जोड़ तोड़ है। यह एक प्रलेखित तथ्य है moneyजिसमें एक निश्चित और बहुत सीमित परिशुद्धता है। ऐसे मामलों में पहले एक को गुणा करना चाहिए, और फिर विभाजित करना चाहिए। इस उदाहरण में ऑपरेटरों के क्रम को बदलें और आपको समान परिणाम मिलेंगे। एक moneyअनिवार्य रूप से एक 64-बिट इंट है, और यदि आप ints से निपटने के लिए थे, तो आप विभाजित होने से पहले गुणा करेंगे।
एंड्री एम

272

SQLMenace ने कहा कि पैसा अक्षम्य है। लेकिन आप पैसे को पैसे से गुणा / भाग नहीं करते हैं! 3 सेंटीमीटर 50 सेंट कितना है? 150 डॉलर में? आप धन को स्केलरों द्वारा गुणा / भाग करते हैं, जो दशमलव होना चाहिए।

DECLARE
@mon1 MONEY,
@mon4 MONEY,
@num1 DECIMAL(19,4),
@num2 DECIMAL(19,4),
@num3 DECIMAL(19,4),
@num4 DECIMAL(19,4)

SELECT
@mon1 = 100,
@num1 = 100, @num2 = 339, @num3 = 10000

SET @mon4 = @mon1/@num2*@num3
SET @num4 = @num1/@num2*@num3

SELECT @mon4 AS moneyresult,
@num4 AS numericresult

सही परिणाम में परिणाम:

मनीरेस्कुल के अंक
--------------------- ----------------------------- ----------
2949.8525 2949.8525

moneyअच्छा है जब तक आपको 4 से अधिक दशमलव अंकों की आवश्यकता नहीं है, और आप यह सुनिश्चित करते हैं कि आपके स्केलर - जो पैसे का प्रतिनिधित्व नहीं करते हैं - decimalएस हैं।


57
एक डॉलर के बिल में आपको कितने 1 प्रतिशत सिक्के मिल सकते हैं? इसका उत्तर पैसे / पैसे की आवश्यकता है।
सीखना

48
उस स्थिति में @Learning का परिणाम पैसा नहीं है, बल्कि एक फ्लोट है। (मूल आयामी विश्लेषण।)
रिचर्ड

11
@ लर्निंग: क्या आप डेटाबेस से पूछते हैं कि एक डॉलर में कितने सेंट बहुत सारे हैं? वैसे भी, यह सही परिणाम लौटाएगा। उनकी समस्या यह थी कि पैसा / पैसा केवल चार अंकों के लिए सटीक था (यह 0.2949 था), फिर जब 10000 से गुणा किया गया तो यह 2949.0000 हो गया।
विन्यासकर्ता

26
@mson वह सही हैं और व्यक्तिगत आलोचना न करें क्योंकि आपने एक पंक्ति की टिप्पणी के आधार पर किया, यह मददगार नहीं है। अगर वह $ 0.01 से विभाजित नहीं करता है, लेकिन 0.01 से, तो परिणाम 100 के बजाय $ 100 है। एक डॉलर में 100 सेंट है, न कि $ 100 सेंट। इकाइयां महत्वपूर्ण हैं! डाइविंग के लिए निश्चित रूप से एक बड़ी जगह है, और शायद गुणा, पैसे से पैसा।
andrewb

19
अगर मैं $ 36 की कीमत पर स्टॉक शेयर खरीदने के लिए $ 1000 खर्च करना चाहता हूं, तो क्या यह वैध उपयोग नहीं है money / money? उत्तर पूरी इकाइयाँ है, जिनमें कोई भी डॉलर का चिह्न नहीं है, जो सही है! यह पूरी तरह से उचित परिदृश्य है, यह सुझाव देता है कि इस तरह के अजीब मामलों के कारण, moneyउपयोग करने के लिए एक अच्छा डेटा प्रकार नहीं है, क्योंकि परिणाम हमेशा moneyसटीक और पैमाने के लिए सामान्य नियमों का पालन करने के बजाय वापस फिट करने के लिए छोटा होता है । क्या होगा यदि आप moneyमूल्यों के एक सेट के मानक विचलन की गणना करना चाहते हैं? हाँ, Sqrt(Sum(money * money))(सरलीकृत) वास्तव में समझ में आता है।
एरिक

59

यदि आप नहीं जानते कि आप क्या कर रहे हैं तो सब कुछ खतरनाक है

यहां तक ​​कि उच्च-सटीक दशमलव प्रकार दिन को नहीं बचा सकते हैं:

declare @num1 numeric(38,22)
declare @num2 numeric(38,22)
set @num1 = .0000006
set @num2 = 1.0
select @num1 * @num2 * 1000000

1.000000 <- 0.6000000 होना चाहिए


moneyप्रकार पूर्णांक हैं

का पाठ निरूपण smallmoneyऔर decimal(10,4)समान दिख सकता है, लेकिन यह उन्हें विनिमेय नहीं बनाता है। जब आप तारीखों को संग्रहित करते देखते हैं तो क्या आप ऐंठ जाते हैं varchar(10)? यह वही चीज़ है।

पर्दे के पीछे, money/ smallmoneya bigint/ a हैं int दशमलव बिंदु पाठ के प्रतिनिधित्व में moneyदृश्य फुलाना है, जैसे एक yyyy-mm-dd दिनांक में डैश। SQL वास्तव में उन आंतरिक रूप से संग्रहीत नहीं करता है।

decimalबनाम के बारे में money, जो भी आपकी आवश्यकताओं के लिए उपयुक्त है, उसे चुनें। moneyप्रकार मौजूद हैं क्योंकि 1/10000 इकाई के के पूर्णांक गुणकों के रूप में लेखांकन मूल्यों के भंडारण के बहुत आम है। इसके अलावा, यदि आप साधारण धनराशि और घटाव से परे वास्तविक धन और गणना कर रहे हैं, तो आपको डेटाबेस स्तर पर ऐसा नहीं करना चाहिए! बैंकर के राउंडिंग (IEEE 754) का समर्थन करने वाले पुस्तकालय के साथ आवेदन स्तर पर करें


1
क्या आप बता सकते हैं कि इस उदाहरण में क्या हुआ?
सर्गेई पोपोव

4
स्केल ओवरफ्लो। छोटे पैमानों पर, संख्यात्मक (ए, बी) * संख्यात्मक (सी, डी) पैदावार संख्यात्मक (ए-बी + सी-डी + 1, अधिकतम (बी, डी))। हालाँकि, अगर (a + b + c + d)> 38, SQL स्केल को मापता है, तो पूर्णांक पक्ष को पैड करने के लिए अंश पक्ष से सटीकता को लूटता है, जिससे गोलाई त्रुटि होती है।
Anon

सभी संख्यात्मक गणना स्केलिंग के कारण सटीक नुकसान के लिए अतिसंवेदनशील होते हैं: इसके बजाय गणना 1000000 * @ num1 * @ num2
मिच गेहूं

Anon का उदाहरण संस्करण और डेटाबेस विशिष्ट है। लेकिन बिंदु सावधान रहना वैध है। 1.1 संस्करण में, उदाहरण के लिए, 0.600000 सही तरीके से देता है। (मुझे पता है कि हम यहाँ ms sql के बारे में बात कर रहे हैं)। अन्य डेटाबेस से पैसे के प्रकार के गायब होने के बारे में एक और बात, वहाँ दशमलव या संख्यात्मक को पैसे के रूप में कॉल करने के तरीके, जैसे कि डोमेन बनाना।
gg89

3
मुझे लगता है कि यह सबसे ज्ञानवर्धक उत्तर है क्योंकि आपने केवल उन त्रुटियों के बारे में नहीं बताया है जो प्रचारित हो जाती हैं, लेकिन वास्तव में दृश्य के पीछे क्या चल रहा है, और क्यों पैसे पहले स्थान पर मौजूद हैं। मुझे यकीन नहीं है कि इस उत्तर को प्राप्त करने में 4 साल क्यों लगे, लेकिन शायद ऐसा इसलिए है क्योंकि गणना "समस्या" पर बहुत अधिक ध्यान केंद्रित किया गया है, और व्हिस और मनी बनाम दशमलव पर इतना अधिक नहीं है।
स्टीव साइडर

44

मुझे पता है कि वेनम ने कहा है कि वह जानता है कि पैसा SQL सर्वर के लिए विशिष्ट है। हालांकि, वह पूछ रहा है कि क्या दशमलव या इसके विपरीत पैसे का उपयोग करने के लिए कोई कारण हैं और मुझे लगता है कि एक स्पष्ट कारण अभी भी कहा जाना चाहिए और दशमलव का उपयोग कर रहा है, तो यह चिंता का एक कम बात है कि क्या आपको कभी अपना DBMS बदलना है। - जो हो सकता है।

अपने सिस्टम को यथासंभव लचीला बनाएं!


1
संभवतः, लेकिन सिद्धांत रूप में आप किसी अन्य DBMS में मनी नामक डोमेन घोषित कर सकते हैं (जो कि डोमेन की घोषणा का समर्थन करता है)।
डिबेटर

जैसा कि वर्तमान में कोई SQL Server डेटाबेस को Amazon Redshift में कनवर्ट कर रहा है, मैं यह प्रतिज्ञा कर सकता हूं कि यह एक वास्तविक मुद्दा है। उन डेटा प्रकारों से बचने की कोशिश करें जो किसी विशेष डेटाबेस प्लेटफ़ॉर्म पर bespoke हैं जब तक कि उनके उपयोग करने के लिए बहुत ही व्यवसायिक कारण न हों।
नाथन ग्रिफ़िथ

@ नाथ ने Redgift के कमजोर टाइप सिस्टम को PostgreSQL या SQL सर्वर की तुलना में दिया, उदाहरण के लिए कोई dateप्रकार नहीं ; मैं कहता हूं कि आप हमेशा ऐसे मुद्दे रखेंगे । आपको कहना चाहिए "जब डेटाबेस पहले से बेहतर, अधिक मानक-संगत प्रकार प्रदान करता है और पदावनत लोगों के खिलाफ चेतावनी देता है, तो पदावनत प्रकारों का उपयोग न करें "।
पनियागोटिस कानावोस

@PanagiotisKanavos - पैसा नहीं निकाला गया
मार्टिन स्मिथ

@MartinSmith यह देखकर चौंक गया, क्योंकि यह वास्तव में 2017 में BTC जैसे पैसे के मूल्यों को संभाल नहीं सकता है। या GBP और EUR राशियों के बीच अंतर - भले ही वे समता की ओर बढ़ें: P। वैसे भी, रेडशिफ्ट में जाने से बहुत दर्द का
सामना करना पड़ता है

32

खैर, मुझे पसंद है MONEY! यह बाइट की तुलना में सस्ता है DECIMAL, और गणना जल्दी करते हैं क्योंकि (कवर के तहत) जोड़ और घटाव संचालन अनिवार्य रूप से पूर्णांक ऑपरेशन हैं। @ SQLMenace का उदाहरण- जो अनजान लोगों के लिए एक बड़ी चेतावनी है - समान रूप से INTईगर्स पर लागू किया जा सकता है , जहां परिणाम शून्य होगा। लेकिन पूर्णांक का उपयोग नहीं करने का कोई कारण नहीं है - जहां उपयुक्त हो

तो, यह पूरी तरह से 'सुरक्षित' है और MONEYजब आप जो व्यवहार कर रहे हैं उसका उपयोग करना उचित है MONEYऔर गणितीय नियमों के अनुसार इसका उपयोग करें कि यह ( INTईगर के समान )।

यह बेहतर होता है अगर एसक्यूएल सर्वर विभाजन और के गुणन पदोन्नत MONEYमें s ' DECIMALs (या FLOAT- संभवतः, लेकिन वे ऐसा करने के लिए नहीं चुना था रों?); और न ही उन्हें विभाजित करते समय INTई को बढ़ावा देने के लिए चुना FLOAT

MONEYकोई सटीक मुद्दा नहीं है; कि DECIMALएक बड़ा मध्यवर्ती गणना के दौरान इस्तेमाल किया प्रकार सिर्फ एक है कि प्रकार का उपयोग करने का 'विशेषता है के लिए मिलता है (और मैं वास्तव में यकीन है कि कितनी दूर है कि' सुविधा 'का विस्तार नहीं कर रहा हूँ)।

विशिष्ट प्रश्न का उत्तर देने के लिए, "सम्मोहक कारण"? ठीक है, अगर आप चाहते हैं कि अधिकतम अधिकतम प्रदर्शन SUM(x)जहां या xतो हो सकता है , तो एक बढ़त होगी।DECIMALMONEYMONEY

इसके अलावा, यह मत भूलना छोटा चचेरा भाई, - SMALLMONEY4 बाइट्स, लेकिन यह अधिकतम करता है 214,748.3647- जो पैसे के लिए बहुत छोटा है - और इसलिए अक्सर एक अच्छा फिट नहीं होता है।

बड़े मध्यवर्ती प्रकारों का उपयोग करते हुए बिंदु को साबित करने के लिए, यदि आप मध्यवर्ती को स्पष्ट रूप से एक चर में निर्दिष्ट करते हैं, तो एक DECIMALही समस्या आती है:

declare @a decimal(19,4)
declare @b decimal(19,4)
declare @c decimal(19,4)
declare @d decimal(19,4)

select @a = 100, @b = 339, @c = 10000

set @d = @a/@b

set @d = @d*@c

select @d

प्रोड्यूस 2950.0000(ठीक है, इसलिए कम से कम DECIMALराउंड किए गए बजाय MONEYएक पूर्णांक के समान होगा)।


21
MONEYएक बाइट एक से भी कम है बड़े DECIMAL , परिशुद्धता के 19 अंक से ऊपर के साथ। हालांकि, अधिकांश वास्तविक-विश्व मौद्रिक गणना ($ 9.99 एम तक) में फिट हो सकते हैं DECIMAL(9, 2), जिसमें सिर्फ पांच बाइट्स की आवश्यकता होती है। आप आकार को बचा सकते हैं, गोलाई की त्रुटियों के बारे में कम चिंता कर सकते हैं और अपने कोड को अधिक पोर्टेबल बना सकते हैं।

जबकि @JonofAllTrades सही है, आप केवल पूर्णांक या सेंट वाले पूर्णांक का उपयोग करके पूर्णांक प्रदर्शन प्राप्त कर सकते हैं, और अतिरिक्त बाइट को बचा सकते हैं जो दशमलव बिंदु की स्थिति को कूटबद्ध करता है, और जिसे एक साथ दशमलव जोड़ते समय जांचना होता है।
dsz

"तो, यह पूरी तरह से 'सुरक्षित' है और पैसे का उपयोग करने के लिए उपयुक्त है जब आप जो काम कर रहे हैं वह पैसा है और गणितीय नियमों के अनुसार इसका उपयोग करें जो" इस प्रकार है "- हालांकि, अनोन का जवाब भी देखें:" सब कुछ खतरनाक है यदि आप नहीं करते हैं जानिए आप क्या कर रहे हैं ”। आप कभी भी यह अनुमान नहीं लगा सकते हैं कि लोग आपके द्वारा बनाई जा रही प्रणाली को कैसे समाप्त करेंगे, दुरुपयोग की संभावना से बचने के लिए सबसे अच्छा होगा जब आप कर सकते हैं। भंडारण में ऋणात्मक लाभ इसके लायक नहीं है IMHO।
नाथन ग्रिफिथ्स

1
एक बिटकॉइन मूल्य संग्रहीत करने का प्रयास करें। इसके
av डेसीमल हैं

13

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

vat proportion = total invoice vat x (voucher line value / total invoice value)

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

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


8
लेकिन यह केवल इसलिए होता है क्योंकि एक अज्ञानी डेवलपर ने वैट गणना के नियमों और पैसे की दस्तावेजित सटीक सीमाओं की अनदेखी की।
टॉमटॉम

1
@TomTom लेकिन इस डेटा प्रकार के दुरुपयोग की संभावना के बारे में आप जो बिंदु बना रहे हैं, वह इसका उपयोग करने से बचने के पक्ष में एक तर्क है।
नाथन ग्रिफ़िथ

@ नथन नं। मैं संकेत कर रहा हूं कि तर्क को कभी भी इस्तेमाल न करने के कारण के रूप में दिया गया यह मूल रूप से अक्षम डेवलपर है, इसलिए यह तर्क फर्जी है।
टॉम टॉम

1
@TomTom दुख की बात है कि कई अक्षम डेवलपर्स (साथ ही कई भयानक वाले) और मेरे लिए हैं, जब तक कि मैं यह गारंटी नहीं दे सकता कि यह डेटा भविष्य में किस तरह से और कभी भी किसी भी तरह की गलतियाँ करने वाला था। , सावधानी के पक्ष में और दशमलव प्रकार का उपयोग करने के लिए बेहतर है। उस ने कहा, इन सभी उत्तरों को पढ़ने के बाद मैं देख सकता हूं कि कुछ विशिष्ट उपयोग के मामले हैं जहां पैसे का उपयोग करने के लिए एक इष्टतम प्रकार होगा, मैं इसका उपयोग तब तक नहीं करूंगा जब तक कि इसके लिए बहुत अच्छा उपयोग का मामला न हो (उदाहरण के लिए कॉलम केवल कभी होगा एसयूएम द्वारा एकत्रित किया जाए, बड़ी मात्रा में वित्तीय डेटा लोड किया जाए)।
नाथन ग्रिफ़िथ्स

@TomTom यह केवल सटीक सीमाएँ नहीं है। आंतरिक प्रतिनिधित्व भी मुद्दों का कारण बन सकता है। पैसा एक सुविधा प्रकार है जो अज्ञानी डेवलपर्स को पकड़ता है, न कि एक महान प्रकार जिसे डेवलपर्स दुरुपयोग कर रहे हैं। वात उदाहरण, इसकी गणना के नियमों की परवाह किए बिना, स्पष्ट रूप से गैर-अज्ञानी डेवलपर्स को डराना चाहिए जब वे सामान्य पर विशिष्ट लागू होते हैं।
जेरार्ड ओनिल

12

एक काउंटर बिंदु के रूप में अन्य उत्तरों के सामान्य जोर पर। पैसे के कई लाभ देखें ... डेटा प्रकार! में संबंधपरक इंजन को SQLCAT की गाइड

विशेष रूप से मैं निम्नलिखित बात करूंगा

ग्राहक कार्यान्वयन पर काम करते हुए, हमें मनी डेटा प्रकार के विषय में कुछ दिलचस्प प्रदर्शन संख्याएँ मिलीं। उदाहरण के लिए, जब SQL Server मनी डेटा प्रकार से मिलान करने के लिए विश्लेषण सेवाओं को मुद्रा डेटा प्रकार (डबल से) में सेट किया गया था, तो प्रसंस्करण गति (पंक्तियों / सेकंड) में 13% सुधार हुआ था। SQL सर्वर इंटीग्रेशन सर्विसेज (SSIS) के भीतर तीस मिनट के भीतर 1.18 टीबी लोड करने के लिए तेजी से प्रदर्शन प्राप्त करने के लिए, जैसा कि SSIS 2008 में उल्लेख किया गया है - विश्व रिकॉर्ड ETL प्रदर्शन, यह देखा गया कि चार दशमलव (9,2) कॉलम को एक आकार के साथ बदलना TPC-H LINEITEM तालिका में 5 बाइट्स को पैसे (8 बाइट्स) में 20% तक थोक आवेषण की गति में सुधार ... प्रदर्शन में सुधार का कारण SQL सर्वर के टैबलर डेटा स्ट्रीम (TDS) प्रोटोकॉल है, जिसके पास कॉम्पैक्ट बाइनरी फॉर्म में डेटा ट्रांसफर करने के लिए मुख्य डिज़ाइन सिद्धांत है और जितना संभव हो उतना SQL सर्वर के आंतरिक भंडारण प्रारूप के करीब है। जाहिर है, यह एसएसआईएस 2008 के दौरान देखा गया था - केर्न्रेट का उपयोग करते हुए विश्व रिकॉर्ड ईटीएल प्रदर्शन परीक्षण; जब डेटा प्रकार दशमलव से पैसे पर स्विच किया गया था, तो प्रोटोकॉल में काफी गिरावट आई थी। यह डेटा के हस्तांतरण को यथासंभव कुशल बनाता है। एक जटिल डेटा प्रकार को निश्चित-चौड़ाई प्रकार की तुलना में अतिरिक्त पार्सिंग और सीपीयू चक्र की आवश्यकता होती है।

तो प्रश्न का उत्तर "यह निर्भर करता है" है। परिशुद्धता को बनाए रखने के लिए आपको कुछ अंकगणितीय परिचालनों के साथ अधिक सावधान रहने की आवश्यकता है, लेकिन आप पा सकते हैं कि प्रदर्शन के विचार इसे सार्थक बनाते हैं।


फिर आप बिटकॉइन को कैसे स्टोर करेंगे ?
पनियागोटिस कानावोस

@PanagiotisKanavos - मुझे कोई पता नहीं है। मैंने कभी भी बिटकॉइन पर ध्यान नहीं दिया है और व्यावहारिक रूप से इसके बारे में कुछ भी नहीं पता है!
मार्टिन स्मिथ

6

मैं काफी हद तक अपनी खुद की विशेषज्ञता और अनुभव के आधार पर MONEY बनाम NUMERICAL का एक अलग दृश्य देना चाहता हूं ... यहां मेरा नजरिया MONEY है, क्योंकि मैंने इसके साथ काफी लंबे समय तक काम किया है और वास्तव में कभी भी NUMERICAL का ज्यादा इस्तेमाल नहीं किया है। ।

पैसा प्रो:

  • मूल डेटा प्रकार । यह एक सीपीयू रजिस्टर (32 या 64 बिट) के समान ही एक देशी डेटा प्रकार ( पूर्णांक ) का उपयोग करता है , इसलिए गणना को अनावश्यक ओवरहेड की आवश्यकता नहीं है, इसलिए यह छोटा और तेज है ... पैसे की जरूरत 8 बाइट्स और न्यूमेरिकल (19, 4) ) 9 बाइट्स (12.5% ​​बड़ा) की जरूरत है ...

    पैसा तब तक तेज होता है जब तक इसका उपयोग किया जाता है जब तक इसका मतलब (धन के रूप में) था। कितना तेज? SUM1 मिलियन डेटा पर मेरा सरल परीक्षण दर्शाता है कि MONEY 275 ms और NUMERIC 517 ms है ... जो लगभग दोगुना है ... क्यों SUM परीक्षण? अगले प्रो बिंदु देखें

  • बेस्ट फॉर मनी । पैसा पैसा जमा करने और संचालन के लिए सबसे अच्छा है, उदाहरण के लिए, लेखांकन में। एक एकल रिपोर्ट SUM ऑपरेशन किए जाने के बाद लाखों जोड़ (SUM) और कुछ गुणन चला सकती है। बहुत बड़े लेखांकन अनुप्रयोगों के लिए यह लगभग दोगुना तेज़ है , और यह बेहद महत्वपूर्ण है ...
  • पैसे की कम शुद्धता । वास्तविक जीवन में पैसा बहुत सटीक होने की जरूरत नहीं है। मेरा मतलब है, बहुत से लोग 1 सेंट अमरीकी डालर के बारे में परवाह कर सकते हैं, लेकिन 0.01 मिलियन अमरीकी डालर के बारे में कैसे? वास्तव में, मेरे देश में, बैंक अब सेंट के बारे में परवाह नहीं करते हैं (दशमलव अल्पविराम के बाद अंक); मैं अमेरिकी बैंक या अन्य देश के बारे में नहीं जानता ...

पैसा कॉन:

  • सीमित परिशुद्धता । MONEY में केवल चार अंक (अल्पविराम के बाद) सटीक होते हैं, इसलिए इसे विभाजन जैसे कार्यों को करने से पहले परिवर्तित करना होगा ... लेकिन तब फिर moneyसे इतनी सटीक होने की आवश्यकता नहीं है और इसका उपयोग केवल पैसे के रूप में किया जाना चाहिए, न कि केवल नंबर ...

लेकिन ... बड़ा है, लेकिन यहां तक ​​कि यहां तक ​​कि आपके आवेदन में वास्तविक धन भी शामिल है, लेकिन लेखांकन में बहुत सारे SUM संचालन में इसका उपयोग न करें। यदि आप इसके बजाय बहुत से विभाजनों और गुणाओं का उपयोग करते हैं, तो आपको पैसे का उपयोग नहीं करना चाहिए ...


1
यदि आप यह कहने जा रहे हैं कि पैसा दशमलव से अधिक तेज़ है, तो आपको हमें यह बताने की ज़रूरत है कि क्या rdbms, किस हार्डवेयर पर, क्या OS चला रहा है, किस विशिष्ट डेटा के साथ आप किस विशिष्ट क्वेरी के बारे में बात कर रहे हैं। इसके अलावा, अगर यह सटीक नहीं है, तो मैं इसके साथ कोई वित्तीय संचालन नहीं कर रहा हूं, क्योंकि कर आदमी खराब संख्या वापस पाने के बजाय नाराज हो जाएगा। यदि आप उदाहरण के लिए अमेरिकी मुद्रा के साथ काम कर रहे हैं तो आप हज़ार प्रतिशत की परवाह करते हैं। यदि पैसा ऐसा नहीं कर रहा है, तो यह प्रयोग करने योग्य नहीं है।
हकोन लोवेटविट

3
@ HaakonLøtveit यह पूरा प्रश्नोत्तर धागा SQL सर्वर डेटा प्रकार "मनी" के बारे में है, इसलिए मुझे नहीं लगता कि उन्हें उत्तर में इसे निर्दिष्ट करने की आवश्यकता है। कुछ परिस्थितियों में दशमलव की तुलना में धन का उपयोग तेजी से किया जा सकता है (जैसे डेटा लोड करना), अधिक विवरण के लिए मार्टिन स्मिथ द्वारा उत्तर देखें। मैं इस जवाब के बहुमत से सहमत हूं, इसमें कुछ उपयोग मामले हैं जो पैसे को दशमलव की तुलना में अधिक कुशल विकल्प बना सकते हैं, हालांकि जब तक कि इसका उपयोग करने के लिए बहुत सम्मोहक मामला नहीं है, मुझे लगता है कि इससे बचना चाहिए।
नाथन ग्रिफिथ्स

1
बिटकॉइन में 8 डेसीमल है। आप इसे एक moneyकॉलम
पनियागोटिस कानावोस

4

पिछले सभी पोस्ट वैध अंक लाते हैं, लेकिन कुछ इस सवाल का सही जवाब नहीं देते हैं।

सवाल यह है: जब हम पहले से ही जानते हैं कि कोई व्यक्ति पैसे को तरजीह देगा तो यह एक कम सटीक डेटा प्रकार है और यदि जटिल गणनाओं में उपयोग किया जाता है, तो त्रुटि हो सकती है?

जब आप जटिल गणनाएँ नहीं करेंगे तो आप पैसे का उपयोग करेंगे और अन्य आवश्यकताओं के लिए इस परिशुद्धता का व्यापार कर सकते हैं।

उदाहरण के लिए, जब आपको उन गणनाओं को करने की आवश्यकता नहीं है, और मान्य मुद्रा पाठ स्ट्रिंग्स से डेटा आयात करने की आवश्यकता है। यह स्वचालित रूपांतरण केवल MONEY डेटा प्रकार के साथ काम करता है:

SELECT CONVERT(MONEY, '$1,000.68')

मुझे पता है कि आप अपनी खुद की आयात दिनचर्या बना सकते हैं। लेकिन कभी-कभी आप दुनिया भर में विशिष्ट स्थानीय स्वरूपों के साथ एक आयात दिनचर्या को फिर से बनाना नहीं चाहते हैं।

एक और उदाहरण, जब आपको उन गणनाओं को करने की ज़रूरत नहीं है (आपको केवल एक मूल्य को संग्रहीत करने की आवश्यकता है) और 1 बाइट बचाने की आवश्यकता है (पैसा 8 बाइट्स लेता है और दशमलव (19,4) 9 बाइट्स लेता है)। कुछ अनुप्रयोगों में (तेजी से सीपीयू, बड़ी रैम, धीमी आईओ), जैसे कि बड़ी मात्रा में डेटा पढ़ना, यह तेजी से भी हो सकता है।


2

जब आपको मूल्य पर गुणा / भाग करने की आवश्यकता हो तो आपको पैसे का उपयोग नहीं करना चाहिए। पैसा उसी तरह संग्रहीत किया जाता है जिस तरह एक पूर्णांक संग्रहीत किया जाता है, जबकि दशमलव को दशमलव बिंदु और दशमलव अंकों के रूप में संग्रहीत किया जाता है। इसका मतलब यह है कि अधिकांश मामलों में पैसा सटीकता को गिरा देगा, जबकि दशमलव केवल तब करेगा जब इसे अपने मूल पैमाने पर वापस बदल दिया जाएगा। पैसा निश्चित बिंदु है, इसलिए गणना के दौरान इसका पैमाना नहीं बदलता है। हालाँकि, क्योंकि यह दशमलव बिंदु के रूप में मुद्रित होने पर निश्चित बिंदु होता है (जैसा कि आधार 2 स्ट्रिंग में एक निश्चित स्थिति के रूप में विरोध किया जाता है), 4 के पैमाने तक के मूल्यों को बिल्कुल प्रतिनिधित्व किया जाता है। तो इसके अलावा और घटाव के लिए, पैसा ठीक है।

एक दशमलव को आधार 10 में आंतरिक रूप से दर्शाया गया है, और इस प्रकार दशमलव बिंदु की स्थिति भी आधार 10 संख्या पर आधारित है। जो इसके भिन्नात्मक हिस्से को उसके मूल्य का प्रतिनिधित्व करता है, ठीक उसी तरह जैसे कि पैसे के साथ। अंतर यह है कि दशमलव के मध्यवर्ती मान 38 अंकों तक सटीक बनाए रख सकते हैं।

फ्लोटिंग पॉइंट नंबर के साथ, मान को बाइनरी में संग्रहीत किया जाता है जैसे कि यह एक पूर्णांक था, और दशमलव (या बाइनरी, अहम) बिंदु की स्थिति संख्या का प्रतिनिधित्व करने वाले बिट्स के सापेक्ष है। क्योंकि यह एक बाइनरी दशमलव बिंदु है, बेस 10 नंबर दशमलव बिंदु के ठीक बाद सटीक खो देते हैं। 1 / 5th, या 0.2, इस तरह से सटीक रूप से प्रतिनिधित्व नहीं किया जा सकता है। न तो धन और न ही दशमलव इस सीमा से ग्रस्त हैं।

धन को दशमलव में बदलना, गणना करना और फिर परिणामी मूल्य को धन क्षेत्र या चर में संग्रहित करना काफी आसान है।

मेरे पीओवी से, मैं सामान चाहता हूं जो संख्याओं के लिए होता है बस उन्हें बहुत अधिक विचार देने के बिना होता है। यदि सभी गणना दशमलव में परिवर्तित होने जा रही हैं, तो मेरे लिए मैं केवल दशमलव का उपयोग करना चाहता हूं। मैं प्रदर्शन उद्देश्यों के लिए धन क्षेत्र को बचाऊंगा।

आकार-वार मुझे अपने मन को बदलने के लिए पर्याप्त अंतर नहीं दिखता है। पैसा 4 - 8 बाइट्स लेता है, जबकि दशमलव 5, 9, 13 और 17 हो सकता है। 9 बाइट्स पूरी रेंज को कवर कर सकते हैं जो कि 8 बाइट्स कर सकते हैं। सूचकांक-वार (तुलना करना और खोजना तुलनात्मक होना चाहिए)।


Upvote के लिए धन्यवाद। मैं इसे देख रहा हूं और जब मुझे जो कहना था, वह मुझे मिल गया, तो मैं इसे बहुत भ्रमित होने वाला भी देख सकता हूं। शायद मैं इसे बाद में कुछ बिट बनाम दशमलव उदाहरणों के साथ फिर से लिखूंगा।
जेरार्ड ओनेइल

2

मुझे सटीकता के विषय में पैसे पर दशमलव का उपयोग करने के बारे में एक कारण मिला।

DECLARE @dOne   DECIMAL(19,4),
        @dThree DECIMAL(19,4),
        @mOne   MONEY,
        @mThree MONEY,
        @fOne   FLOAT,
        @fThree FLOAT

 SELECT @dOne   = 1,
        @dThree = 3,    
        @mOne   = 1,
        @mThree = 3,    
        @fOne   = 1,
        @fThree = 3

 SELECT (@dOne/@dThree)*@dThree AS DecimalResult,
        (@mOne/@mThree)*@mThree AS MoneyResult,
        (@fOne/@fThree)*@fThree AS FloatResult

DecimalResult> 1.000000

MoneyResult> 0.9999

फ्लोटअंडाल्ट> १

बस इसे परखें और अपना निर्णय लें।


2
हम आपका निष्कर्ष सुनना (पढ़ना, यही है) बहुत पसंद करेंगे ।
पीटर मोर्टेंसन

@PeterMortensen मुझे लगता है कि अगर मुझे पैसे और दशमलव के बीच पूर्णता और सटीकता चाहिए, तो मेरा निर्णय दशमलव एक होना चाहिए।
QMaster

1
उपरोक्त के वास्तविक परिणाम के साथ अपने उत्तर को अपडेट करने पर विचार करें। फिर आपका निष्कर्ष किसी को भी पढ़ने के लिए तुरंत स्पष्ट हो जाएगा :-)
अग्रीक्स

1
@Ageax परिणाम उत्तर में जोड़ा गया।
क्यूमास्टर

1

मैंने सिर्फ इस ब्लॉग प्रविष्टि को देखा: SQL सर्वर में पैसा बनाम दशमलव

जो मूल रूप से कहता है कि पैसा एक सटीक मुद्दा है ...

declare @m money
declare @d decimal(9,2)

set @m = 19.34
set @d = 19.34

select (@m/1000)*1000
select (@d/1000)*1000

के लिए moneyप्रकार, आप 19.30 की बजाय 19.34 मिल जाएगा। मुझे यकीन नहीं है कि अगर कोई ऐसा एप्लिकेशन परिदृश्य है जो गणना के लिए 1000 भागों में पैसे को विभाजित करता है, लेकिन यह उदाहरण कुछ सीमाओं को उजागर करता है।


15
यह एक "मुद्दा" नहीं है, यह "प्रति विनिर्देशों" है: « moneyऔर smallmoneyडेटा प्रकार मौद्रिक इकाइयों के दस हजारवें हिस्से के लिए सटीक हैं, जो वे प्रतिनिधित्व करते हैं।» जैसा कि msdn.microsoft.com/en-us/library/ms179882.aspx में कहा गया है कि कोई भी यह कह रहा है कि "यह बकवास है" नहीं जानता कि वह किस बारे में बात कर रहा है।
अल्बेरियो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.