El mejor tipo de datos para almacenar valores monetarios en MySQL


Quiero almacenar muchos registros en una base de datos MySQL. Todos ellos contienen valores monetarios. Pero no se cuántos dígitos se insertarán para cada uno.
¿Qué tipo de datos tengo que utilizar para este fin?
VARCHAR o INT (u otros tipos de datos numéricos)?

Author: shA.t, 2012-10-23

10 answers

Dado que el dinero necesita una representación exacta, no use tipos de datos que solo sean aproximados como float. Puede usar un tipo de datos numéricos de punto fijo para eso como

decimal(15,2)
  • 15 es la precisión (longitud total del valor incluyendo los decimales)
  • 2 es el número de dígitos después del punto decimal

Ver Tipos numéricos de MySQL :

Estos tipos se utilizan cuando es importante preservar la precisión exacta, por ejemplo con datos monetarios .

 299
Author: juergen d,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-26 14:05:04

Puedes usar DECIMAL o NUMERIC ambos son iguales

Los tipos DECIMAL y NUMÉRICO almacenan valores de datos numéricos exactos. Estos tipos se utilizan cuando es importante preservar la precisión exacta, por ejemplo con datos monetarios. En MySQL, NUMÉRICO se implementa como DECIMAL, por lo que las siguientes observaciones sobre DECIMAL se aplican igualmente a NUMÉRICO. : MySQL

i. e. DECIMAL(10,2)

Configuración de ejemplo

Buena lectura

 81
Author: NullPoiиteя,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-14 04:24:03

Depende de su necesidad.

Usar DECIMAL(10,2) generalmente es suficiente, pero si necesita valores un poco más precisos, puede establecer DECIMAL(10,4).

Si trabaja con valores grandes, reemplace 10 por 19.

 26
Author: Svetoslav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-28 11:02:53

Prefiero usar BIGINT, y almacenar los valores en multiplicar por 100, de modo que se convertirá en entero.

Por ejemplo, para representar un valor de moneda de 93.49, el valor se almacenará como 9349, mientras se muestra el valor que podemos dividir por 100 y mostrar. Esto ocupará menos espacio de almacenamiento.

Precaución:
En su mayoría no realizamos currency * currency multiplicación, en caso de que si lo estamos haciendo, dividimos el resultado con 100 y almacenamos, de modo que vuelve a la precisión adecuada.

 24
Author: Dinesh P.R.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-28 09:58:25

Si su aplicación necesita manejar valores monetarios de hasta un billón, esto debería funcionar: 13,2 Si necesita cumplir con los GAAP (Principios de Contabilidad Generalmente Aceptados), utilice: 13,4

Por lo general, debe sumar sus valores monetarios a 13,4 antes de redondear la salida a 13,2.

 13
Author: david.ee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-28 23:40:05

De hecho, esto depende de las preferencias del programador. Yo personalmente uso: numeric(15,4) para cumplir con los Principios de Contabilidad Generalmente Aceptados (GAAP).

 3
Author: Chagbert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-28 10:07:41

Intenta usar

Decimal(19,4)

Esto generalmente funciona con todos los otros DB también

 2
Author: Deepesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-05 09:40:03

En el momento en que se hizo esta pregunta, nadie pensó en el precio de Bitcoin. En el caso de BTC, es probablemente insuficiente usar DECIMAL(15,2). Si el Bitcoin subirá a $100,000 o más, necesitaremos al menos DECIMAL(18,9) para admitir criptomonedas en nuestras aplicaciones.

DECIMAL(18,9) toma 12 bytes de espacio en MySQL (4 bytes por 9 dígitos).

 2
Author: bizwiz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-06 10:34:30

Usamos double.

*gasp *

¿Por qué?

Porque puede representar cualquier número de 15 dígitos sin restricciones sobre dónde está el punto decimal. ¡Todo por unos míseros 8 bytes!

Así que puede representar:

  • 0.123456789012345
  • 123456789012345.0

...y cualquier cosa en el medio.

Esto es útil porque estamos tratando con monedas globales , y double puede almacenar los diversos números de lugares decimales que probable encuentro.

Un solo campo double puede representar 999,999,999,999,999 s en yenes japoneses, 9,999,999,999,999.99 s en dólares estadounidenses e incluso 9,999,999. 999999999 s en bitcoins

Si intenta hacer lo mismo con decimal, necesita decimal(30, 15) que cuesta 14 bytes.

Advertencias

Por supuesto, usar double no está exento de advertencias.

Sin embargo, no es pérdida de precisión como algunos tienden a señalar. Aunque double en sí mismo puede no ser internamente exacto para el sistema base 10 , podemos hacerlo exacto al redondear el valor que extraemos de la base de datos a sus decimales significativos. Si es necesario. (e. g. Si va a ser outputted, y se requiere la representación de la base 10.)

Las advertencias son, cada vez que realizamos aritmética con él, necesitamos normalizar el resultado (redondeándolo a sus decimales significativos) antes de:

  1. Realizar comparaciones en él.
  2. Escribiendo de nuevo a la base.

Otro tipo de advertencia es que, a diferencia de decimal(m, d) donde la base de datos evitará que los programas inserten un número con más de m dígitos, no existen tales validaciones con double. Un programa podría insertar un valor ingresado por el usuario de 20 dígitos y terminará siendo registrado silenciosamente como una cantidad inexacta.

 1
Author: antak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-03 07:12:28

Multiplica 10000 y almacena como BIGINT, como "Currency" en Visual Basic y Office. Véase https://msdn.microsoft.com/en-us/library/office/gg264338.aspx

 0
Author: auntyellow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-08 13:09:48