[mysql] Best data type to store money values in MySQL

I want to store many records in a MySQL database. All of them contains money values. But I don't know how many digits will be inserted for each one.
Which data type do I have to use for this purpose?
VARCHAR or INT (or other numeric data types)?

This question is related to mysql sqldatatypes currency

The answer is


Try using

Decimal(19,4)

this usually works with every other DB as well


I prefer to use BIGINT, and store the values in by multiply with 100, so that it will become integer.

For e.g., to represent a currency value of 93.49, the value shall be stored as 9349, while displaying the value we can divide by 100 and display. This will occupy less storage space.

Caution:
Mostly we don't perform currency * currency multiplication, in case if we are doing it then divide the result with 100 and store, so that it returns to proper precision.


Storing money as BIGINT multiplied by 100 or more with the reason to use less storage space makes no sense in all "normal" situations.


At the time this question was asked nobody thought about Bitcoin price. In the case of BTC, it is probably insufficient to use DECIMAL(15,2). If the Bitcoin will rise to $100,000 or more, we will need at least DECIMAL(18,9) to support cryptocurrencies in our apps.

DECIMAL(18,9) takes 12 bytes of space in MySQL (4 bytes per 9 digits).


Multiplies 10000 and stores as BIGINT, like "Currency" in Visual Basic and Office. See https://msdn.microsoft.com/en-us/library/office/gg264338.aspx


You can use DECIMAL or NUMERIC both are same

The DECIMAL and NUMERIC types store exact numeric data values. These types are used when it is important to preserve exact precision, for example with monetary data. In MySQL, NUMERIC is implemented as DECIMAL, so the following remarks about DECIMAL apply equally to NUMERIC. : MySQL

i.e. DECIMAL(10,2)

Example settings

Good read


It depends on your need.

Using DECIMAL(10,2) usually is enough but if you need a little bit more precise values you can set DECIMAL(10,4).

If you work with big values replace 10 with 19.


If GAAP Compliance is required or you need 4 decimal places:

DECIMAL(13, 4) Which supports a max value of:

$999,999,999.9999

Otherwise, if 2 decimal places is enough: DECIMAL(13,2)

src: https://rietta.com/blog/best-data-types-for-currencymoney-in/


Indeed this relies on the programmer's preferences. I personally use: numeric(15,4) to conform to the Generally Accepted Accounting Principles (GAAP).


If your application needs to handle money values up to a trillion then this should work: 13,2 If you need to comply with GAAP (Generally Accepted Accounting Principles) then use: 13,4

Usually you should sum your money values at 13,4 before rounding of the output to 13,2.


We use double.

*gasp*

Why?

Because it can represent any 15 digit number with no constraints on where the decimal point is. All for a measly 8 bytes!

So it can represent:

  • 0.123456789012345
  • 123456789012345.0

...and anything in between.

This is useful because we're dealing with global currencies, and double can store the various numbers of decimal places we'll likely encounter.

A single double field can represent 999,999,999,999,999s in Japanese yens, 9,999,999,999,999.99s in US dollars and even 9,999,999.99999999s in bitcoins

If you try doing the same with decimal, you need decimal(30, 15) which costs 14 bytes.

Caveats

Of course, using double isn't without caveats.

However, it's not loss of accuracy as some tend to point out. Even though double itself may not be internally exact to the base 10 system, we can make it exact by rounding the value we pull from the database to its significant decimal places. If needed that is. (e.g. If it's going to be outputted, and base 10 representation is required.)

The caveats are, any time we perform arithmetic with it, we need to normalize the result (by rounding it to its significant decimal places) before:

  1. Performing comparisons on it.
  2. Writing it back to the database.

Another kind of caveat is, unlike decimal(m, d) where the database will prevent programs from inserting a number with more than m digits, no such validations exists with double. A program could insert a user inputted value of 20 digits and it'll end up being silently recorded as an inaccurate amount.


Examples related to mysql

Implement specialization in ER diagram How to post query parameters with Axios? PHP with MySQL 8.0+ error: The server requested authentication method unknown to the client Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver' phpMyAdmin - Error > Incorrect format parameter? Authentication plugin 'caching_sha2_password' is not supported How to resolve Unable to load authentication plugin 'caching_sha2_password' issue Connection Java-MySql : Public Key Retrieval is not allowed How to grant all privileges to root user in MySQL 8.0 MySQL 8.0 - Client does not support authentication protocol requested by server; consider upgrading MySQL client

Examples related to sqldatatypes

What does it mean when the size of a VARCHAR2 in Oracle is declared as 1 byte? How to get a list column names and datatypes of a table in PostgreSQL? How to display two digits after decimal point in SQL Server Conversion failed when converting the varchar value to data type int in sql Best data type to store money values in MySQL How to convert Nvarchar column to INT MySql: Tinyint (2) vs tinyint(1) - what is the difference? Is there any boolean type in Oracle databases? Appropriate datatype for holding percent values? How do you create a yes/no boolean field in SQL server?

Examples related to currency

Converting Float to Dollars and Cents Best data type to store money values in MySQL How to use GOOGLEFINANCE(("CURRENCY:EURAUD")) function What data type to use for money in Java? Cast a Double Variable to Decimal Yahoo Finance All Currencies quote API Documentation How can I correctly format currency using jquery? Currency format for display Print Currency Number Format in PHP Why not use Double or Float to represent currency?