【MySQL】MySQL数据类型

文章目录

    • 1. 数据类型总览
    • 2. 整数类型
    • 3. 浮点数类型
    • 4. 定点数类型
    • 5. 位类型
    • 6. 日期与时间
    • 7. 文本字符串类型
      • 7.1 CHAR与VARCHAR类型
      • 7.2 TEXT类型
      • 7.3 ENUM类型
      • 7.4 SET类型
      • 7.5 二进制字符串类型
        • 7.5.1 BINARY与VARBINARY类型
        • 7.5.2 BLOB类型
      • 7.6 TEXT和BLOB的使用注意事项
    • 8. JSON 类型
    • 9. 空间类型

1. 数据类型总览

类型 类型举例
整数类型 TINYINT、SMALLINT、MEDIUMINT、INT(或INTEGER)、BIGINT
浮点类型 FLOAT、DOUBLE
定点数类型 DECIMAL
位类型 BIT
日期时间类型 YEAR、TIME、DATE、DATETIME、TIMESTAMP
文本字符串类型 CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT
枚举类型 ENUM
集合类型 SET
二进制字符串类型 BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB
JSON类型 JSON对象、JSON数组
空间数据类型 单值类型:GEOMETRY、POINT、LINESTRING、POLYGON;
集合类型:MULTIPONINT、MULTILINESTRING、MULTIPOLYGON、GEOMETRYCOLLECTION;

2. 整数类型

整数类型 字节 有符号数取值范围 无符号数取值范围 适用场景
TININT 1 -128~127 0~255 一般用于枚举数据,比如系统设定取值范围很小且固定的场景
SMALLINT 2 -32768~32767 0~65535 可以用于较小范围的统计数据,比如统计工厂的固定资产库存数量等
MEDIUMENT 3 -8388608~8388607 0~16777215 用于较大整数的计算,比如车站每日的客流量等
INT、INTEGER 4 -2147483648~2147483647 0~4294967295 取值范围足够大,一般情况下不用考虑超限问题,用得最多。比如商品编号
BIGINT 8 -9223372036854775808~9223372036854775807 0~18446744073709551615 只有当你处理特别巨大的整数时才会用到。比如双十一的交易量、大型门户网站点击量、证券公司衍生产品持仓等

M : 表示显示宽度,M的取值范围是(0, 255)。例如,int(5):当数据宽度小于5位的时候在数字前面需要用字符填满宽度。该项功能需要配合“ ZEROFILL ”使用,表示用“0”填满宽度,否则指定显示宽度无效。

如果设置了显示宽度,那么插入的数据宽度超过显示宽度限制,会不会截断或插入失败?

答案:不会对插入的数据有任何影响,还是按照类型的实际宽度进行保存,即 显示宽度与类型可以存储的值范围无关 。从MySQL 8.0.17开始,整数数据类型不推荐使用显示宽度属性

选用类型标准:

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

3. 浮点数类型

从MySQL 8.0.17开始,FLOAT(M,D) 和DOUBLE(M,D)用法在官方文档中已经明确不推荐使用,将来可能被移除。另外,关于浮点型FLOAT和DOUBLE的UNSIGNED也不推荐使用了,将来也可能被移除

浮点数类型有个缺陷,就是不精准。

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

在编程中,如果用到浮点数,要特别注意误差问题,因为浮点数是不准确的,所以我们要避免使用“=”来判断两个数是否相等。同时,在一些对精确度要求较高的项目中,千万不要使用浮点数,不然会导致结果错误,甚至是造成不可挽回的损失。那么,MySQL 有没有精准的数据类型呢?当然有,这就是定点数类型: DECIMAL

4. 定点数类型

定点数类型 字节 取值范围
DECIMAL(M,D) M+2字节 有效范围由M和D决定
  • 使用 DECIMAL(M,D) 的方式表示高精度小数。其中,M被称为精度,D被称为标度。0<=M<=65,0<=D<=30,D
  • 定点数在MySQL内部是以 字符串 的形式进行存储,这就决定了它一定是精准的
  • 当DECIMAL类型不指定精度和标度时,其默认为DECIMAL(10,0)。当数据的精度超出了定点数类型的精度范围时,则MySQL同样会进行四舍五入处理

5. 位类型

BIT类型中存储的是二进制值,类似010110

