MySQL_数据类型

内容

  1. 数值类型
  2. 字符串类型
  3. 日期和时间类型
  4. enum和set

设计数据类型的重要性

业务层是工作在内存上的,速度很快。

而最先达到性能瓶颈的一般都是数据库,因为数据库涉及到磁盘IO。磁盘IO是很慢的。

所以我们定义数据表时,每一个字段的数据类型都要好好去斟酌。

MySQL server虽然工作在内存上,但是它要读取数据、索引时,就要进行磁盘IO。磁盘IO次数越少,则性能越高,所以我们要尽力减少磁盘IO次数。

MySQL数据类型定义了数据的大小范围,因此使用时选择合适的类型,不仅会降低表占用的磁盘空间,还能间接减少磁盘IO的次数,提高了表的访问效率;不仅如此,索引的效率也和数据类型息息相关。

数值类型

整数类型 字节 最小值 最大值
TINYINT 1 有符号-128;无符号0 有符号127;无符号255
SMALLINT 2 有符号-32768;无符号0 有符号32767;无符号65535
MEDIUMINT 3 有符号-8388608;无符号0 有符号8388607;无符号1677215
INTINTEGER 4 有符号-2147483648;无符号0 有符号2147483647;无符号4294967295
BIGINT 8 有符号-9223372036854775808;无符号0 有符号9223372036854775807;无符号18446744073709551615
浮点数类型 字节 最小值 最大值
FLOAT 4 ±1.175494351E38\pm 1.175494351E-38 ±3.402823466E+38\pm 3.402823466E+38
DOUBLE 8 ±2.2250738585072014E308\pm 2.2250738585072014E-308 ±1.7976931348623517E+308\pm 1.7976931348623517E+308

其中浮点类型推荐使用decimal类型(保存为字符串格式)。数据精度范围很大,约28位,而且计算时,越界、溢出会报错,而普通整数、浮点只是截断。

  • 注意
    • age INT(9)这不是意味着定义了一个长度为9字节的整型。数值类型占用内存的大小是固定的,和具体的类型是强相关的,括号内的数目只是代表它显示的宽度。

示例

1
create table user(age TINYINT unsigned NOT NULL default 0)

字符串类型

字符串类型 字节 描述及存储需求
CHAR(M) M M为0~255之间的整数。占用空间M字节。
VARCHAR(M) M为0~65535之间的整数,值的长度+1个字节
TINYBLOB 允许长度0~255字节,值的长度+1字节
BLOB 允许长度0~65535字节,值的长度+2字节
MEDIUMBLOB 允许长度0~167772150字节,值的长度+3字节
LONGBLOB 允许长度0~4294967295字节,值的长度+4字节
TINYTEXT 允许长度0~255字节,值的长度+2字节
TEXT 允许长度0~65535字节,值的长度+2字节
MEDIUMTEXT 允许长度0~167772150字节,值的长度+3字节
LONGTEXT 允许长度0~4294967295字节,值的长度+4字节
VARBINARY(M) 允许长度0~M个字节的变长字节字符串,值的长度+1字节
BINARY(M) M 允许长度0~M个字节的定长字节字符串
  • CHAR(12)VARCHAR(12)的区别在于,如果实际的字符串长度不够12,VARCHAR大小则为实际的长度,而CHAR的大小则依旧是12字节;共同点:如果数据超过12则都会产生截断。
  • BLOB一般用于存储二进制格式的图片、音频。
  • TEXT的应用:留言板,商品的备注说明,聊天信息的存储。一些大文本。

初期设计时,可能低估了将来的数据量,可能会超过设计的范围。

数据库中字符串以单引号包裹。

  • SQL注入式攻击——字符串拼接导致的问题。

日期和时间类型

日期和时间类型 字节 最小值 最大值
DATE 4 1000-01-01 9999-12-31
DATETIME 8 1000-01-01 00:00:00 9999-12-31 23:59:59
TIMESTAMP 4 19700101080001 2038年的某个时刻
TIME 3 -838:59:59 838:59:59
YEAR 1 1901 2155
  • 日期类型是做项目过程中经常使用的类型信息,尤其是TIMESTAMPDATETIME两个类型;
  • 注意TIMESTAMP会自动更新时间,非常适合需要记录最新更新时间的场景,对应的函数是unix_timestamp(now());而DATETIME需要手动更新。
  • 这里虽然介绍了MySQL的时间类型,但是现代的后端开发,MySQL基本已经很少使用自身的存储过程、存储函数、触发器、外键设置了,尽量把复杂的业务在业务层处理。涉及的时间操作也是同理。应该让MySQL聚焦在核心的增删改查操作上。

时间戳示例

1
2
select now();					# 2022-04-28 19:30:11
select unix_timestamp(now()); # 1617683855

unix_timestamp(now());用于生成UNIX的时间戳,数值含义是自1970年起的秒数。用整型存储。

枚举和集合(enum和set)

  • 这两种类型都是限制该字段只能取预定义的固定的某些值。比如性别——只能男或女。
  • 枚举字段只能取一个唯一的值。
  • 集合字段可以取任意个值。

示例

1
sex enum('M','W') default 'M'