1. 数值类型
1.1 表
| 类型 |
大小(字节) |
范围 |
无符号范围 |
| tinyint |
1 |
-128~127 |
0~255 |
| smallint |
2 |
-2 -1 ~ 2 |
0~2-1 |
| mediumint |
3 |
-2 -1 ~ 2 |
0~2 -1 |
| int |
4 |
|
|
| bigint |
8 |
|
|
| float |
4 |
|
|
| double |
8 |
|
|
| decimal |
DECIMAL(M,D) ,如果M>D为M+2,否则为D+2 |
|
1.2 注意
- tinyint 我们一般用来存储状态,性别等
- 虽然mysql中的枚举也可以用来存储性别,而且效率更高。但是修改会不方便
- 例如数据库有一字段类型为enum(’a’,’b’),当库中有上百万数据的时候,可以把该字段更改为enum(’a’,’b’,’c’,’d’)么,速度会很慢。
- 对于无符号位的应用我们通常是用来设置主键,这样存储范围更大,而且主键数字一般也不会出现负数啊
- 我们存储年龄用什么最好?
- 考虑到 tinyint 的范围是 -128~127,可能有些不够用,我们可以使用 UNSIGNED TINYINT
- float 和 double 的选择?
- float 最多存8位10进制数,存储占用4个字节
- double 最多存18位10进制数。存储占用8个字节
2. 日期/时间类型
2.1 表
| 类型 |
大小(字节) |
格式 |
用途 |
| DATE |
3 |
YYYY-MM-DD |
日期值 |
| TIME |
3 |
HH:MM:SS |
时间值或持续时间 |
| YEAR |
1 |
YYYY |
年份值 |
| DATETIME |
8 |
YYYY-MM-DD HH:MM:SS |
混合日期和时间值 |
| TIMESTAMP |
4 |
YYYYMMDD HHMMSS |
混合日期和时间值,时间戳 |
2.2 注意
- mysql 中的日期函数,我们常用的其实也就只有 datetime 和 date
- 我并不推荐使用 TIMESTAMP,它会存在一个时区的问题,我们可以使用int来存一个时间戳
3. 字符串类型
3.1 表
| 类型 |
大小(字节) |
用途 |
| CHAR |
0-255 bytes |
定长字符串 |
| VARCHAR |
0-65535 bytes |
变长字符串 |
| TINYBLOB |
0-255 bytes |
不超过 255 个字符的二进制字符串 |
| TINYTEXT |
0-255 bytes |
短文本字符串 |
| BLOB |
0-65 535 bytes |
二进制形式的长文本数据 |
| TEXT |
0-65 535 bytes |
长文本数据 |
| MEDIUMBLOB |
0-16 777 215 bytes |
二进制形式的中等长度文本数据 |
| MEDIUMTEXT |
0-16 777 215 bytes |
中等长度文本数据 |
| LONGBLOB |
0-4 294 967 295 bytes |
二进制形式的极大文本数据 |
| LONGTEXT |
0-4 294 967 295 bytes |
极大文本数据 |
3.2 注意
- 常见面试题,CHAR 和 VARCHAR 的区别
- 定长和变长:char存储是定长的,varchar存储的是变长的。这就导致char可能造成空间的浪费
- 对于varchar,在声明时,如果长度不超过255,varchar会额外申请一个字节,存放实际的长度。
- 如果超过 255,8个比特为肯定是存不下,所以还会去申请一个字节,依次类推
- 所以说 varchar(4) 和 char(4) 就算都是存放4个字节的test,实际上占用情况也是不一样的

- 速度问题:就一般而言 char 和 varchar 的查询效率来说。char要优于varchar,但这不一定是绝对的
字符串的节取问题:这里我直接在 Mysql8.012 的版本来测试一下。
SELECT version();-- 8.0.12-- 这里我没有关闭严格模式show variables like 'sql_mode';-- 创建测试表CREATE TABLEIF NOT EXISTS `test_01` ( `id` INT UNSIGNED AUTO_INCREMENT NOT NULL, `name` VARCHAR (10) NOT NULL, PRIMARY KEY (`id`)) ENGINE = INNODB DEFAULT CHARSET = utf8;-- 进行数据插入 测试对象 varchar()INSERT INTO test_01 VALUES(1,'test');-- OKINSERT INTO test_01 VALUES(2, 'test1');-- OK INSERT INTO test_01 VALUES(4, '这是一个简单的测试11111111111');-- Data too long for column 'name' at row 1-- 没啥必要测试 varcharr-- 关闭 sql_mode 的严格模式,重启服务-- 测试 charINSERT into test_01 (name) VALUES('1234');-- okINSERT into test_01 (name) VALUES('abcde');-- Data too long for column 'name' at row 1-- 都会报错,呵呵。这才是正常的啊