二进制字符串类型 长度 取值范围 占用空间
DECIMAL(M,D) M(默认1) 1<=M<=64 约为(M + 7)/8个字节
  • 可考虑用来做签到记录功能,如0101表示第一、三天未签到,第二四天有签到

6. 日期与时间

类型 表示 长度(字节) 格式 表示范围
YEAR 1 YYYY或YY 1901~2155
TIME 时间 3 HH:MM:SS -838:59:59~838:59:59
DATE 日期 3 YYYY-MM-SS 1000-01-01~9999-12-03
DATETIME 日期 时间 8 YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00~9999-12-31 23:59:59
TIMESTAMP 日期 时间 4 YYYY-MM-DD HH:MM:SS 1970-01-01 00:00:00 UTC~2038-01-19 03:14:07 UTC
  • 为什么时间类型 TIME 的取值范围不是 -23:59:59~23:59:59 呢?原因是 MySQL 设计的 TIME 类型,不光表示一天之内的时间,而且可以用来表示一个时间间隔,这个时间间隔可以超过 24 小时

  • 从MySQL5.5.27开始,2位格式的YEAR已经不推荐使用。YEAR默认格式就是“YYYY”,没必要写成YEAR(4),
    从MySQL 8.0.19开始,不推荐使用指定显示宽度的YEAR(4)数据类型

  • TIMESTAMP类型也可以表示日期时间,其显示格式与DATETIME类型相同,都是 YYYY-MM-DD HH:MM:SS ,需要4个字节的存储空间。但是TIMESTAMP存储的时间范围比DATETIME要小很多,只能存储“1970-01-01 00:00:01 UTC”到“2038-01-19 03:14:07 UTC”之间的时间。其中,UTC表示世界统一时间,也叫作世界标准时间

    • TIMESTAMP存储数据的时候需要对当前时间所在的时区进行转换,查询数据的时候再将时间转换回当前的时区。因此,使用TIMESTAMP存储的同一个时间值,在不同的时区查询时会显示不同的时间
    • TIMESTAMP和时区有关。TIMESTAMP会根据用户的时区不同,显示不同的结果。而DATETIME则只能反映出插入时当地的时区,其他时区的人查看数据必然会有误差的
  • 在实际项目中,尽量用 DATETIME 类型。因为这个数据类型包括了完整的日期和时间信息,取值范围也最大,使用起来比较方便。毕竟,如果日期时间信息分散在好几个字段,很不容易记,而且查询的时候,SQL 语句也会更加复杂

7. 文本字符串类型

文本字符串类型 值的长度 长度范围 占用的存储空间
CHAR(M) M 0<=M<=255 M个字节
VARCHAR(M) M 0<=M<=65535 M+1个字节
TINYTEXT L 0<=L<=255 L+2个字节
TEXT L 0<=L<=65535 L+2个字节
MEDIUMTEXT L 0<=L<=16777215 L+3个字节
LONGTEXT L 0<=L<=4294967295 L+4个字节
ENUM L 1<=L<=65535 1或2个字节
SET L 0<=L<=64 1,2,3,4或8个字节

7.1 CHAR与VARCHAR类型

字符串类型 特点 长度 占用的存储空间 占用的存储空间
CHAR(M) 固定长度 M 0<=M<=255 M个字节
VARCHAR(M) 可变长度 M 0<=M<=65535 (实际长度+1)个字节
  • MySQL5.0版本以上,varchar(20):指的是20字符

哪些情况使用 CHAR 或 VARCHAR 更好

类型 特点 空间上 时间上 适用场景
CHAR(M) 固定长度 浪费存储空间 效率高 存储不大,速度要求高
VARCHAR(M) 可变长度 节省存储空间 效率低 非CHAR的情况
  • 情况1:存储很短的信息。比如门牌号码101,201……这样很短的信息应该用char,因为varchar还要占个byte用于存储信息长度,本来打算节约存储的,结果得不偿失
  • 情况2:固定长度的。比如使用UUID为主键
  • 情况3:十分频繁改变的column。因为varchar每次存储都要有额外的计算,得到长度等工作,如果一个非常频繁改变的,那就要有很多的精力用于计算,而这些对于char来说是不需要的
  • 情况4:具体存储引擎中的情况
    • MyISAM 数据存储引擎和数据列:MyISAM数据表,最好使用固定长度(CHAR)的数据列代替可变长度(VARCHAR)的数据列。这样使得整个表静态化,从而使数据检索更快 ,用空间换时间
    • MEMORY 存储引擎和数据列:MEMORY数据表目前都使用固定长度的数据行存储,因此无论使用CHAR或VARCHAR列都没有关系,两者都是作为CHAR类型处理的
    • InnoDB 存储引擎,建议使用VARCHAR类型。因为对于InnoDB数据表,内部的行存储格式并没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),而且主要影响性能的因素是数据行使用的存储总量,由于char平均占用的空间多于varchar,所以除了简短并且固定长度的,其他考虑varchar。这样节省空间,对磁盘I/O和数据存储总量比较好

