El mejor tipo de datos para almacenar valores de moneda en una base de datos MySQL


¿Cuál es el mejor tipo de datos SQL para los valores de moneda? Estoy usando MySQL, pero preferiría un tipo de base de datos independiente.

Author: John Slegers, 2009-03-10

9 answers

Algo como Decimal(19,4) generalmente funciona bastante bien en la mayoría de los casos. Puede ajustar la escala y la precisión para adaptarse a las necesidades de los números que necesita almacenar. Incluso en SQL Server, tiendo a no usar " money" ya que no es estándar.

 217
Author: Kibbee,
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:12:25

Lo único que debes tener en cuenta es que si migras de una base de datos a otra, puedes encontrar que DECIMAL(19,4) y DECIMAL(19,4) significan cosas diferentes

( http://dev.mysql.com/doc/refman/5.1/en/precision-math-decimal-changes.html )

    DBASE: 10,5 (10 integer, 5 decimal)
    MYSQL: 15,5 (15 digits, 10 integer (15-5), 5 decimal)
 47
Author: SeanJA,
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
2009-03-10 02:13:16

También es importante calcular cuántos decimales pueden ser necesarios para sus cálculos.

Trabajé en una aplicación de precio de acciones que requería el cálculo del precio de un millón de acciones. El precio de las acciones cotizadas tuvo que almacenarse a 7 dígitos de precisión.

 17
Author: Leah,
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
2009-03-10 02:34:09

Respuesta de Assaf de

Depende de cuánto dinero tienes...

Suena frívolo, pero en realidad es pertinente.

Solo hoy tuvimos un problema en el que un registro no se insertó en nuestra tabla de tarifas, porque una de las columnas (Tasa bruta) se establece en decimal (11,4), y nuestro departamento de Productos acaba de obtener un contrato para habitaciones en un increíble resort en Bora Bora, que se venden por varios millones de francos del Pacífico por noche... algo que nunca fue anticuado cuando el esquema de la base de datos fue diseñado hace 10 años.

 17
Author: Scott Ferguson,
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
2012-10-27 18:13:53

Para aplicaciones de contabilidad es muy común almacenar los valores como enteros (algunos incluso van tan lejos como para decir que es la única manera). Para tener una idea, tome la cantidad de las transacciones (supongamos $100.23) y múltiples por 100, 1000, 10000, etc. para obtener la precisión que necesita. Así que si solo necesita almacenar centavos y puede redondear de forma segura hacia arriba o hacia abajo, simplemente multiplique por 100. En mi ejemplo, que haría 10023 como el entero a almacenar. Ahorrará espacio en la base de datos y comparará dos los enteros es mucho más fácil que comparar dos flotadores. Mi $0.02.

 10
Author: Dane Bendixen,
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
2013-08-24 04:52:15

Entrada super tardía pero GAAP es una buena regla general..

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), use: 13,4

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

Fuente: El mejor tipo de datos para almacenar el valor monetario en MySQL

 7
Author: Damian,
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-05-23 10:31:02

Podría usar algo como DECIMAL(19,2) por defecto para todos sus valores monetarios, pero si solo almacenará valores inferiores a $1,000, eso solo será un desperdicio de valioso espacio en la base de datos.

Para la mayoría de las implementaciones, DECIMAL(N,2) sería suficiente, donde el valor de N es al menos el número de dígitos antes de . de la suma más grande que se espera que se almacene en ese campo + 5. Por lo tanto, si nunca espera almacenar valores superiores a 999999.99, DECIMAL(11,2) debería ser más que suficiente (hasta que cambien las expectativas).

Si quieres ser GAAP obediente, usted podría ir con DECIMAL(N,4), donde el valor de N es al menos el número de dígitos antes del . de la suma más grande que usted espera que se almacene en ese campo + 7.

 5
Author: John Slegers,
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-08 00:05:41

Depende de la naturaleza de los datos. Necesitas contemplarlo de antemano.

