1. 背景
* MySQL支持的浮点类型中有单精度类型(float), 双精度类型(double),和高精度类型(decimal),在数字货币类型中推荐使用高精度类型(decimal)来进行应用.
* MySQL浮点型和定点型可以用类型名称后加(M,D)来表示,M表示该值的总共长度,D表示小数点后面的长度,M和D又称为精度和标度,如float(7,4)的可显示为-999.9999,MySQL保存值时进行四舍五入,如果插入999.00009,则结果为999.0001。FLOAT和DOUBLE在不指定精度时,默认会按照实际的精度来显示,而DECIMAL在不指定精度时,默认整数为10,小数为0。
2. 整数类型所需的存储和值范围
类型 | 占用空间 | 精度 | 精确性 |
FLOAT | 4 | 单精度 | 精确到小数点后7位小数 |
DOUBLE | 8 | 双精度 | 精确到小数点后15位小数 |
DECIMAL | 变长 | 高精度 | 精确到小数点后65位小数 |
3. 浮点数应用中的 M / G * G (!=|=)(不一定等于) M
M = 3.1415 G = 2.1542,统一精确到小数点后6位
* 单精度(float)应用
* 创建float_test 表
1
2
3
4
5
|
mysql> CREATE TABLE float_test( -> m FLOAT(10,6),
-> g FLOAT(10,6)
-> )ENGINE=INNODB CHARSET=utf8mb4;
Query OK, 0 rows affected (0.06 sec) |
* 插入 m 与 g 的数据
1
2
3
4
5
6
7
8
9
10
11
|
mysql> INSERT INTO float_test SELECT 3.1415,2.1542; Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> select * from float_test;
+----------+----------+ | m | g | +----------+----------+ | 3.141500 | 2.154200 | +----------+----------+ 1 row in set (0.00 sec)
|
* 进行 M / G * G 运算
1
2
3
4
5
6
7
|
mysql> SELECT m / g * g, m FROM float_test; +--------------+----------+ | m / g * g | m | +--------------+----------+ | 3.1414999962 | 3.141500 | +--------------+----------+ 1 row in set (0.00 sec)
|
* 双精度(double)应用
* 创建double_test 表
1
2
3
4
5
|
mysql> CREATE TABLE double_test( -> m DOUBLE(10,6),
-> g DOUBLE(10,6)
-> )ENGINE=INNODB CHARSET=utf8mb4;
Query OK, 0 rows affected (0.08 sec) |
* 插入 m 与 g 的数据
1
2
3
4
5
6
7
8
9
10
11
|
mysql> INSERT INTO double_test SELECT 3.1415,2.1542; Query OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> select * from double_test;
+----------+----------+ | m | g | +----------+----------+ | 3.141500 | 2.154200 | +----------+----------+ 1 row in set (0.00 sec)
|
* 进行 M / G * G 运算
1
2
3
4
5
6
7
|
mysql> SELECT m / g * g, m FROM double_test; +--------------+----------+ | m / g * g | m | +--------------+----------+ | 3.1415000000 | 3.141500 | +--------------+----------+ 1 row in set (0.01 sec)
|
* 高精度(decimal)应用
* 创建decimal_test 表
1
2
3
4
5
|
mysql> CREATE TABLE decimal_test( -> m DECIMAL(10,6),
-> g DECIMAL(10,6)
-> )ENGINE=INNODB CHARSET=utf8mb4;
Query OK, 0 rows affected (0.05 sec) |
* 插入 m 与 g 的数据
1
2
3
4
5
6
7
8
9
10
11
|
mysql> INSERT INTO decimal_test SELECT 3.1415,2.1542; Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM decimal_test; +----------+----------+ | m | g | +----------+----------+ | 3.141500 | 2.154200 | +----------+----------+ 1 row in set (0.00 sec)
|
* 进行 M / G * G 运算
1
2
3
4
5
6
7
|
mysql> SELECT m / g * g, m FROM decimal_test; +--------------------+----------+ | m / g * g | m | +--------------------+----------+ | 3.1415000000000000 | 3.141500 | +--------------------+----------+ 1 row in set (0.00 sec)
|
4. 浮点类型应用总结
* 浮点数如果不写精度和标度,则会按照实际显示
* 如果有精度和标度,则会将数据四舍五入后插入,系统不报错
* DECIMAL如果不设置精度和标度,刚按照默认的(10,0)进行操作,如果数据超过了精度和标度值,则会报错。
* 账务、账务系统必须要用DECIMAL类型确定精确与资金安全。
5. 总结
以需求驱动技术,技术本身没有优略之分,只有业务之分。