7.2 TEXT类型

文本字符串类型 值的长度 长度范围 占用的存储空间 特点
TINYTEXT L 0<=L<=255 L+2个字节 小文本、可变长度
TEXT L 0<=L<=65535 L+2个字节 文本、可变长度
MEDIUMTEXT L 0<=L<=16777215 L+3个字节 中等文本、可变长度
LONGTEXT L 0<=L<=4294967295 L+4个字节 大文本、可变长度
  • TEXT文本类型,可以存比较大的文本段,搜索速度稍慢,因此如果不是特别大的内容,建议使用CHAR,VARCHAR来代替
  • TEXT类型不用加默认值,加了也没用
  • text和blob类型的数据删除后容易导致“空洞”,使得文件碎片比较多,所以频繁使用的表不建议包含TEXT类型字段,建议单独分出去,单独用一个表

7.3 ENUM类型

不推荐使用

7.4 SET类型

和枚举类似,用的较少,故暂时跳过,待未来有需求时再考虑深入研究

7.5 二进制字符串类型

7.5.1 BINARY与VARBINARY类型

BINARY和VARBINARY类似于CHAR和VARCHAR,只是它们存储的是二进制字符串

二进制字符串类型 特点 值的长度 占用空间
BINARY(M) 固定长度 M(0<=M<=255) M个字节
VARBINARY(M) 可变长度 M(0<=M<=65535) M+1个字节
7.5.2 BLOB类型

MySQL中的BLOB类型包括TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB 4种类型,它们可容纳值的最大长度不同。可以存储一个二进制的大对象,比如 图片音频视频

需要注意的是,在实际工作中,往往不会在MySQL数据库中使用BLOB类型存储大对象数据,通常会将图片、音频和视频文件存储到 服务器的磁盘上 ,并将图片、音频和视频的访问路径存储到MySQL中

二进制字符串类型 值的长度 长度范围 占用的存储空间
TINYBLOB L 0 <= L <= 255 L + 1 个字节
BLOB L 0 <= L <= 65535(相当于64KB) L + 2 个字节
MEDIUMBLOB L 0 <= L <= 16777215 (相当于16MB) L + 3 个字节
LONGBLOB L 0 <= L <= 4294967295(相当于4GB) L + 4 个字节

7.6 TEXT和BLOB的使用注意事项

  • BLOB和TEXT值也会引起自己的一些问题,特别是执行了大量的删除或更新操作的时候。删除这种值会在数据表中留下很大的" 空洞 ",以后填入这些"空洞"的记录可能长度不同。为了提高性能,建议定期使用 OPTIMIZE TABLE 功能对这类表进行 碎片整理
  • 如果需要对大文本字段进行模糊查询,MySQL 提供了 前缀索引 。但是仍然要在不必要的时候避免检索大型的BLOB或TEXT值
  • 把BLOB或TEXT列 分离到单独的表 中。在某些环境中,如果把这些数据列移动到第二张数据表中,可以让你把原数据表中的数据列转换为固定长度的数据行格式,那么它就是有意义的。这会 减少主表中的碎片 ,使你得到固定长度数据行的性能优势。它还使你在主数据表上运行 SELECT * 查询的时候不会通过网络传输大量的BLOB或TEXT值

8. JSON 类型

不推荐使用,需要使用的话可以使用非关系型数据库如MongoDB/Redis

9. 空间类型

MySQL 空间类型扩展支持地理特征的生成、存储和分析。这里的地理特征表示世界上具有位置的任何东西,可以是一个实体,例如一座山;可以是空间,例如一座办公楼;也可以是一个可定义的位置,例如一个十字路口等等。MySQL中使用 Geometry(几何) 来表示所有地理特征。Geometry指一个点或点的集合,代表世界上任何具有位置的事物

未使用到,且不具有普遍性,暂不深入

你可能感兴趣的:(MySQL,mysql)