OK, entonces sé que hay toneladas de artículos que dicen que no debo usar DOUBLE para almacenar dinero en una base de datos MySQL, o voy a terminar con errores de precisión difíciles. El punto es que no estoy diseñando una nueva base de datos, me pregunto para encontrar la manera de optimizar un sistema existente. La versión más nueva contiene 783 columnas de tipo DOBLE, la mayoría de las cuales se usan para almacenar dinero o fórmulas para calcular la cantidad de dinero.DOUBLE vs DECIMAL en MySQL
Así que mi primera opinión sobre el tema fue que recomiendo encarecidamente una conversión de DOUBLE a DECIMAL en la próxima versión, porque el doc de MySQL y todos dicen que sí. Pero entonces no pude encontrar ningún buen argumento para justificar esta recomendación, por tres razones:
- No realizamos ningún cálculo en la base de datos. Todas las operaciones se realizan en Java utilizando BigDecimal, y MySQL simplemente se usa como almacenamiento simple para obtener resultados.
- La precisión de 15 dígitos que ofrece un DOBLE es suficiente ya que almacenamos principalmente cantidades con 2 dígitos decimales, y ocasionalmente números pequeños con 8 dígitos decimales para los argumentos de fórmula.
- Tenemos un récord de producción de 6 años sin problemas conocidos de error debido a una pérdida de precisión en el lado de MySQL.
Incluso realizando operaciones en una tabla de filas de 18 millones, como SUM y multiplicaciones complejas, no pude realizar un error de falta de precisión. Y no hacemos este tipo de cosas en producción. Puedo mostrar la precisión perdido haciendo algo como
SELECT columnName * 1.000000000000000 FROM tableName;
Pero no puedo encontrar una manera de convertirlo en un error en el segundo dígito decimal. La mayoría de los problemas reales que encontré en Internet son entradas de foros de 2005 y anteriores, y no pude reproducir ninguno de ellos en un servidor MySQL 5.0.51.
Así que mientras no realicemos ninguna operación aritmética de SQL, lo cual no planeamos hacer, ¿hay algún problema que deberíamos esperar al solo almacenar y recuperar un monto de dinero en una columna DOBLE?
¿Calcula las cantidades imponibles en Java y las redondea según el contrato antes de almacenarlas? Por ejemplo, si vende un artículo de $ 1.47 y tiene un impuesto de ventas local del 8.25%, es posible que necesite registrar $ 0.121275 en impuestos.Me pregunto en qué forma está almacenando este tipo de campo en el DB, y si está redondeando a $ 0,12 antes de almacenar (o redondeando hasta $ 0,13, dependiendo de su localidad). – rajah9
Sí, calculamos los impuestos en Java, y almacenamos el precio del artículo, el importe del impuesto redondeado al 4º decimal y el precio total redondeado al 2º decimal. Por lo tanto, en su ejemplo, una fila contendría 1.47, 0.1213 y 1.59. El 8.25% se almacena en otro lugar como 0.08250000 y no se repite para cada venta. – user327961