MySQL必知必会02:字段类型选择_字段选择-程序员宅基地

技术标签: MySQL  mysql  数据库  sql  

阅读整理自《MySQL 必知必会》- 朱晓峰,详细内容请登录 极客时间 官网购买专栏。

MySQL 中有很多字段类型,比如整数、文本、浮点数,等等。如果类型定义合理,就能节省存储空间,提升数据查询和处理的速度,相反,如果数据类型定义不合理,就有可能会导致数据超出取值范围,引发系统报错,甚至可能会出现计算错误的情况,进而影响到整个系统。

整型

整数类型一共有 5 种,包括 TINYINT、SMALLINT、MEDIUMINT、INT(INTEGER)和 BIGINT
在这里插入图片描述
在评估用哪种整数类型的时候,需要考虑存储空间和可靠性的平衡问题:

  • 用占用字节数少的整数类型可以节省存储空间;
  • 要是为了节省存储空间,使用的整数类型取值范围太小,一旦遇到超出取值范围的情况,就可能引起系统错误,影响可靠性。

在实际工作中,系统故障产生的成本远远超过增加几个字段存储空间所产生的成本。因此,首先确保数据不会超过取值范围,在这个前提之下,再去考虑如何节省存储空间。


浮点数

MySQL 支持的浮点数类型,分别是 FLOAT、DOUBLE、REAL。

  • FLOAT 表示单精度浮点数;

  • DOUBLE 表示双精度浮点数;

  • REAL 默认就是 DOUBLE。如果把 SQL 模式设定为启用 REAL_AS_FLOAT,那么,MySQL 就认为 REAL 是 FLOAT。如果要启用“REAL_AS_FLOAT”,就可以通过以下 SQL 语句实现:

    SET sql_mode = "REAL_AS_FLOAT";
    

LOAT 占用字节数少,取值范围小;DOUBLE 占用字节数多,取值范围也大。浮点数类型的无符号数取值范围,只相当于有符号数取值范围的一半,也就是只相当于有符号数取值范围大于等于零的部分。

浮点数类型有个缺陷,就是不精准。因此,在一些对精确度要求较高的项目中,千万不要使用浮点数,不然会导致结果错误,甚至是造成不可挽回的损失。

show databases;
use demo;
create table demo.goodsmaster
(
barcode text,
goodname text,
price double,
itemnumber int primary key auto_increment
);

mysql> describe goodsmaster;
+------------+--------+------+-----+---------+----------------+
| Field      | Type   | Null | Key | Default | Extra          |
+------------+--------+------+-----+---------+----------------+
| barcode    | text   | YES  |     | NULL    |                |
| goodname   | text   | YES  |     | NULL    |                |
| price      | double | YES  |     | NULL    |                |
| itemnumber | int    | NO   | PRI | NULL    | auto_increment |
+------------+--------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
insert into demo.goodsmaster (barcode, goodname, price) values ('001', 'book', 0.47);
insert into demo.goodsmaster (barcode, goodname, price) values ('002', 'pen', 0.44);
insert into demo.goodsmaster (barcode, goodname, price) values ('003', 'rubber', 0.19);

mysql> select * from goodsmaster;
+---------+----------+-------+------------+
| barcode | goodname | price | itemnumber |
+---------+----------+-------+------------+
| 001     | book     |  0.47 |          1 |
| 002     | pen      |  0.44 |          2 |
| 003     | rubber   |  0.19 |          3 |
+---------+----------+-------+------------+
3 rows in set (0.00 sec)

mysql> select sum(price) from goodsmaster;
+--------------------+
| sum(price)         |
+--------------------+
| 1.0999999999999999 |
+--------------------+
1 row in set (0.00 sec)

会存在这样的误差,问题还是出在 MySQL 对浮点类型数据的存储方式上。

