高性能 MySQL(五):设计表结构时,如何选择数据类型会更高效?

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MySQL 支持的数据类型有很多,在设计表结构时,选择正确的数据类型可以获得更高的性能。如果你还不知道如何选择,那么希望这篇文章能帮到你。

image.png

大家好,我是水滴~~

MySQL 支持的数据类型有很多,在设计表结构时,选择正确的数据类型可以获得更高的性能。如果你还不知道如何选择,那么希望这篇文章能帮到你。

选择数据类型的原则

在选择数据类型时,一般要遵循下面三个原则。

选择更小的

一般情况下,应该尽量使用可以正确存储数据的最小数据类型。

更小的数据类型通常更快,因为它们占用更少的磁盘、内存和 CPU 缓存,并且处理时需要的 CPU 周期也更少。前提条件时,选择的数据类型能够在存储值的范围内。

例如,在为“年龄”字段选择类型时,使用tinyint unsigned类型就能满足人类的需求(tinyint只占一个字节,其无符号的数据范围是:0~255)。

选择简单的

尽量选择简单的数据类型,因为它们的操作通常需要更少的 CPU 周期。

例如,字符型之间的比较,比整形之间的比较更复杂,这会影响到排序的效率。

尽量避免 NULL

通常情况下,应尽量指定列为 NOT NULL,特别是索引列,除非真的需要存储 NULL 值。

如果查询中包含可为 NULL 的列,对 MySQL 来说更难优化,因为可为 NULL 的列使得索引、索引统计和值比较都更复杂。可为 NULL 的列会使用更多的存储空间,在 MySQL 里也需要特殊处理。

当可为 NULL 的列被索引时,每个索引记录需要一个额外的字节。所以,如果计划在列上建索引,应尽量避免设计成可为 NULL 的列。

常用数据类型

下面列举一些常用数据类型,只有了解了它们的特性,才能帮助我们做正确的选择。

整数类型

MySQL 中有 5 种整数类型:tinyintsmallintmediumintintbigint,它们分别占用 8、16、24、32 和 64 位存储空间。它们可以存储值的范围可以用下面公式表示,其中 N 是存储空间的位数:

$$ -2^{(N-1)}到2^{(N-1)}-1 $$

整数类型可以使用unsigned属性,表示为无符号整形(不允许负值),这大致可以使正数的上限提高一倍。无符号存储值的范围可以使用下面公示表示:

$$ 0到2^{N}-1 $$

下表为每个整数类型的存储范围:

66f4433f87bfbaba8abab9753e897bd4_%E6%95%B4%E6%95%B0%E7%B1%BB%E5%9E%8B%20(4)_auth_key=1686636264-w66xPodRZ7L6of65bJudAQ-0-8665e93a0131d60ed2752f67443ce912&file_size=37035.jpg

有符号与无符号类型的存储空间和性能是相同的,所以可以根据实际情况选择合适的类型。对整数类型指定宽度是没有意义的,不会影响存储范围。例如,int(1)int(10)的存储和计算是相同的。

如果你能大体知道数据的范围,可以根据实际情况选择数据类型;
bigint适用于数据量巨大的场景,比如自增主键;
当你不知道该选择哪个类型,就使用int类型。

实数类型

实数是带有小数部分的数字。MySQL 有 3 种实数类型:floatdoubledecimal。其中floatdouble是浮点类型,分别占用 32 和 64 位存储空间;decimal支持高精度计算,存储空间依据列的设置,最高可设置 65 位。

值得注意的是,对于浮点型使用unsigned属性,只是不可使用负数,并没有增加正数的存储范围,所以意义不大。

下表为每个实数类型的存储范围:

989d4785766c4e3bdbc9518a5da451d8_%E5%AE%9E%E6%95%B0%E7%B1%BB%E5%9E%8B_auth_key=1686636287-eDBZoP2BZRKuBwpUHVZGAr-0-a11cb20dc69bfe3767a41dddf47691ba&file_size=49440.jpg

floatdouble是标准的浮点类型,CPU直接支持原生浮点计算,所以浮点运算速度会很快。但其最大的缺点是精度问题,造成数据偏差。

dicimal类型使用二进制格式存储,CPU 不支持对该类型的直接运算,它的高精度计算是由 MySQL 服务器自身实现,对小数计算精确。由于dicimal类型需要额外的空间和计算开销,所以相对会慢一些。

当计算的数据量大,并且对小数的精度要求没那么高时,可以使用floatdouble
如果对小数进行精确计算时,比如财务数据,请使用dicimal类型。实际在业务中,基本上也都是使用dicimal类型。

字符串类型

MySQL 支持多种字符串类型,我们分别来介绍一下吧.

CHAR 和 VARCHAR 类型

charvarchar是最主要的两种字符串类型。

char用于存储定长的字符串,适合存储很短的字符串,或者所有值都接近同一长度,比如 MD5 值;varchar用于存储可变长字符串,应用最为广泛。

对于经常变化的数据,charvarchar更好,因为定长的char类型不容易产生磁盘碎片;而varchar在变更时,如果新数据比原来的更长,这就导致需要做一些额外的工作,来找到适合的存储空间。

92743425c64b30b1a8094124288c3dd1_char%E5%92%8Cvarchar_auth_key=1686636304-q9SfcWX5JCgwRRLDKZFuDx-0-c40cf63a235f3d5ccd651714c9c76e5b&file_size=11143.jpg

