MySQL中Decimal类型和Float Double的区别 & BigDecimal与Double使用场景
MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型。
其区别在于,float,double等非标准类型,在DB中保存的是近似值,而Decimal则以字符串的形式保存数值。
float,double类型是可以存浮点数(即小数类型),但是float有个坏处,当你给定的数据是整数的时候,那么它就以整数给你处理。这样我们在存取货币值的时候自然遇到问题,我的default值为:0.00而实际存储是0,同样我存取货币为12.00,实际存储是12。
幸好mysql提供了两个数据类型:decimal,这种数据类型可以轻松解决上面的问题:decimal类型被 MySQL 以同样的类型实现,这在 SQL92 标准中是允许的。他们用于保存对准确精度有重要要求的值,例如与金钱有关的数据。
数据定义
float(M,S) M为全长,S为小数点后长度。
数据库类型和Java类型之间的关系:
DBC Type Java Type
CHAR String
VARCHAR String
LONGVARCHAR String
NUMERIC java.math.BigDecimal
DECIMAL java.math.BigDecimal
BIT boolean
BOOLEAN boolean
TINYINT byte
SMALLINT short
INTEGER int
BIGINT long
REAL float
FLOAT double
DOUBLE double
BINARY byte[]
VARBINARY byte[]
LONGVARBINARY byte[]
DATE java.sql.Date
TIME java.sql.Time
TIMESTAMP java.sql.Timestamp
CLOB Clob
BLOB Blob
ARRAY Array
DISTINCT mapping of underlying type
STRUCT Struct
REF Ref
项目中BigDecimal与Double使用场景
金额要用BigDecimal
金额计算不能用doube!!!!
金额计算必须用BigDecimal,下面对比一下用double 跟BigDecimal的区别。先看一个小例子:
请看题:
示例1
问, 结果是多少? 0.01?
No! 结果是0.009999999999999998!
为什么会这样呢? 因为float和double都是浮点数, 都有取值范围, 都有精度范围. 浮点数与通常使用的小数不同, 使用中, 往往难以确定.
常见的问题是定义了一个浮点数, 经过一系列的计算, 它本来应该等于某个确定值, 但实际上并不是!
double相减会转换成二进制,因double有效位数为 16位这就会出现存储小数位数不够的情况,这种情况下就会出现误差,解决方法就是使用BigDecimal,它的有效长度足够长可存储小数位数。
因此可代替double来进行加减乘除, 金额必须是完全精确的计算, 故不能使用double或者float, 而应该采用java.math.BigDecimal.
加减乘除
两个BigDecimal值应该怎样进行加减乘除呢? +, -, *, / 这样写吗? 不!
请看示例:
加减乘除使用了英文的加减乘除, 即add, substract, multiply和divide
大小比较
两个BigDecimal值怎么比较大小呢? 能用>或者<吗? 也不可以!
两个BigDecimal值比较使用compareTo方法, 比较结果有-1, 0, 1, 分别表示小于, 等于, 大于; 对于0, 可以使用BigDecimal.ZERO表示!
四舍五入
简化BigDecimal计算的小工具类
如果我们要做一个加法运算,需要先将两个浮点数转为String,然后够造成BigDecimal,在其中一个上调用add方法,传入另一个作为参数,然后把运算的结果(BigDecimal)再转换为浮点数。
你能够忍受这么烦琐的过程吗?
网上提供的工具类Arith来简化操作。它提供以下静态方法,包括加减乘除和四舍五入:
public static double add(double v1,double v2)
public static double sub(double v1,double v2)
public static double mul(double v1,double v2)
public static double div(double v1,double v2)
public static double div(double v1,double v2,int scale)
public static double round(double v,int scale)
定点数和浮点数的区别
在计算机系统的发展过程中,曾经提出过多种方法表达实数。典型的比如相对于浮点数的定点数(Fixed Point Number)。在这种表达方式中,小数点固定的位于实数所有数字中间的某个位置。
货币的表达就可以使用这种方式,比如 99.00 或者 00.99 可以用于表达具有四位精度(Precision),小数点后有两位的货币值。由于小数点位置固定,所以可以直接用四位数值来表达相应的数值。
SQL 中的 NUMBER 数据类型就是利用定点数来定义的。还有一种提议的表达方式为有理数表达方式,即用两个整数的比值来表达实数。
定点数表达法的缺点在于其形式过于僵硬,固定的小数点位置决定了固定位数的整数部分和小数部分,不利于同时表达特别大的数或者特别小的数。
最终,绝大多数现代的计算机系统采纳了所谓的浮点数表达方式。这种表达方式利用科学计数法来表达实数,即用一个尾数(Mantissa ),一个基数(Base),一个指数(Exponent)以及一个表示正负的符号来表达实数。
比如 123.45 用十进制科学计数法可以表达为 1.2345 × 102 ,其中 1.2345 为尾数,10 为基数,2 为指数。浮点数利用指数达到了浮动小数点的效果,从而可以灵活地表达更大范围的实数。
在MySQL中使用浮点数类型和定点数类型来表示小数。浮点数类型包括单精度浮点数(FLOAT型)和双精度浮点数(DOUBLE型)。定点数类型就是DECIMAL型。MySQL的浮点数类型和定点数类型如下表所示:
类型名称 | 字节数 | 负数的取值范围 | 非负数的取值范围 |
---|---|---|---|
FLOAT | 4 | -3.402823466E+38~ -1.175494351E-38 |
0和1.175494351E-38~ 3.402823466E+38 |
DOUBLE | 8 | -1.7976931348623157E+308~ -2.2250738585072014E-308 |
0和2.2250738585072014E-308~ 1.7976931348623157E+308 |
DECIMAL(M,D)或DEC(M,D) | M+2 | 同DOUBLE型 | 同DOUBLE型 |
从上表中可以看出,DECIMAL型的取值范围与DOUBLE相同。但是,DECIMAL的有效取值范围由M和D决定,而且DECIMAL型的字节数是M+2,也就是说,定点数的存储空间是根据其精度决定的。
MySQL
BigDecimal在进行入库时, 数据库选择decimal类型, 长度可以自定义, 如18; 小数点我们项目中用的是2, 保留2位小数. 此外还要注意的就是默认值, 一定写成0.00, 不要用默认的NULL, 否则在进行加减排序等操作时, 会带来转换的麻烦!
`balance` decimal(18,2) DEFAULT '0.00' COMMENT '账户余额',
MySQL DECIMAL
数据类型用于在数据库中存储精确的数值。我们经常将DECIMAL
数据类型用于保留准确精确度的列,例如会计系统中的货币数据。
要定义数据类型为DECIMAL
的列,请使用以下语法:
1
|
column_name DECIMAL (P,D); |
在上面的语法中:
P
是表示有效数字数的精度。P
范围为1〜65
。D
是表示小数点后的位数。D
的范围是0
~30
。MySQL要求D
小于或等于(<=
)P
。
DECIMAL(P,D)
表示列可以存储D
位小数的P
位数。十进制列的实际范围取决于精度和刻度。
与INT数据类型一样,DECIMAL
类型也具有UNSIGNED
和ZEROFILL
属性。 如果使用UNSIGNED
属性,则DECIMAL UNSIGNED
的列将不接受负值。
如果使用ZEROFILL
,MySQL将把显示值填充到0
以显示由列定义指定的宽度。 另外,如果我们对DECIMAL
列使用ZERO FILL
,MySQL将自动将UNSIGNED
属性添加到列。
以下示例使用DECIMAL
数据类型定义的一个叫作amount
的列。
1
|
amount DECIMAL (6,2); |
在此示例中,amount
列最多可以存储6
位数字,小数位数为2
位; 因此,amount
列的范围是从-9999.99
到9999.99
。
参考:
https://www.jb51.net/article/109363.htm
https://www.cnblogs.com/owenma/p/7991508.html
http://www.cnblogs.com/owenma/p/7097602.html
MySQL中Decimal类型和Float Double的区别 & BigDecimal与Double使用场景的更多相关文章
- MySQL中Decimal类型和Float Double等区别
MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型. 其区别在于,float,double等非标准类型,在DB中保存的是近似值,而Decimal则以字符串的形 ...
- mysql中Numeric类型和int类型的区别
首先记一下,Numeric数字数据只包含 数字.数字数据包括正数.负数.小数.分数和整数 例子如下: Numeric(6,2) Numeric(16,6) Numeric(16,0) 从左到右,第一个 ...
- Mysql 中 text类型和 blog类型的异同
MySQL存在text和blob: (1)相同 在TEXT或BLOB列的存储或检索过程中,不存在大小写转换,当未运行在严格模式时,如果你为BLOB或TEXT列分配一个超过该列类型的最大长度的值值,值被 ...
- mysql中varchar类型和datetime类型字段进行比较
我是在mysql5.7版本进行比较 表a的字段order_no和表iwebshop_tmp的字段order_no一样 需要更新iwebshop_member_order表的datetime类型expi ...
- MySQL中 DECIMAL FLOAT DOUBLE的区别
第一篇文章: MySQL中Decimal类型和Float Double等区别 MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型. 其区别在于,float,d ...
- Python3.x中bytes类型和str类型深入分析
Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分.文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示.Python 3不会以任意隐式的方式混用str和b ...
- 关于 Go 中 Map 类型和 Slice 类型的传递
关于 Go 中 Map 类型和 Slice 类型的传递 Map 类型 先看例子 m1: func main() { m := make(map[int]int) mdMap(m) fmt.Printl ...
- java 8 Stream中操作类型和peek的使用
目录 简介 中间操作和终止操作 peek 结论 java 8 Stream中操作类型和peek的使用 简介 java 8 stream作为流式操作有两种操作类型,中间操作和终止操作.这两种有什么区别呢 ...
- Java中的基本类型和引用类型变量的区别
Java中的基本类型和引用类型变量的区别 学了一年多,说实话你要我说这些东西我是真说不出来是啥意思 基本类型: 基本类型自然不用说了,它的值就是一个数字,一个字符或一个布尔值. 引用类型: ...
随机推荐
- TestFlight 测试
问题1:iOS提交TestFlight测试显示缺少合规证明 解决:有的时候testFlight会显示@“缺少合规证明” 最简单的解决办法就是点击文字前边的黄色标识符,会询问你是否加密,选择相应选项就可 ...
- .NET Core 事件总线,分布式事务解决方案:CAP 基于Kafka
背景 相信前面几篇关于微服务的文章也介绍了那么多了,在构建微服务的过程中确实需要这么一个东西,即便不是在构建微服务,那么在构建分布式应用的过程中也会遇到分布式事务的问题,那么 CAP 就是在这样的背景 ...
- zabbix监控实战<3> 之自定义监控实例
第一章 自定义监控tcp状态 命令可以选择ss 或者 netstat ss打印基于socket的统计信息,实际运行下来,ss的速度要比netstat要快得多 1.1 tcp的十一种状态 ...
- RAID技术详解
RAID:Redundant Array of Independent Disks 中文我们称为独立冗余磁盘阵列.基本上是见名知意.RAID的基本思想就是将多个容量较小且价格实惠的磁盘进行组合起来构成 ...
- js获取url指定参数值
function GetQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&] ...
- JDBC中常用的接口
JDBC常用的接口DriverManager 驱动管理器获得数据库链接 Connection 数据库链接接口 Statement 语句接口,用来静态操作SQL语句 PreparedStatement ...
- zigbee 中ZDO的理解
---恢复内容开始--- ZigBee 物理层:主要进行无线数据的收发,同时定义了无线传输的信道以及频率. MAC层:使用CSMA-CA机制接入到无线信道,负责传输信标帧,保持同步和 ...
- vxworks开发中simulator的使用之建立虚拟网卡
在使用windriver workben ch开发vxWorks应用时,有时需要在本机上利用Simulator跑一下程序,这就需要你安装一个虚拟的网卡.vxWorks自带了这些工具,下面,以windo ...
- 使用OGG添加唯一标识字段到目标表
利用GoldenGate,可以获取到变更记录在源端对应的redo日志序号,redo中的地址RBA,如果源端是RAC,还可以拿到源端节点的编号,通过这3个值,可以定位该变更记录的唯一性. 这些信息,在G ...
- WSDL文档
portType 相当于一个类. operation 相当于该类里有一个方法名,方法名为processAPNManagement,该方法里有一个输入消息,一个输出消息,一个错误消息.