declarar - El mejor tipo de datos para almacenar valores de moneda en una base de datos MySQL
sql data types (9)
Aunque esto puede ser tarde, pero será útil para otra persona. De mi experiencia e investigación he llegado a conocer y aceptar el decimal (19, 6). Eso es cuando se trabaja con php y mysql. Cuando se trabaja con gran cantidad de dinero y tipo de cambio.
¿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.
Depende de la naturaleza de los datos. Necesitas contemplarlo de antemano.
Mi caso
- decimal (13,4) sin firmar para registrar transacciones de dinero
- almacenamiento eficiente (4 bytes para cada lado del punto decimal de todos modos) 1
- Cumple con GAAP
- decimal (19,4) sin firmar para agregados
- Necesitamos más espacio para los totales de múltiples transacciones multimillonarias.
- semi-cumplimiento con el tipo de datos de MS Currency no hará daño a 2
- tomará más espacio por registro (11 bytes - 7 a la izquierda y 4 a la derecha), pero esto está bien ya que hay menos registros para los agregados 1
- decimal (10,5) para los tipos de cambio
- normalmente se citan con 5 dígitos en total, por lo que puede encontrar valores como 1.2345 y 12.345 pero no 12345.67890
- es una convención generalizada, pero no es un estándar codificado (al menos según mi conocimiento de búsqueda rápida)
- puede hacer que sea 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 centavos.
- hay equivalentes de dinero como "Unidad de Fermento", "CLF" expresado con 4 lugares decimales significativos 3 , 4
- es compatible con GAAP
Compensación
- menor precisión:
- menos costo de almacenamiento
- cálculos más rápidos
- menor riesgo de error de cálculo
- copia de seguridad y restauración más rápidas
- 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 usar 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 y precisión máximas en RDBMS más comunes:
Precision Scale Oracle 31 31 T-SQL 38 38 MySQL 65 30 PostgreSQL 131072 16383
Razonable Extremo
- ¿Por qué (27,4)?
- nunca se sabe cuando el sistema necesita almacenar dólares zimbabuenses
Septiembre de 2015, el gobierno de Zimbabue declaró que cambiaría dólares de Zimbabwe por dólares estadounidenses a una tasa de 1 USD a 35 cuatrillones de dólares de Zimbabwe 5
Tendemos a decir "sí, claro ... no necesitaré esas figuras locas". Bueno, los zimbabuenses solían decir eso también. No hace mucho tiempo.
Imaginemos que necesita registrar una transacción de 1 millón de USD en dólares zimbabuenses (quizás poco probable hoy, pero ¿quién sabe cómo se verá esto dentro de 10 años a partir de ahora?).
- (1 millón de USD) * (35 Quadrylion ZWL) = (10 ^ 6) * (35 * 10 ^ 15) = 35 * 10 ^ 21
- necesitamos:
- 2 dígitos para almacenar "35"
- 21 dígitos para almacenar los ceros.
- 4 dígitos a la derecha del punto decimal
- esto hace decimal (27,4) que nos cuesta 15 bytes por cada entrada
- podemos agregar un dígito más a la izquierda sin costo alguno: tenemos un decimal (28,4) para 15 bytes
- Ahora podemos almacenar 10 millones de transacciones en dólares expresados en dólares zimbabuenses, o protegernos de otra huelga de hiperinflación, lo que con suerte no sucederá
La 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 no se pudo insertar un registro en nuestra tabla de tarifas, porque una de las columnas (GrossRate) está configurada en decimal (11,4), y nuestro departamento de productos acaba de obtener un contrato para habitaciones en un resort increíble 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 se diseñó hace 10 años.
Lo único que debes tener en cuenta es 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)
Para las aplicaciones de contabilidad, es muy común almacenar los valores como enteros (algunos incluso llegan a decir que es la única forma). Para tener una idea, tome el monto de las transacciones (supongamos $ 100.23) y múltiplo por 100, 1000, 10000, etc. para obtener la precisión que necesita. Entonces, si solo necesita almacenar centavos y puede redondear hacia arriba o hacia abajo de manera segura, simplemente multiplique por 100. En mi ejemplo, eso haría 10023 como el número entero para almacenar. Ahorrarás espacio en la base de datos y comparar dos enteros es mucho más fácil que comparar dos flotantes. Mis $ 0.02.
Podría usar algo como DECIMAL(19,2)
de forma predeterminada para todos sus valores monetarios, pero si solo almacena valores inferiores a $ 1,000, eso 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 esperas que se almacene en ese campo + 5
. Entonces, si nunca espera almacenar ningún valor superior a 999999.99, DECIMAL(11,2)
debería ser más que suficiente (hasta que las expectativas cambien).
Si desea ser compatible con GAAP , puede ir con DECIMAL(N,4)
, donde el valor de N
es al menos el número de dígitos antes de .
de la suma más grande que esperas que se almacene en ese campo + 7
.
También es importante calcular cuántos decimales pueden requerirse 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 la acción cotizado tenía que almacenarse con 7 dígitos de precisión.
entrada super tardía pero GAAP es una buena regla de oro ..
Si su aplicación necesita manejar valores monetarios de hasta un billón, entonces 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 en 13,4 antes de redondear la producción a 13,2.
Fuente: El mejor tipo de datos para almacenar valor monetario en MySQL
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.