MySQL数据库中的浮点类型和高精度类型有什么区别?为什么不推荐使用浮点类型?

在软件开发中,作为后端,无可避免的需要熟练使用 MySQL 数据库进行数据存储和读取。对于信息系统而言,数据库的的地位不言而喻。那作为软件开发工程师,在使用 MySQL 过程中,又有哪些需要注意的呢?我们从实际开发来一点点的介绍。

本篇文章,我们先来了解一下关于数据库数字类型的一些内容。我们在做表设计的时候,数字类型是常见的数据类型,用于存储数字相关的信息(整数型、浮点型、高精度型)。但是在不同的业务场景中,错误的使用数字类型,也会给系统带来很大的风险。

一、数字类型

1、整数类型

MySQL 数据库支持 SQL 标准支持的整型类型:INT、SMALLINT。此外,MySQL 数据库也支持诸如 TINYINT、MEDIUMINT 和 BIGINT 整型类型。我们来看一下各整型所占用的存储空间及取值范围:

类型占用空间最小值-最大值(signed)最小值-最大值(unsigned)
TINYINT1-128~1270~255
SMALLINT2-32768~327680~65535
MEDIUMINT3-8388608~83886070~16777215
INT4-2147483648~21474836470~4294967295
BIGINT8-9223372036854775808~92233720368547758070~18446744073709551615

在整型数字类型中,有 signed 和 unsigned 的属性,表示的是整型的取值范围。默认是 signed。我们在设计时,建议不要刻意去用 unsigned 属性,因为在做数据分析时,SQL 可能会返回不是理想的结果。

2、浮点类型和高精度类型

MySQL 的数字类型中,除了上面说的整数类型,还有浮点型和高精度型。

MySQL 之前的版本中存在浮点类型 Float 和 Double,但这些类型因为不是高精度,也不是 SQL 标准的类型,所以在真实的生产环境中不推荐使用,否则在计算时,由于精度类型问题,会导致最终的计算结果出错。

更重要的是,在 MySQL8.0.17 版本开始,如果我们建表继续使用 FLOAT 和 DOUBLE,则会抛出警告:

Specifying number of digits for floating point data types is deprecated and will be removed in a future release

数字类型中的高精度 DECIMAL 类型可以使用,在设置字段为 DECIMAL 类型时,需要指定精度和标度。例如:

count DECIMAL(6,4)

其中,6 是精度(精度表示保存值的主要位数),4 是标度(标度表示小数点后面保存的位数)。通常在表结构设计中,类型 DECIMAL 可以用来表示用户的工程款项、账户的余额等精确到小数点后 4 位的业务。

然而,在海量并发的互联网业务中使用,金额字段的设计并不推荐使用 DECIMAL 类型,而更推荐使用 INT 整型类型。

二、表结构设计实战

1、整型与主键自增设计

在真实业务场景中,整型类型最常见的就是在业务中用来表示某件物品的数量。例如销售数量,或电商中的库存数量、购买次数等。在业务中,整型类型的另一个常见且重要的使用用法是作为表的主键,即用来唯一标识一行数据。

整型结合属性 auto_increment,可以实现自增功能,但在表结构设计时用自增做主键,特别要注意以下两点,若不注意,可能会对业务造成灾难性的打击:

  • 用 BIGINT 做主键,而不是 INT;

  • 自增值并不持久化,可能会有回溯现象(MySQL 8.0 版本前)。

从上述的类型对比中可以发现,INT 的最大范围在 42 亿级别,在互联网应有中,很容易就达到这个量级。比如一些日志表、浏览记录表等,每天 1000w 的数据增量,420 天后就达到了 INT 上限。

因此,用自增型做主键,应该使用 BIGINT,而不是 INT

另外,MySQL8.0 以前的版本,自增不持久化,自增值可能会存在回溯问题

我们以以下实例来看:

mysql> SELECT * FROM t;

+---+

| a |

+---+

| 1 |

| 2 |

| 3 |

+---+

3 rows in set (0.01 sec)



mysql> DELETE FROM t WHERE a = 3;

Query OK, 1 row affected (0.02 sec)



mysql> SHOW CREATE TABLE t\G

*************************** 1. row ***************************

       Table: t

Create Table: CREATE TABLE `t` (

  `a` int NOT NULL AUTO_INCREMENT,

  PRIMARY KEY (`a`)

) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

