PostgreSQL: मुद्रा के लिए कौन सा डेटाटाइप का उपयोग किया जाना चाहिए?


128

यहाँMoney वर्णित के अनुसार प्रकार जैसे लगता है हतोत्साहित किया जाता है

मेरे आवेदन को मुद्रा स्टोर करने की आवश्यकता है, मैं किस डेटाटाइप का उपयोग कर रहा हूं? संख्यात्मक, धन या FLOAT?


7
यदि आपने पूरा धागा पढ़ा है, तो न्यूमेरिक जाने का रास्ता है।
रज़ेपिटिया

कई मुद्राओं के साथ काम करने वाले लोगों के लिए और राशियों के अलावा मुद्रा कोडों के भंडारण के बारे में, आप डेटाबेस (SO) और ISO 4217 (विकिपीडिया) में मुद्रा मॉडलिंग देखना चाहते हैं । संक्षिप्त उत्तर यह है कि आपको दो कॉलमों की आवश्यकता होगी।
फेबिन स्नूवर्ट 19

जवाबों:


90

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

पैसा प्रकार केवल ऐतिहासिक कारणों से बचा है जहां तक ​​मैं बता सकता हूं।


9
इसलिए आप फ्लोटिंग पॉइंट से बचें। यहां तक ​​कि न्यूमेरिक में राउंडिंग त्रुटियां होंगी यदि आप किसी भी चीज से विभाजित करते हैं जो दस की शक्ति में विभाजित नहीं करता है, तो कोई फर्क नहीं पड़ता कि आप क्या सटीक उपयोग करते हैं। (2 की शुद्धता वैसे भी एक बुरा विचार है ... डॉक्स की जांच करें।)
डोरैडस

6
यदि आप मनमानी मुद्राओं का समर्थन करना चाहते हैं, तो कभी भी 2 के बराबर कोई पैमाना न बनाएं (पोस्टग्रैक्स्ल शर्तों में, सटीक सभी अंकों की एक संख्या है, उदाहरण के लिए 121.121 में यह 6 के बराबर है)। बहरीन दीनार जैसी मुद्राएँ हैं, जहाँ 1000 उप-इकाइयाँ एक इकाई के बराबर हैं, और ऐसी मुद्राएँ हैं जिनकी उप-इकाइयाँ बिल्कुल नहीं हैं।
निकोले आरिपोव

@NikolayArhipov अच्छा बिंदु है, इसलिए अधिकतम वास्तव में हैscale - precision
कोनराड

1
numeric(3,2)अधिकतम स्टोर करने में सक्षम होगा9.99 3-2 = 1
कोनराड

5
यह मत करो! जब तक आप अन्य भाषाओं में किसी भी मान को लोड करने से पहले 100 से गुणा करने की योजना नहीं बनाते हैं और तब पूर्णांक के साथ गणित कर रहे हैं - आप गलत परिणामों के साथ समाप्त हो जाएंगे। सेंट में चीजों को स्टोर करें (सबसे छोटी मुद्रा इकाई जिसके साथ आप काम कर रहे हैं) और अपने आप को कुछ परेशानी से बचाएं। कई मामलों में बहुत बुरा जवाब।
22

111

आपका स्रोत किसी भी तरह से आधिकारिक नहीं है। यह 2011 की है और मैं लेखकों को भी नहीं जानता। अगर पैसे का प्रकार आधिकारिक तौर पर "हतोत्साहित" किया गया था, तो पोस्टग्रेएसक्यूएल मैनुअल में ऐसा कहेगा - जो यह नहीं करता है

के लिए एक और अधिक आधिकारिक स्रोत , पढ़ा (बस इस सप्ताह से!) Pgsql-सामान्य रूप में इस सूत्र डी'आर्सी जेएम कैन (पैसा प्रकार के मूल लेखक) और टॉम लेन और कोर डेवलपर्स से बयान के साथ,:

संबंधित उत्तर (और टिप्पणियाँ!) हालिया रिलीज़ में सुधार के बारे में:

असल में, moneyइसके (बहुत सीमित) उपयोग हैं। The Postgres Wiki उन संकीर्ण रूप से परिभाषित मामलों को छोड़कर, मोटे तौर पर इससे बचने का सुझाव देता है। लाभ से अधिक numericहै प्रदर्शन

decimalnumericPostgres में केवल एक उपनाम है , और व्यापक रूप से मौद्रिक डेटा के लिए उपयोग किया जाता है, एक "मनमाना सटीक" प्रकार है। मैनुअल :

प्रकार numericबहुत बड़ी संख्या में अंकों के साथ संख्याओं को संग्रहीत कर सकता है। यह विशेष रूप से मौद्रिक मात्रा और अन्य मात्रा के भंडारण के लिए अनुशंसित है जहां सटीकता की आवश्यकता होती है।