MySQL 用 4 个字节存储 FLOAT 类型数据,用 8 个字节来存储 DOUBLE 类型数据。无论哪个,都是采用二进制的方式来进行存储的。比如 9.625,用二进制来表达,就是 1001.101,或者表达成 1.001101×2^3。如果尾数不是 0 或 5(比如 9.624),就无法用一个二进制数来精确表达。怎么办呢?就只好在取值允许的范围内进行近似(四舍五入)。(十进制小数转化为二进制小数

数据类型是 DOUBLE 的时候,得到的结果误差更小一些,而数据类型是 FLOAT 的时候,误差会更大一下。原因就是,DOUBLE 有 8 位字节,精度更高。


定点数

定点数 DECIMAL 的存储方式决定了它一定是精准的。

浮点数类型是把十进制数转换成二进制数存储,DECIMAL 则不同,它是把十进制数的整数部分和小数部分拆开,分别转换成十六进制数,进行存储。这样,所有的数值,就都可以精准表达了,不会存在因为无法表达而损失精度的问题。

mysql> alter table demo.goodsmaster modify column price decimal(5,2);
Query OK, 3 rows affected (0.14 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select sum(price) from demo.goodsmaster;
+------------+
| sum(price) |
+------------+
|       1.10 |
+------------+
1 row in set (0.00 sec)

由于 DECIMAL 数据类型的精准性,在项目中,除了极少数(比如商品编号)用到整数类型外,其他的数值都用的是 DECIMAL,原因就是这个项目所处的零售行业,要求精准,一分钱也不能差。

小结下浮点数和定点数的特点:

  • 浮点类型取值范围大,但是不精准,适用于需要取值范围大,又可以容忍微小误差的科学计算场景(比如计算化学、分子建模、流体动力学等);
  • 定点数类型取值范围相对小,但是精准,没有误差,适合于对精度要求极高的场景(比如涉及金额计算的场景)。

文本

TEXT 类型是 MySQL 支持的文本类型的一种。此外,MySQL 还支持 CHAR、VARCHAR、ENUM 和 SET 等文本类型。

  • CHAR(M):固定长度字符串。CHAR(M) 类型必须预先定义字符串长度。如果太短,数据可能会超出范围;如果太长,又浪费存储空间
  • VARCHAR(M): 可变长度字符串。VARCHAR(M) 也需要预先知道字符串的最大长度,不过只要不超过这个最大长度,具体存储的时候,是按照实际字符串长度存储的
  • TEXT:字符串。系统自动按照实际长度存储,不需要预先定义长度
  • ENUM:枚举类型,取值必须是预先设定的一组字符串值范围之内的一个,必须要知道字符串所有可能的取值
  • SET:是一个字符串对象,取值必须是在预先设定的字符串值范围之内的 0 个或多个,也必须知道字符串所有可能的取值

因为不需要预先知道字符串的长度,系统会按照实际的数据长度进行存储,所以 TEXT 类型最为灵活方便。

TEXT 类型也有 4 种,它们的区别就是最大长度不同。

  • TINYTEXT:255 字符(这里假设字符是 ASCII 码,一个字符占用一个字节,下同)
  • TEXT: 65535 字符
  • MEDIUMTEXT:16777215 字符
  • LONGTEXT: 4294967295 字符(相当于 4GB)

需要注意的是,TEXT 也有一个问题:由于实际存储的长度不确定,MySQL 不允许 TEXT 类型的字段做主键。遇到这种情况,只能采用 CHAR(M),或者 VARCHAR(M)。在项目中,只要不是主键字段,就可以按照数据可能的最大长度,选择这几种 TEXT 类型中的的一种,作为存储字符串的数据类型。


日期与时间

用得最多的日期时间类型,就是 DATETIME。虽然 MySQL 也支持 YEAR(年)、TIME(时间)、DATE(日期),以及 TIMESTAMP 类型,不同数据类型表示的时间内容不同、取值范围不同,而且占用的字节数也不一样,要根据实际需要灵活选取。
在这里插入图片描述
在实际项目中,尽量用 DATETIME 类型。因为这个数据类型包括了完整的日期和时间信息,可以确保数据的完整性和系统的稳定性,使用起来比较方便。毕竟,如果日期时间信息分散在好几个字段,就会很不容易记,而且查询的时候,SQL 语句也会更加复杂。


小结

在定义数据类型时,如果确定是整数,就用 INT;如果是小数,一定用定点数类型 DECIMAL;如果是字符串,只要不是主键,就用 TEXT;如果是日期与时间,就用 DATETIME。

凡事都是有两面的,可靠性好,并不意味着高效。比如,TEXT 虽然使用方便,但是效率不如 CHAR(M) 和 VARCHAR(M)。

进一步优化的需求,可参考:Data Type

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_31362767/article/details/123162627

智能推荐

分布式光纤传感器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告_预计2026年中国分布式传感器市场规模有多大-程序员宅基地

文章浏览阅读3.2k次。本文研究全球与中国市场分布式光纤传感器的发展现状及未来发展趋势,分别从生产和消费的角度分析分布式光纤传感器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国市场主要生产商的市场份额。主要生产商包括:FISO TechnologiesBrugg KabelSensor HighwayOmnisensAFL GlobalQinetiQ GroupLockheed MartinOSENSA Innovati_预计2026年中国分布式传感器市场规模有多大

07_08 常用组合逻辑电路结构——为IC设计的延时估计铺垫_基4布斯算法代码-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏12次。常用组合逻辑电路结构——为IC设计的延时估计铺垫学习目的:估计模块间的delay,确保写的代码的timing 综合能给到多少HZ,以满足需求!_基4布斯算法代码

OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版-程序员宅基地

文章浏览阅读3.3k次,点赞3次,收藏5次。OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版

关于美国计算机奥赛USACO,你想知道的都在这_usaco可以多次提交吗-程序员宅基地

文章浏览阅读2.2k次。USACO自1992年举办,到目前为止已经举办了27届,目的是为了帮助美国信息学国家队选拔IOI的队员,目前逐渐发展为全球热门的线上赛事,成为美国大学申请条件下,含金量相当高的官方竞赛。USACO的比赛成绩可以助力计算机专业留学,越来越多的学生进入了康奈尔,麻省理工,普林斯顿,哈佛和耶鲁等大学,这些同学的共同点是他们都参加了美国计算机科学竞赛(USACO),并且取得过非常好的成绩。适合参赛人群USACO适合国内在读学生有意向申请美国大学的或者想锻炼自己编程能力的同学,高三学生也可以参加12月的第_usaco可以多次提交吗

MySQL存储过程和自定义函数_mysql自定义函数和存储过程-程序员宅基地

文章浏览阅读394次。1.1 存储程序1.2 创建存储过程1.3 创建自定义函数1.3.1 示例1.4 自定义函数和存储过程的区别1.5 变量的使用1.6 定义条件和处理程序1.6.1 定义条件1.6.1.1 示例1.6.2 定义处理程序1.6.2.1 示例1.7 光标的使用1.7.1 声明光标1.7.2 打开光标1.7.3 使用光标1.7.4 关闭光标1.8 流程控制的使用1.8.1 IF语句1.8.2 CASE语句1.8.3 LOOP语句1.8.4 LEAVE语句1.8.5 ITERATE语句1.8.6 REPEAT语句。_mysql自定义函数和存储过程

半导体基础知识与PN结_本征半导体电流为0-程序员宅基地

文章浏览阅读188次。半导体二极管——集成电路最小组成单元。_本征半导体电流为0

随便推点

【Unity3d Shader】水面和岩浆效果_unity 岩浆shader-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏18次。游戏水面特效实现方式太多。咱们这边介绍的是一最简单的UV动画(无顶点位移),整个mesh由4个顶点构成。实现了水面效果(左图),不动代码稍微修改下参数和贴图可以实现岩浆效果(右图)。有要思路是1,uv按时间去做正弦波移动2,在1的基础上加个凹凸图混合uv3,在1、2的基础上加个水流方向4,加上对雾效的支持,如没必要请自行删除雾效代码(把包含fog的几行代码删除)S..._unity 岩浆shader

广义线性模型——Logistic回归模型(1)_广义线性回归模型-程序员宅基地

文章浏览阅读5k次。广义线性模型是线性模型的扩展,它通过连接函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。广义线性模型拟合的形式为:其中g(μY)是条件均值的函数(称为连接函数)。另外,你可放松Y为正态分布的假设,改为Y 服从指数分布族中的一种分布即可。设定好连接函数和概率分布后,便可以通过最大似然估计的多次迭代推导出各参数值。在大部分情况下,线性模型就可以通过一系列连续型或类别型预测变量来预测正态分布的响应变量的工作。但是,有时候我们要进行非正态因变量的分析,例如:(1)类别型.._广义线性回归模型

HTML+CSS大作业 环境网页设计与实现(垃圾分类) web前端开发技术 web课程设计 网页规划与设计_垃圾分类网页设计目标怎么写-程序员宅基地

文章浏览阅读69次。环境保护、 保护地球、 校园环保、垃圾分类、绿色家园、等网站的设计与制作。 总结了一些学生网页制作的经验:一般的网页需要融入以下知识点:div+css布局、浮动、定位、高级css、表格、表单及验证、js轮播图、音频 视频 Flash的应用、ul li、下拉导航栏、鼠标划过效果等知识点,网页的风格主题也很全面:如爱好、风景、校园、美食、动漫、游戏、咖啡、音乐、家乡、电影、名人、商城以及个人主页等主题,学生、新手可参考下方页面的布局和设计和HTML源码(有用点赞△) 一套A+的网_垃圾分类网页设计目标怎么写

C# .Net 发布后,把dll全部放在一个文件夹中,让软件目录更整洁_.net dll 全局目录-程序员宅基地

文章浏览阅读614次,点赞7次,收藏11次。之前找到一个修改 exe 中 DLL地址 的方法, 不太好使,虽然能正确启动, 但无法改变 exe 的工作目录,这就影响了.Net 中很多获取 exe 执行目录来拼接的地址 ( 相对路径 ),比如 wwwroot 和 代码中相对目录还有一些复制到目录的普通文件 等等,它们的地址都会指向原来 exe 的目录, 而不是自定义的 “lib” 目录,根本原因就是没有修改 exe 的工作目录这次来搞一个启动程序,把 .net 的所有东西都放在一个文件夹,在文件夹同级的目录制作一个 exe._.net dll 全局目录

BRIEF特征点描述算法_breif description calculation 特征点-程序员宅基地

文章浏览阅读1.5k次。本文为转载,原博客地址:http://blog.csdn.net/hujingshuang/article/details/46910259简介 BRIEF是2010年的一篇名为《BRIEF:Binary Robust Independent Elementary Features》的文章中提出,BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度..._breif description calculation 特征点

房屋租赁管理系统的设计和实现,SpringBoot计算机毕业设计论文_基于spring boot的房屋租赁系统论文-程序员宅基地

文章浏览阅读4.1k次,点赞21次,收藏79次。本文是《基于SpringBoot的房屋租赁管理系统》的配套原创说明文档,可以给应届毕业生提供格式撰写参考,也可以给开发类似系统的朋友们提供功能业务设计思路。_基于spring boot的房屋租赁系统论文