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 TABLE
IF 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');
-- OK
INSERT 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 的严格模式,重启服务
-- 测试 char
INSERT into test_01 (name) VALUES('1234');
-- ok
INSERT into test_01 (name) VALUES('abcde');
-- Data too long for column 'name' at row 1
-- 都会报错,呵呵。这才是正常的啊