How to store & process currencies in mysql / zend framework - mysql

We want to store product prices and weight (kg/pound) in MySQL. Can somebody tell me what's the best way to do this?
double/decimal/... ?
We need to be able to display both USD and EURos.
I don't know if it helps, but we use the Zend framework to build our application.

Have you looked at the Zend_Currency family of functions?
This component works with all available locales and therefore knows about more than 100 different localized currencies. This includes informations like currency names, abbreviations, money signs and much more.
Zend_Currency has the advantage that already defined currency representations can be reused. You could also have 2 different representations for the same currency.
Zend_Currency allows you also to calculate with currency values. Therefore, it provides you an interface to exchange services.
If you like that part of the Zend Framework, I guess a lot of decisions will "sort themselves out" based on what they use to work with the values.

for currency use decimal
from http://dev.mysql.com/doc/refman/5.1/en/numeric-types.html :
The DECIMAL and NUMERIC data types are used to store exact numeric data values. In MySQL, NUMERIC is implemented as DECIMAL. These types are used to store values for which it is important to preserve exact precision, for example with monetary data.

We always use decimal and add a currency_id field to denote currency.
You can create a currency table with id, and name, and sign and join it on queries for price.

Related

Microsoft Access Automatically Increase Decimal

Hi My Fellow Access user.
I am using Access to do reconciliation, by link two Excel sheets. the number are two decimal.
Linked Table view
However, when i was trying to run subtraction between two numbers both 2 decimals, it return results like this:
Appreciate if anyone know how this could happen, and what steps I need to take to fix it?
Thanks
Tian
Don't use the linked Excel data directly.
Create simple select queries where you can convert and trim your data. Like:
Select SomeField, Description, CCur([TotalAmount]) As Total
From YourLinkedExcelTable
When dealing with amounts, always use Currency as data type.
Now, calculate your Diff using the query.
For a linked Excel sheet, the column type is probably Double, a 64-bit floating point number. This problem you experience is probably due to an inherent limitation of floating point numbers and is not unique to Excel or Access.
This Stack Overflow question asks essentially the same thing: Why does this subtraction not equal zero?
Excel is no exception, only that the default formatting might not show the necessary precision to reveal the behavior. Selecting scientific format or increasing the number of displayed decimal places will reveal the same behavior.
Consider the following:
For monetary amounts, convert values to Currency using the CCur() function. Currency is a fixed-decimal value, but be aware it only has 4 digits to the right of the decimal. (Updated to reflect advice from Gustav)
Convert values to fixed-point Decimal type using CDec() function before performing the math. There is no native VBA Decimal type, so these are variants containing Decimal values. But upon conversion back to floating-point, it is still possible to experience extra digits.
Round the results using the Round() function, but again this is not guaranteed to eliminate floating-point limitations.
Choose an explicit format for displaying the numbers.

Microsoft Access decimal representation

I have a MS Access 2010 database with a products table. The price column is a single datatype with format set to Fixed(2). There are certain values that are not being represented correctly, and I've no idea why. For example, one price is shown in the table as 1.52. However, if I export to Excel, or view it in a form with the Currency format, I see that Access has really stored 1.51999998092651. No matter what I do, I can't seem to change the value to represent the 0.20 correctly.
I know that computers store reals as approximations, but this seems rather ridiculous. Any ideas what's going on here and how I can fix it?
Replace 'Single' datatype to 'Currency', or at least to 'Double'.
Floating point numbers in common do not have accurate binary representation. Certainly 'Double' type will have less mistakes. So you need to use fixed point numbers, named 'Currency' in ms access. But they have limited precession 15 digits before and 4 digits after point.
P.S. You have to change type, not format.

Storing currency values in MySQL database

This question has been asked many times before, but I've found conflicting opinions on the topic so I thought I would bring it up again in hopes of a more unified conclusion.
I would like to store a currency value in my database. Let's assume all entries are the same type of currency (USD for example) and that both positive and negative values are allowed.
My initial thought would be to store the value as a signed integer in terms of the smallest unit of the associated currency. For example, if I want to store the value $1.25, I would insert 125 into the database, since the smallest unit of USD is $0.01. The nice thing about this method is that MySQL will automatically round to the nearest integer. For example, if the dollar value is $1.259, I could insert 125.9, which would automatically be rounded and stored as 126 or $1.26.
So, what do you think? Is this a sound approach or is there a better way?
Financial data can be stored as DECIMAL(p,s) where p is the number of significant digits, and s is the scale (number of places to the right of the decimal point). See The MySQL documentation.
Also from O'Reilly's High Performance MySQL, chapter 3:
"...you should use DECIMAL only when you need exact results for
fractional numbers--for example, when storing financial data."
From O'Reilly's Learning MySQL:
DECIMAL is, "...A commonly used numeric type. Stores a fixed-point
number such as a salary or distance..."
And MySQL Pocket Reference:
DECIMAL "...Stores floating-point numbers where precision is
critical, such as for monetary values."
There is nothing wrong with the approach you describe. There is no right or wrong when it comes to this question.
You have to keep in mind that to display a $ value to the user, you would need to always do a division operation or some kind of formatting.
Will it be easier to debug your formulas/calculations if everything was in cents or dollars? Will you be displaying the values in cents or dollars? etc.
Keep it simple, but either way you'll have to use a decimal.

Is it good practice to use a pivot currency when converting currencies?

In microsoft's documention they use a pivot currency exchange rate:
"The currency conversion functionality converts such transactions into the pivot currency, and then to one or more other reporting currencies."
But in another article, they demo converting direct from any currency to any other currency (skipping the pivot).
Just curious as to why, in most documented examples, people use the pivot method - where as the non-pivot method seems less used? Is there any advantages/disadvantages of either?
By using the pivot method you only need to keep track of the exchange rates for that one currency (to all other currencies), so if you handle n currencies, you have n exchange rates to track, rather than n²-n.
Storing all n²-n exchange rates is redundant data storage since you can get by with just n and calculate all currency exchanges using the pivot method.
Most folk use a base or accounting currency.
That is, you'll have exchange rates against this (on my case CHF). So USDCHF, EURCHF etc. I had to do everything via CHF.
For 30 rates, you either use 30 pairs (includes CHFCHF) or all 900+ combinations precalculated (EURUSD and USDEUR)

Datatype for unit of measurement in database

For my application I need to keep the prefered unit of measurement of a user.
The possible units currently are:
Liter (the unit the values in the rest of my database are stored in)
Kilogram (varries with the density of the products)
US Liquid Gallon (3.785411784 litres)
US Liquid Quart (1/4th of above)
UK Liquid Gallon (4.54609 litres)
UK Liquid Quart (1/4th of above)
I need a way to save these units in an mssql 2005 (and up) database so that there can be no ambiguity and preferably without all the applications keeping an enumeration and without having to create an extra table.
Using an ISO abbreviation would work for the first two, but AFAIK there is none for the last four.
Using the string representation is also asking for trouble..
So besides of finally getting through to the project manager about not using retarded units of measurement, what other suggestions do you have?
I know you don't want to create a new table, but in all honesty, it's the Right Thing™ to do. Add a column with a foreign key reference, and just do it - it'll work better in the end!
I think you need to reconsider using a table to store these values. The main reason being that you will want to convert from one unit of measure to another and you need to decide on the number of significant digits that is important to your application.
If you have a table, then you can store the litre to X conversion value in the record. This will help keeping all of the other applications in sync in order to reduce rounding and comparison problems.