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,实际上占用情况也是不一样的
      • image.png
    • 速度问题:就一般而言 char 和 varchar 的查询效率来说。char要优于varchar,但这不一定是绝对的

字符串的节取问题:这里我直接在 Mysql8.012 的版本来测试一下。

  1. SELECT version();
  2. -- 8.0.12
  3. -- 这里我没有关闭严格模式
  4. show variables like 'sql_mode';
  5. -- 创建测试表
  6. CREATE TABLE
  7. IF NOT EXISTS `test_01` (
  8. `id` INT UNSIGNED AUTO_INCREMENT NOT NULL,
  9. `name` VARCHAR (10) NOT NULL,
  10. PRIMARY KEY (`id`)
  11. ) ENGINE = INNODB DEFAULT CHARSET = utf8;
  12. -- 进行数据插入 测试对象 varchar()
  13. INSERT INTO test_01 VALUES(1,'test');
  14. -- OK
  15. INSERT INTO test_01 VALUES(2, 'test1');
  16. -- OK
  17. INSERT INTO test_01 VALUES(4, '这是一个简单的测试11111111111');
  18. -- Data too long for column 'name' at row 1
  19. -- 没啥必要测试 varcharr
  20. -- 关闭 sql_mode 的严格模式,重启服务
  21. -- 测试 char
  22. INSERT into test_01 (name) VALUES('1234');
  23. -- ok
  24. INSERT into test_01 (name) VALUES('abcde');
  25. -- Data too long for column 'name' at row 1
  26. -- 都会报错,呵呵。这才是正常的啊