व्यक्तिगत रूप से, मुझे मुद्रा को integerसेंट के प्रतिनिधित्व के रूप में संग्रहीत करना पसंद है यदि आंशिक अंश कभी नहीं होते हैं (मूल रूप से जहां पैसा समझ में आता है)। यह किसी भी अन्य विकल्पों की तुलना में अधिक कुशल है।


4
मेलिंग सूचियों पर कई चर्चाएं हैं जो यह धारणा देती हैं कि धन प्रकार कम से कम अनुशंसित नहीं है, उदाहरण के लिए: यहाँ: postgresql.nabble.com/Money-type-todos-td1964190.html##1964192 प्लस निष्पक्ष होने के लिए: संस्करण 8.2 के लिए मैनुअल ने इसे पदावनत कहा: postgresql.org/docs/8.2/static/datatype-money.html
a_horse_with_no_name

11
@a_horse_with_no_name: आपका लिंक 2007 से एक थ्रेड पर है, जो तब भी है जब 8.2 वर्तमान संस्करण था और moneyप्रकार वास्तव में, हटा दिया गया था। मुद्दों को ठीक कर दिया गया है और बाद के संस्करणों में प्रकार को वापस जोड़ दिया गया है। व्यक्तिगत रूप से मैं मुद्रा का integerप्रतिनिधित्व सेंट के रूप में करना पसंद करता हूं ।
एरविन ब्रान्डेसटेटर

1
इरविन, आप अकेले डेटाबेस के नजरिए से सही सोच सकते हैं। हालाँकि, यदि आप Postgresql + Java को संयोजित करते हैं, तो यह बिल्कुल अच्छा नहीं है (मेरे अनुभव से)। आपकी टिप्पणी को पढ़ते हुए, मैंने अपने अधिकांश मुद्रा क्षेत्रों के लिए MONEY का उपयोग किया और अब मुझे यह जावा अपवाद मिलता है: " SQLException हुई: org.postgresql.util.PSQLException: टाइप डबल के लिए खराब मूल्य: 2,500.00 "। मैंने गुगली की है और कोई अच्छा समाधान नहीं मिला है, इसलिए मैं उन सभी को NUMERIC या DECALAL में बदलने के उबाऊ कार्य में हूँ !!!
एमडी

1
@MD: यह सुनने के लिए क्षमा करें, लेकिन मैंने स्पष्ट रूप से जावा (जो मैं नहीं कर सकता) के लिए बात नहीं की थी। त्रुटि संदेश विषम है। "डबल"? और हजारों विभाजक भी एक समस्या हो सकती है। आप उस बारे में एक नया सवाल शुरू करना चाह सकते हैं।
एरविन ब्रान्डेसटेटर

2
@PirateApp: हां, मेरा व्यक्तिगत पसंदीदा। आपने मेरे उत्तर के अंतिम वाक्य को याद किया होगा, बस इतना कहकर।
एरविन ब्रान्डेसटेटर

68

आपकी पसंद हैं:

  1. bigint: राशि को सेंट में स्टोर करें। यह वही है जो EFTPOS लेनदेन का उपयोग करता है।
  2. decimal(12,2): राशि को दो दशमलव स्थानों के साथ संग्रहित करें। यह सबसे सामान्य खाता बही सॉफ्टवेयर का उपयोग करता है।
  3. float: भयानक विचार - अपर्याप्त सटीकता। यह भोले डेवलपर्स का उपयोग करता है।

विकल्प 2 सबसे आम और सबसे आसान काम है। सटीक (मेरे उदाहरण में 12, सभी में 12 अंक) का अर्थ करें जितना बड़ा या छोटा आपके लिए सबसे अच्छा काम करता है।

ध्यान दें कि यदि आप कई लेन-देन एकत्र कर रहे हैं जो एक गणना का परिणाम था (उदाहरण के लिए एक विनिमय दर को शामिल करना) जिसमें एक भी मूल्य है जिसका व्यवसाय अर्थ है, सटीक सटीक मैक्रो मान प्रदान करने के लिए उच्चतर होना चाहिए; कुछ का उपयोग करने पर विचार करें decimal(18, 8)ताकि योग सटीक हो और प्रदर्शन के लिए व्यक्तिगत मानों को प्रतिशत सटीकता के लिए गोल किया जा सके।


10
यदि आप किसी भी प्रकार की रिवर्स टैक्स गणना या विदेशी मुद्रा के साथ काम कर रहे हैं, तो आपको कम से कम 4 दशमलव स्थानों की आवश्यकता है, या आप डेटा खो देंगे। तो numeric(15,4)या numeric(15,6)एक अच्छा विचार है।
पेट्रस थेरोन

3
एक 4 वाँ विकल्प है - वह है स्ट्रिंग का उपयोग करना और मेजबान भाषा में एक समान गैर-हानिरहित दशमलव प्रकार का उपयोग करना।
ioquatix

2
अगर एक स्केल किए गए पूर्णांक के बारे में, निश्चित रूप से 10000.045 भंडारण नहीं होता है अगर यह 1000x स्केलिंग कारक के साथ 10000045 के रूप में संग्रहीत किया गया था?
पाइरेटऐप