varchar在存储时,只使用必要的空间。也就是说,越短的字符串使用的存储空间也越少。
但也不能盲目的设置更大的长度,更长的列消耗更多的内存,因为 MySQL 通常会分配固定大小的内存块来保存内部值。所以最好还是按需分配。

TEXT 类型

文本类型用于存储大的字符集,MySQL 有4种文本类型:tinytexttextmediumtextlongtext,它们可存储的最大长度不同,可以根据实际情况选择。

文本类型也可以进行排序,但它只对每个列的最前max_sort_length字节做排序。

5443250a84b5d666daf945ebd9a3f49f_char%E5%92%8Cvarchar%20(2)_auth_key=1686636322-k5jURKfGdS7NzGbawgcWV4-0-668c916f5600f112ae834f6962236044&file_size=18034.jpg

BINARY 和 VARBINARY 类型

binaryvarbinary类似于charvarchar,不同的是它们存储的是二进制字符串。

二进制字符串跟常规字符串非常相似,但二进制字符串存储的是字节码而不是字符。

MySQL 比较 binary字符串时,每次按一个字节,并且根据该字节的数值进行比较。因此,二进制比较会比字符比较简单很多,所以速度更快。

BLOB 类型

blob是一个二进制大对象,它有4种类型:tinyblobblobmediumbloblongblob,同样它们可存储的最大长度不同,可以根据实际情况选择。

blob类型与text类型非常相似,只不过blob存储的是二进制,而非字符。

55cfc98616c3a1a6d84ce611d035b456_char%E5%92%8Cvarchar%20(3)_auth_key=1686636339-gzM7rpa6BPwMyFrRcsAnq2-0-ecd643a8fec5a0eb7c3c0e7d9daedd7a&file_size=19821.jpg

日期和时间类型

MySQL 有多种类型来保存日期和时间:yeardatedatetimetimestamp

其中year用于存储年份,date用户存储日期,也就是:年-月-日。

datetimetimestamp两个类型最常用,都是用于存储时间,并且它们的精度都是秒,下面看下它们的区别:

  • datetime能保存大范围的值,从1001年到9999年。它把日期和时间封装成格式为YYYYMMDDHHMMSS的整数,与时区无关,使用8个字节的存储空间。
  • timestam存储的是时间戳,即从1970年1月1日午夜以来的秒数,它和 UNIX 时间戳相同。它只使用4个字节的存储空间,所以它的范围比datetime小,只能存储从1970年到2038年的数据。并且timestamp显示的值依赖于时区。

如果追求效率,应该选择timestamp,因为它使用的空间小。但由于其存储范围的原因,还是有很多人选择datetime

image.png

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3月前
|
关系型数据库 MySQL 数据库
MySQL数据库基础(数据库操作,常用数据类型,表的操作)
MySQL数据库基础(数据库操作,常用数据类型,表的操作)
46 5
|
3月前
|
存储 关系型数据库 MySQL
MySQL支持多种数据类型
MySQL支持多种数据类型
147 3
|
3月前
|
存储 关系型数据库 MySQL
什么是mysql的数据类型?
什么是mysql的数据类型?
53 2
|
3月前
|
存储 关系型数据库 MySQL
MySQL数据类型
MySQL数据类型
62 2
|
4月前
|
存储 关系型数据库 MySQL
深入解析MySQL数据存储机制:从表结构到物理存储
深入解析MySQL数据存储机制:从表结构到物理存储
410 1
|
5月前
|
存储 关系型数据库 MySQL
MySQL 中的 BLOB 数据类型深入解析
【8月更文挑战第31天】
611 0
|
13天前
|
存储 Oracle 关系型数据库
数据库传奇:MySQL创世之父的两千金My、Maria
《数据库传奇:MySQL创世之父的两千金My、Maria》介绍了MySQL的发展历程及其分支MariaDB。MySQL由Michael Widenius等人于1994年创建,现归Oracle所有,广泛应用于阿里巴巴、腾讯等企业。2009年,Widenius因担心Oracle收购影响MySQL的开源性,创建了MariaDB,提供额外功能和改进。维基百科、Google等已逐步替换为MariaDB,以确保更好的性能和社区支持。掌握MariaDB作为备用方案,对未来发展至关重要。
39 3
|
13天前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
42 3
|
13天前
|
SQL 关系型数据库 MySQL
数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog
《数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog》介绍了如何利用MySQL的二进制日志(Binlog)恢复误删除的数据。主要内容包括: 1. **启用二进制日志**:在`my.cnf`中配置`log-bin`并重启MySQL服务。 2. **查看二进制日志文件**:使用`SHOW VARIABLES LIKE 'log_%';`和`SHOW MASTER STATUS;`命令获取当前日志文件及位置。 3. **创建数据备份**:确保在恢复前已有备份,以防意外。 4. **导出二进制日志为SQL语句**:使用`mysqlbinlog`
54 2
|
26天前
|
关系型数据库 MySQL 数据库
Python处理数据库:MySQL与SQLite详解 | python小知识
本文详细介绍了如何使用Python操作MySQL和SQLite数据库,包括安装必要的库、连接数据库、执行增删改查等基本操作,适合初学者快速上手。
181 15