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)?
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 .
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)
Buena lectura
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
.
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 realizamoscurrency * 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.
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.
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).
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
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).
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:
- Realizar comparaciones en él.
- 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.
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
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