1 row in set (0.00 sec

从上述代码可以看出,在删除自增为 3 的记录后,下一个自增依然为 4,这里没有问题,自增不会回溯。但如果此时数据库发生重启,那数据库启动后,表 t 的自增起始值会再次变为 3,这就是自增值发生回溯。

mysql> SHOW CREATE TABLE t\G

*************************** 1. row ***************************

       Table: t

Create Table: CREATE TABLE `t` (

  `a` int NOT NULL AUTO_INCREMENT,

  PRIMARY KEY (`a`)

) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

1 row in set (0.00 s

如果想解决这个问题,有以下两个做法:

  • 1、升级 MySQL 到 8.0 版本,让每个表的自增值持久化。

  • 2、如无法升级版本,则不推荐在核心业务表使用自增数据类型做主键。

其实在海量的互联网架构设计中,为了后续分布式架构更好的扩展,一般是不使用整型来做主键的,更为推荐的是使用字符串类型

2、资金字段设计

在用户余额、基金账户余额、数字钱包、零钱等的业务设计中,由于字段都是资金字段,通常技术人员习惯使用 DECIMAL 类型作为字段的选型,因为这样可以精确到分,如:DECIMAL(6,2)。

CREATE TABLE User (

  userId BIGINT AUTO_INCREMENT,

  money DECIMAL(8,2) NOT NULL,

  ......

)

在海量互联网业务的设计标准中,并不推荐用 DECIMAL 类型,而是更推荐将 DECIMAL 转化为 整型类型。也就是说,资金类型更推荐使用用分单位存储,而不是用元单位存储。如 1 元在数据库中用整型类型 100 存储。

金额字段的取值范围如果用 DECIMAL 表示的,如何定义长度呢?因为类型 DECIMAL 是个变长字段,若要定义金额字段,则定义为 DECIMAL(8,2) 是远远不够的。这样只能表示存储最大值为 999999.99,百万级的资金存储。

用户的金额至少要存储百亿的字段,而统计局的 GDP 金额字段则可能达到百万亿级别。用类型 DECIMAL 定义,不好统一。

另外重要的是,类型 DECIMAL 是通过二进制实现的一种编码方式,计算效率远不如整型来的高效。因此,推荐使用 BIG INT 来存储金额相关的字段

字段存储时采用分存储,即便这样 BIG INT 也能存储千兆级别的金额。这里,1 兆 = 1 万亿。

文章将持续更新,欢迎关注公众号:服务端技术精选。欢迎点赞、关注、转发

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/611338.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自动驾驶主流芯片及平台架构(三)低算力平台

前面有提到,自动驾驶等级每增加一级,所需要的芯片算力就会呈现十数倍的上升,L2级自动驾驶的算力需求仅要求2-2.5TOPS,但是L3级自动驾驶算力需求就需要20-30TOPS,到L4级需要200TOPS以上,L5级别算力需求则超过2000TOPS。…

【Docker】Docker部署Java程序

Maven中使用打包插件 <build><finalName>duanjian</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><mainClass…

让GPT们成为我们的小助手:使用ChatGPT来生成测试用数据

让GPT们成为我们的小助手 任务&#xff1a;帮忙生成测试数据 今天本来想做一个测试&#xff0c;所以需要一些测试数据。为了让测试显得更真实&#xff0c;所以希望测试数据看上去就是一份真实的数据&#xff0c;所以我就希望ChatGPT&#xff08;这里是代指&#xff0c;我有使…

高校教务选课管理系统开发方案

一、项目背景与目标 &#xff08;一&#xff09;项目背景 随着高校教育规模的扩大&#xff0c;教务管理变得越来越复杂&#xff0c;传统的手工管理方式已经无法满足现代高校的需求。因此&#xff0c;开发一套高效、便捷的高校教务选课管理系统显得尤为重要。该系统将涵盖学生…

控制情绪是交易成功的根本?大错特错

布雷特斯坦伯格&#xff08;Brett Steenbarger&#xff09;是一位在美国享有盛誉的交易心理学专家&#xff0c;他曾在华尔街的多个顶尖培训中心担任交易员的心理指导。身为心理学教授兼高级交易员的布雷特在交易心理方面要比别人了解得多。而且小编觉得做一个成功的交易员只靠交…

NSS刷题

1、[SWPUCTF 2021 新生赛]gift_f12 打开题目后查看源码无发现&#xff0c;用f12发现flag 2、[GDOUCTF 2023]hate eat snake 打开链接是一个贪吃蛇小游戏&#xff0c;f12找到js文件中有一个speed的语句&#xff0c;该语句的作用是使速度增加&#xff0c;因此&#xff0c;将该语…

【全开源】Java外卖霸王餐免费吃外卖小程序+APP+公众号+H5多端霸王餐源码

一、特色功能 霸王餐活动管理&#xff1a;允许商家发布和管理霸王餐活动&#xff0c;包括设置活动时间、具体优惠、活动规则等。用户参与与浏览&#xff1a;用户可以在小程序中浏览霸王餐活动列表&#xff0c;查看活动的详情信息&#xff0c;如商品或服务的免费赠送、活动规则…

一文带你了解军用电源绝缘性能测试规范和标准

军用电源是指主要用于军事、航空航天等领域的电源模块&#xff0c;因其良好的稳定性和可靠性也在通信、交通、航空航海、加工工业等领域广泛应用。因此&#xff0c;对于军用电源的性能要求比较严格&#xff0c;性能测试是确保电源质量的关键环节。 那么&#xff0c;在测试军品电…

【vulhub靶场】Apache 中间件漏洞复现

【vulhub靶场】Apache 中间件漏洞复现 一、Apache HTTPD 换行解析漏洞&#xff08;CVE-2017-15715&#xff09;1. 漏洞详情2. 影响版本3. 漏洞复现 二、Apache多后缀解析漏洞&#xff08;apache_parsing_vulnerability&#xff09;1. 漏洞详情2. 漏洞复现 三、Apache HTTP Serv…

一篇详解Git版本控制工具

华子目录 版本控制集中化版本控制分布式版本控制 Git简史Git工作机制Git和代码托管中心局域网互联网 Git安装基础配置git的--local&#xff0c;--global&#xff0c;--system的区别 创建仓库方式1git init方式2git clone git网址 工作区&#xff0c;暂存区&#xff0c;本地仓库…

将AI融入项目开发工作中去吧

目录 1.提高编写开发日报的效率 2.提高编写代码注释的效率 3.提高代码重构的效率 4.编写测试用例及测试报告 5. 协助进行代码走查与工作量分析 在AI元年后&#xff0c;作为一名程序员&#xff0c;相信各位友友已经深切地感受到了它带来的变革。作为一个从小白到资深码农的…

canvas识别路线

theme: jzman 视频说明 jvideo 前言 效果一 技术栈 htmljavascriptcsscanvas 项目主要功能上传一张地图&#xff0c;或者迷宫地图&#xff0c;通过canvas的一系列操作&#xff0c;并指定一个起点和终点&#xff0c;并找到到达终点最近的路线 迷宫找出口效果 正文 加载图像 首先…

芋道系统springcloud模块启动报错,枚举类不能为空

问题描述&#xff1a; Error starting ApplicationContext. To display the conditions report re-run your application with debug enabled. 2024-05-10 15:50:15.756 | ERROR 9120 | main [TID: N/A] o.s.b.d.LoggingFailureAnalysisReporter | ************************…

【C++】详细版 RAII技术的应用之智能指针(智能指针发展历程和简单模拟实现介绍)

目录 前言 一、智能指针有什么用&#xff1f; 二、什么是RAII(智能指针的底层思想)&#xff1f; 三、智能指针的发展历程以及模拟实现 1.auyo_ptr&#xff08;C98&#xff09; 2.unique_ptr&#xff08;C11&#xff09; 3.shared_ptr&#xff08;C11&#xff09; 前言 C中…

面向对象 03:类与对象的创建、初始化和使用,通过 new 关键字调用构造方法,以及创建对象过程的内存分析

一、前言 记录时间 [2024-05-10] 系列文章简摘&#xff1a; Java 笔记 01&#xff1a;Java 概述&#xff0c;MarkDown 常用语法整理 Java 笔记 11&#xff1a;Java 方法相关内容&#xff0c;方法的设计原则&#xff0c;以及方法的定义和调用 面向对象 01&#xff1a;Java 面向对…

使用com.google.common.collect依赖包中的Lists.transform()方法转换集合对象之后,修改集合中的对象属性,发现不生效

目录 1.1、错误描述 &#xff08;1&#xff09;引入依赖 &#xff08;2&#xff09;模拟代码 &#xff08;3&#xff09;运行结果 1.2、解决方案 1.1、错误描述 最近在开发过程中&#xff0c;使用到了com.google.common.collect依赖包&#xff0c;通过这个依赖包中提供的…

4D 成像毫米波雷达:新型传感器助力自动驾驶

1 感知是自动驾驶的首要环节&#xff0c;高性能传感器必不可少 感知环节负责对侦测、识别、跟踪目标&#xff0c;是自动驾驶实现的第一步。自动驾驶的实现&#xff0c;首先要能够准确理解驾驶环境信息&#xff0c;需要对交通主体、交通信号、环境物体等信息进行有效捕捉&#x…

2024-AIDD-人工智能药物设计-AlphaFold3

AlphaFold3&#xff5c;万字长文解读 AlphaFold3预测所有分子相互作用准确结构 AlphaFold3 自2021年AlphaFold2问世以来&#xff0c;科研工作者们便开始利用这一蛋白结构预测模型来详细描绘众多蛋白质的结构、探索新药。近日&#xff0c;Google DeepMind公司推出了其最新产品…

[附源码]石器时代_恐龙宝贝内购版_三网H5手游_带GM工具

石器时代之恐龙宝贝内购版_三网H5经典怀旧Q萌全网通手游_Linux服务端源码_视频架设教程_GM多功能授权后台_CDK授权后台 本教程仅限学习使用&#xff0c;禁止商用&#xff0c;一切后果与本人无关&#xff0c;此声明具有法律效应&#xff01;&#xff01;&#xff01;&#xff0…
最新文章