26

मैं अपने सभी मौद्रिक क्षेत्र इस प्रकार रखता हूं:

numeric(15,6)

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

यदि आप एक मुद्रा के अलावा कुछ नहीं करते हैं, तो सबसे बुरी बात यह है कि आपने कुछ जीरो स्टोर करने के लिए थोड़ी जगह बर्बाद की है।


6
यह ट्रंकेशन की कमी के कारण गलत परिणामों का जोखिम है। यदि नॉनज़ेरो मूल्यों को अनायास ही शेष दशमलव स्थानों में लीक कर देता है, उदाहरण के लिए, एक मूल्य फ़ील्ड जिसमें 0.333333 डॉलर हैं, तो आपके पास ऐसी स्थिति हो सकती है जहां सिस्टम $ 0.33 में 3 आइटम खरीदने वाले किसी व्यक्ति का परिणाम दिखाता है, $ 0.99 के बजाय $ 1.00 तक कुल।
पीटरिस जूल

1
पेरिटिस, तो आप इसके बजाय क्या सुझाव देते हैं? कोई फर्क नहीं पड़ता कि आप इस गोलाई में कितनी सटीकता फेंकते हैं, यह एक मुद्दा हो सकता है। मैं बस एक बेहतर तरीका नहीं मिला है, भले ही यह एक आदर्श नहीं है।
माइकल कोलेट

3
निश्चित बिंदु और जहां भी उचित हो, काट दें। जैसे ही आप "स्ट्राई" मनी वैल्यू तक पहुँचते हैं जैसे किसी ग्राहक को दिया जाने वाला मूल्य, यह उपयुक्त मेट्रिक्स में होना चाहिए, जो कि ज्यादातर मामलों में मानक खुदरा वातावरण में पूरे सेंट में होगा। यदि आपके पास अलग-अलग व्यावसायिक आवश्यकताएं हैं (उदाहरण के लिए प्रति यूनिट उच्च-मात्रा वाले सामान की कीमत), तो सटीकता की एक अलग सेटिंग हो सकती है, लेकिन आपको स्टोरेज के साथ प्रस्तुति का इलाज करना होगा - यदि आप x दशमलव (या इसके विपरीत) के साथ धन संख्या प्रदर्शित करते हैं, पूरे हजारों में उदाहरण के लिए) फिर आपको इसे उस सटीकता के साथ भी स्टोर करना चाहिए , कम नहीं, बल्कि अधिक नहीं।
पीटरिस

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

19

के रूप में संग्रहीत 64-बिट पूर्णांक का उपयोग करें bigint

मैं माइक्रो-डॉलर (या समान प्रमुख मुद्रा) का उपयोग करने की सलाह देता हूं। माइक्रो का मतलब है 1 मिलियन तो 1 माइक्रो-डॉलर = 0.000001।

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

1
यह सबसे सही उत्तर है और कोई भी उचित सॉफ्टवेयर हाथ में सबसे छोटी मुद्रा इकाई है। पूर्णांक पर सभी गणित करने का मतलब है कि आपको किसी भी भाषा-विशेष फ्लोट मैनिंग से निपटना नहीं है।
अवामंदर

1
उसका भी उपयोग कर रहे होंगे। धन्यवाद

यह numeric(15,6)एक और जवाब में क्यों सुझाया गया?
जूलियस गोंजा

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

1
आह, ठीक है, मैं भंडारण के बारे में हिस्सा याद किया। धन्यवाद! "सरल उपयोग करने और हर भाषा के साथ संगत" के बारे में दुर्भाग्य से जावास्क्रिप्ट 9007199254740991 तक पूर्णांकों का समर्थन करता है जो अधिकतम मूल्य से 1000 गुना अधिक है bigint। नहीं है developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... लेकिन यह सीमित समर्थन के साथ (अब के लिए) चेतावनियां (जैसे आप नहीं गुणा यह एक नाव के द्वारा आसानी से जब मुद्रा रूपांतरण कर सकते हैं) आता है और । यह देखते हुए कि माइक्रो-डॉलर का उपयोग करके आप जेएस पूर्णांक में अधिकतम स्टोर कर सकते हैं $ 9 बिलियन है जो शायद अभी भी अधिकांश मामलों के लिए अच्छा है।
जूलियस गोंजा

3

BigIntसबसे छोटी मुद्रा इकाई में मौद्रिक मूल्य का प्रतिनिधित्व करने वाले एक सकारात्मक पूर्णांक के रूप में मुद्रा को स्टोर करने के लिए उपयोग करें (जैसे, 100 सेंट $ 1.00 या 100 को स्टोर करने के लिए (100 (जापानी येन, एक शून्य-दशमलव मुद्रा)। यह वही है जो स्ट्राइप करता है - एक। वैश्विक ई-कॉमर्स के लिए सबसे महत्वपूर्ण वित्तीय सेवा कंपनियां।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.