当前位置: 首页 > news >正文

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: tCreate Table: CREATE TABLE `t` (`a` int NOT NULL AUTO_INCREMENT,PRIMARY KEY (`a`)) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci1 row in set (0.00 sec

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

mysql> SHOW CREATE TABLE t\G*************************** 1. row ***************************Table: tCreate Table: CREATE TABLE `t` (`a` int NOT NULL AUTO_INCREMENT,PRIMARY KEY (`a`)) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci1 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 万亿。

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

相关文章:

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

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

C++ 抽象与封装

一 抽象 抽象实例:时钟 数据抽象: 具有表面当前时间的时、分、秒 行为抽象: 具有设置时间和显示时间两个最基本的功能。 抽象实例:人 数据抽象:姓名、年龄、性别等。 行为抽象: 生物属性:吃…...

antV X6的简要使用教程

🧑‍🎓 个人主页:《爱蹦跶的大A阿》 🔥当前正在更新专栏:《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 在我们的日常开发工作中,我们经常需要构建复杂的交互式图…...

【LLM 论文】Step-Back Prompting:先解决更高层次的问题来提高 LLM 推理能力

论文:Take a Step Back: Evoking Reasoning via Abstraction in Large Language Models ⭐⭐⭐⭐ Google DeepMind, ICLR 2024, arXiv:2310.06117 论文速读 该论文受到的启发是:人类再解决一个包含很多细节的具体问题时,先站在更高的层次上解…...

Java——接口的补充

目录 一:接口的注意事项 1. 接口中不能有方法块; 2. 接口没有构造方法: 3.接口是可以多继承的; 4. 多个接口抽象方法重复 5. 类的父类方法与接口方法重复 二:类与接口 1. 继承与实现 2. 多个父接口的抽象…...

word转pdf的java实现(documents4j)

一、多余的话 java实现word转pdf可用的jar包不多,很多都是收费的。最近发现com.documents4j挺好用的,它支持在本机转换,也支持远程服务转换。但它依赖于微软的office。电脑需要安装office才能转换。鉴于没在linux中使用office,本…...

基于K8S构建Jenkins持续集成平台

文章目录 安装和配置NFSNFS简介NFS安装 在Kubernetes安装Jenkins-Master创建NFS client provisioner安装Jenkins-Master Jenkins与Kubernetes整合实现Jenkins与Kubernetes整合构建Jenkins-Slave自定义镜像 JenkinsKubernetesDocker完成微服务持续集成拉取代码,构建镜…...

PHPStudy 访问网页 403 Forbidden禁止访问

涉及靶场 upload-labd sqli-labs pikachu dvwa 以及所有部署在phpstudy中的靶场 注意:一定要安装解压软件 很多同学解压靶场代码以后访问报错的原因是:电脑上没有解压软件。 这个时候压缩包看起来就是黄色公文包的样子,右键只有“全部提取…...

热爱电子值得做的电子制作实验

加我zkhengyang,进嵌入式音频系统研究开发交流答疑群(课题组) AM/FM收音机散件制作,磁带随声听散件,黑白电视机散件制作,功放散件制作,闪光灯散件制作,声控灯散件,等等,可提高动手能…...

.class文件启动过程以及文件内容结构讲解

当你直接启动一个.class文件时,实际上是在操作系统中调用Java虚拟机(JVM),并将该.class文件传递给JVM以执行。现在让我们来解释一下.class文件的启动过程以及文件内容结构: 启动过程:操作系统通过指定的命…...

解锁楼宇自动化新维度西门子Insight+BACnet IP I/O控制器

数字城市的楼宇自动化已不再是一个遥不可及的概念,而是成为了现代建筑的标配。特别是在大型商业综合体、高端写字楼和公共设施中,高效的楼宇管理系统是确保环境舒适度与能源效率的关键。当提及楼宇自动化领域的佼佼者,西门子Insight楼宇自动化…...

2024.05.10作业

TCP服务器 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> #include <QTcpSocket> #include <QList> #include <QMessageBox> #include <QDebug>QT_BEGIN_NAMESPACE namespace Ui { class Widget; …...

基于POSIX标准库的读者-写者问题的简单实现

文章目录 实验要求分析保证读写、写写互斥保证多个读者同时进行读操作读者优先实例代码分析写者优先读写公平法示例代码分析实验要求 创建一个控制台进程,此进程包含n个线程。用这n个线程来表示n个读者或写者。每个线程按相应测试数据文件的要求进行读写操作。用信号量机制分别…...

重生我是嵌入式大能之串口调试UART

什么是串口 串口是一种在数据通讯中广泛使用的通讯接口&#xff0c;通常我们叫做UART (通用异步收发传输器Universal Asynchronous Receiver/Transmitter)&#xff0c;其具有数据传输速度稳定、可靠性高、适用范围广等优点。在嵌入式系统中&#xff0c;串口常用于与外部设备进…...

【智能优化算法】蜜獾优化算法(Honey Badger Algorithm,HBA)

蜜獾优化算法(Honey Badger Algorithm,HBA)是期刊“MATHEMATICS AND COMPUTERS IN SIMULATION”&#xff08;IF 3.6&#xff09;的2022年智能优化算法 01.引言 蜜獾优化算法(Honey Badger Algorithm,HBA)受蜜獾智能觅食行为的启发&#xff0c;从数学上发展出一种求解优化问题的…...

【算法与数据结构】数组

文章目录 前言数组数组的定义数组的基本操作增加元素删除元素修改元素查找元素 C STL 中的数组arrayvector Python3 中的列表访问更改元素值遍历列表检查列表中是否存在某元素增加元素删除元素拷贝列表总结 Python3 列表的常用操作 参考资料写在最后 前言 本系列专注更新基本数…...

【数据结构】队列详解(Queue)

文章目录 有关队列的概念队列的结点设计及初始化队列的销毁判空和计数入队操作出队操作 有关队列的概念 队列:只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出FIFO(First In First Out)入队列:进行插入操作的一端…...

Baumer工业相机堡盟工业相机如何通过NEOAPISDK获取相机的Statistics图像传输统计信息(C#)

Baumer工业相机堡盟工业相机如何通过NEOAPISDK获取相机的Statistics图像传输统计信息&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机NEOAPI SDK和相机Statistics图像传输统计信息的技术背景Baumer工业相机通过NEOAPISDK获取相机的Statistics图像传输统计信息技术1.引…...

FreeRTOS标准库例程代码

1.设备STM32F103C8T6 2.工程模板 单片机: 部分单片机的程序例程 - Gitee.comhttps://gitee.com/lovefoolnotme/singlechip/tree/master/STM32_FREERTOS/1.%E5%B7%A5%E7%A8%8B%E6%A8%A1%E6%9D%BF 3.代码 1-FreeRTOS移植模板 #include "system.h" #include "…...

wandb: - 0.000 MB of 0.011 MB uploaded持续出现的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

ubuntu22.04有线网络无法连接,图标也没了

今天突然无法有线网络无法连接任何设备&#xff0c;并且图标都没了 错误案例 往上一顿搜索&#xff0c;试了很多博客都不行&#xff0c;比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动&#xff0c;重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...