Mi caso

  • decimal(13,4) sin firmar para registrar transacciones monetarias
    • almacenamiento eficiente (4 bytes para cada lado del punto decimal de todos modos) 1
    • Cumple los GAAP
  • decimal (19,4) sin signo para agregados
    • necesitamos más espacio para los totales de múltiples transacciones multimillonarias
    • el semiacondicionamiento con el tipo de datos MS Currency no hurt 2
    • tomará más espacio por registro (11 bytes - 7 izquierda y 4 derecha), pero esto está bien ya que hay menos registros para agregados 1
  • decimal(10,5) para los tipos de cambio
    • normalmente se citan con 5 dígitos en total para que pueda encontrar valores como 1.2345 y 12.345 pero no 12345.67890
    • es una convención generalizada, pero no un estándar codificado (al menos para mi conocimiento de búsqueda rápida)
    • usted podría hacerlo decimal (18,9) con el mismo almacenamiento, pero las restricciones de tipo de datos son un valioso mecanismo de validación incorporado

¿Por qué (M, 4)?

  • hay monedas que se dividen en mil peniques
  • hay equivalentes monetarios como "Unidad de Fermento", " CLF " expresado con 4 decimales significativos3,4
  • cumple los GAAP

Compensación

  • menor precisión:
    • menos almacenamiento costo
    • cálculos más rápidos
    • menor riesgo de error de cálculo
    • copia de seguridad y restauración más rápida
  • mayor precisión:
    • compatibilidad futura (los números tienden a crecer)
    • ahorro de tiempo de desarrollo (no tendrá que reconstruir la mitad de un sistema cuando se cumplan los límites)
    • menor riesgo de fallo de producción debido a una precisión de almacenamiento insuficiente

Compatible Extreme

Aunque MySQL le permite utilizar decimal(65,30), 31 para escala y 30 para precisión parecen ser nuestros límites si queremos dejar abierta la opción de transferencia.

Escala máxima y precisión en los RDBMS más comunes:

            Precision   Scale
Oracle      31          31
T-SQL       38          38
MySQL       65          30
PostgreSQL  131072      16383

6, 7, 8, 9

Extremo razonable

  1. ¿Por qué (27,4)?
    • nunca se sabe cuándo el sistema necesita almacenar dólares zimbabuenses

Septiembre 2015 El gobierno de Zimbabue declaró que intercambiaría Dólares zimbabuenses por dólares estadounidenses a una tasa de 1 USD a 35 cuatrillones de dólares zimbabuenses 5

Tendemos a decir "sí, claro... No necesitaré esas figuras locas". Bueno, los zimbabuenses solían decir eso también. No hace mucho.

Imaginemos que necesita registrar una transacción de 1 millón de USD en dólares zimbabuenses (tal vez improbable hoy, pero quién sabe cómo se verá dentro de 10 años?).

  1. (1 millón USD) * (35 Cuadrilion ZWL) = (10^6 ) * (35 * 10^15) = 35 * 10^21
  2. necesitamos:
    • 2 dígitos para almacenar"35"
    • 21 dígitos para almacenar los ceros
    • 4 dígitos a la derecha del punto decimal
  3. esto hace decimal (27,4) que nos cuesta 15 bytes por cada entrada
  4. podemos agregar un dígito más a la izquierda sin costo-tenemos decimal(28,4) para 15 bytes
  5. Ahora podemos almacenar 10 millones de USD transacción expresada en dólares zimbabuenses, o seguro de otra huelga de hiperinflación, que con suerte no sucederá
 2
Author: kshishkin,
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-04-01 04:43:48

Aunque esto puede ser tarde, pero será útil para alguien más.De mi experiencia e investigación he llegado a conocer y aceptar decimal (19, 6).Eso es cuando se trabaja con php y mysql. cuando se trabaja con gran cantidad de dinero y tipo de cambio

 0
Author: precious,
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-10-05 07:43:26