MySQL_数据类型
内容
- 数值类型
- 字符串类型
- 日期和时间类型
- 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 |
INT 、INTEGER |
4 | 有符号-2147483648 ;无符号0 |
有符号2147483647;无符号4294967295 |
BIGINT |
8 | 有符号-9223372036854775808 ;无符号0 |
有符号9223372036854775807;无符号18446744073709551615 |
浮点数类型 | 字节 | 最小值 | 最大值 |
---|---|---|---|
FLOAT |
4 | ||
DOUBLE |
8 |
其中浮点类型推荐使用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 |
- 日期类型是做项目过程中经常使用的类型信息,尤其是
TIMESTAMP
和DATETIME
两个类型; - 注意
TIMESTAMP
会自动更新时间,非常适合需要记录最新更新时间的场景,对应的函数是unix_timestamp(now())
;而DATETIME
需要手动更新。 - 这里虽然介绍了MySQL的时间类型,但是现代的后端开发,MySQL基本已经很少使用自身的存储过程、存储函数、触发器、外键设置了,尽量把复杂的业务在业务层处理。涉及的时间操作也是同理。应该让MySQL聚焦在核心的增删改查操作上。
时间戳示例
1 | select now(); # 2022-04-28 19:30:11 |
unix_timestamp(now());
用于生成UNIX的时间戳,数值含义是自1970年起的秒数。用整型存储。
枚举和集合(enum和set)
- 这两种类型都是限制该字段只能取预定义的固定的某些值。比如性别——只能男或女。
- 枚举字段只能取一个唯一的值。
- 集合字段可以取任意个值。
示例
1 | sex enum('M','W') default 'M' |