Skip to content

数据类型

数值类型

数值类型分 严格数值类型近似数值类型

  • 严格数值类型
    • INTEGER
    • SMALLINT
    • DECIMAL
    • NUMBERIC
  • 近似数值类型
    • FLOAT
    • REAL
    • DOUBLE PRECISION
  • 扩展之后的数据类型
    • TINYINT
    • MEDIUMINT
    • BIGINT
    • BIT

整数

整数类型 字节 有符号 无符号
TINYINT 1 -128 ~ 127 0 ~ 255
SMALLINT 2 -32768 ~ 32767 0 ~ 65535
MEDIUMINT 3 -8388608 ~ 8388607 0 ~ 1677215
INT、INTEGER 4 -2147473648 ~ 2147483647 0 ~ 4294967295
BIGINT 8 -263 ~ 263 - 1 0 ~ 264

在建表时一般会在数据类型后面加上指定长度来表示字段数据类型许可的范围,如 INT(6) 表示 INT 类型的数据、最大长度为 6,不满 6 位会自动填充。若不指定长度,则默认为 INT(11)

整型的字段可以使用 AUTO_INCREMENT 属性,但一个表中只能有一个 AUTO_INCREMENT 属性,一般用于自增主键。

小数

浮点数类型 字节 最小值 最大值
FLOAT 4 \(\pm\)1.175494351E-38 \(\pm\)3.402823466E+38
DOUBLE 8 \(\pm\)2.2250738585072014E-308 \(\pm\)1.7976931348623157E+308
定点数类型 字节 描述
DEC(M, D) 或 DECIMAL(M, D) M+2 最大值取值范围与 DOUBLE 相同,给定DECIMAL 的有效取值范围由 M 和 D 决定

小数分 「浮点数」 和 「定点数」,浮点数分「单精度浮点型 Float」和「双精度浮点型」;定点数只有一种「decimal」,在 MySQL 内部中以字符串的形式存在,比浮点数更为精确,适合用来表示精度特别高的数据。

浮点数和定点数都可以使用 (M, D) 的方式来表示。M 表示 整数位+小数位 的位数,D 表示小数位数。M 称为精度,D 称为标度。

mysql> CREATE TABLE test1 (
    ->     aId FLOAT(6,2)   DEFAULT NULL,
    ->     bId DOUBLE(6,2)  DEFAULT NULL,
    ->     cId DECIMAL(6,2) DEFAULT NULL
    -> );
Query OK, 0 rows affected, 2 warnings (0.06 sec)

mysql> INSERT INTO test1 VALUES (1234.12,1234.12,1234.12);
Query OK, 1 row affected (0.02 sec)

mysql> SELECT * FROM test1;
+---------+---------+---------+
| aId     | bId     | cId     |
+---------+---------+---------+
| 1234.12 | 1234.12 | 1234.12 |
+---------+---------+---------+
1 row in set (0.00 sec)

超出精度的部分会被截断:

mysql> INSERT INTO test1 VALUES (1234.123,1234.123,1234.123);
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> SELECT * FROM test1;
+---------+---------+---------+
| aId     | bId     | cId     |
+---------+---------+---------+
| 1234.12 | 1234.12 | 1234.12 |
| 1234.12 | 1234.12 | 1234.12 | -- 超出精度的部分会被截断
+---------+---------+---------+
3 rows in set (0.00 sec)

如不指定精度和标度,则浮点数会按照实际精度(不超过范围)存储,定点数会省略小数:

mysql> CREATE TABLE test2 (
    -> aId FLOAT   DEFAULT NULL,
    -> bId DOUBLE  DEFAULT NULL,
    -> cId DECIMAL DEFAULT NULL
    -> );
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO test VALUES (12.34567, 12.34567, 12.34567);
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> SELECT * FROM test;
+---------+----------+------+
| aId     | bId      | cId  |
+---------+----------+------+
| 12.3457 | 12.34567 |   12 |
+---------+----------+------+
2 rows in set (0.00 sec)

位类型

位类型 字节 最小值 最大值
BIT(M) 1~8 BIT(1) BIT(64)

日期时间类型

类型 日期格式 日期范围 字节
YEAR YYYY 1901 ~ 2155 1
TIME HH:MM:SS -838:59:59 ~ 838:59:59 3
DATE YYYY-MM-DD 1000-01-01 ~ 9999-12-30 3
DATETIME YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 8
TIMESTAMP YYYY-MM-DD HH:MM:SS 1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC 4

YEAR

year 有三种方式表示:

  • 用 4 位的数字或者字符串表示,两者效果相同,表示范围 1901 - 2155,插入超出范围的数据会报错。
  • 以 2 位**字符串**格式表示,范围为 00~99。
    • '00'~'69' 表示 2000~2069;
    • '70'~'99' 表示1970~1999;
    • '0' 和 '00' 都会被识别为 2000,超出范围的数据也会被识别为 2000。
  • 以 2 位**数字**格式表示,范围为 1~99。
    • 1~69 表示 2001~2069;
    • 70~99 表示 1970~1999;
    • 但 0 值会被识别为0000,这和 2 位字符串被识别为 2000 有所不同
mysql> CREATE TABLE test3 (
    -> theYear YEAR
    -> );
Query OK, 0 rows affected (0.04 sec)

mysql> INSERT INTO test3 VALUES
    -> (1997),      -- 插入年份
    -> ('2001');    -- 插入年份
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM test3;
+---------+
| theYear |
+---------+
|    1997 |
|    2001 |
+---------+
2 rows in set (0.00 sec)

插入 2 位字符串的栗子:

mysql> INSERT INTO test3 VALUES
    -> ('05'),
    -> ('69'),
    -> ('70'),
    -> ('99'),
    -> ('0'),
    -> ('00');
Query OK, 6 rows affected (0.01 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM test3;
+---------+
| theYear |
+---------+
|    2005 |
|    2069 |
|    1970 |
|    1999 |
|    2000 |
|    2000 |
+---------+
8 rows in set (0.00 sec)

插入 2 位数字的栗子:

mysql> INSERT INTO test3 VALUES
    -> (05),
    -> (69),
    -> (70),
    -> (99),
    -> (0),
    -> (00);
Query OK, 6 rows affected (0.01 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM test3;
+---------+
| theYear |
+---------+
|    2005 |
|    2069 |
|    1970 |
|    1999 |
|    2000 | -- 字符串的 00 是 2000 年
|    2000 |
|    2005 | --  ------插入的数据从这开始
|    2069 |
|    1970 |
|    1999 |
|    0000 | -- 数字的 00 是 0000 年
|    0000 |
+---------+
14 rows in set (0.00 sec)

TIME

类型 日期格式 日期范围 字节
TIME HH:MM:SS -838:59:59 ~ 838:59:59 3
mysql> CREATE TABLE test4 (
    -> theTime TIME
    -> );
Query OK, 0 rows affected (0.04 sec)

mysql> INSERT INTO test4 VALUES
    -> ('18:05:06'),
    -> ('21:45'),
    -> ('2 12:49'),
    -> ('2 12:49:15'),
    -> ('2 05'),
    -> ('18');
Query OK, 6 rows affected (0.01 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM test4;
+----------+
| theTime  |
+----------+
| 18:05:06 |    -- -> ('18:05:06'),   正常输入
| 21:45:00 |    -- -> ('21:45'),      表示 21点45分
| 60:49:00 |    -- -> ('2 12:49'),    表示 2天+12小时49分
| 60:49:15 |    -- -> ('2 12:49:15'), 表示 2天+12小时49分15秒
| 53:00:00 |    -- -> ('2 05'),       表示 2天+5小时
| 00:00:18 |    -- -> ('18'),         表示18秒
+----------+
6 rows in set (0.00 sec)

DATE

类型 日期格式 日期范围 字节
DATE YYYY-MM-DD 1000-01-01 ~ 9999-12-30 3

DATE 的表示一般很多种,如:

  • 字符串形式
    • 'YYYY-MM-DD'
    • 'YYYYMMDD'
    • 'YY-MM-DD'
    • 'YYMMDD'
  • 数字形式
    • YYYYMMDD
    • YYMMDD
mysql> CREATE TABLE test5 (
    -> theDate DATE
    -> );
Query OK, 0 rows affected (0.04 sec)

mysql> INSERT INTO test5 VALUES
    -> ('1949-10-01'),
    -> ('19970701'),
    -> ('00-01-01'),
    -> ('70-01-01'),
    -> (19491001),
    -> (000101),
    -> (700101);
Query OK, 7 rows affected (0.02 sec)
Records: 7  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM test5;
+------------+
| theDate    |
+------------+
| 1949-10-01 |  -- -> ('1949-10-01'),
| 1997-07-01 |  -- -> ('19970701'),
| 2000-01-01 |  -- -> ('00-01-01'), 00~69 表示 2000 年 ~ 2069 年
| 1970-01-01 |  -- -> ('70-01-01'), 70~99 表示 1970 年 ~ 1999 年
| 1949-10-01 |  -- -> (19491001),
| 2000-01-01 |  -- -> (000101),     00~69 表示 2000 年 ~ 2069 年
| 1970-01-01 |  -- -> (700101);     70~99 表示 1970 年 ~ 1999 年
+------------+
7 rows in set (0.00 sec)

mysql> INSERT INTO test5 VALUES (9901011);
Query OK, 1 row affected (0.01 sec)

mysql> SELECT * FROM test5;
+------------+
| theDate    |
+------------+
| 1949-10-01 |
| 1997-07-01 |
| 2000-01-01 |
| 1970-01-01 |
| 1949-10-01 |
| 2000-01-01 |
| 1970-01-01 |
| 1999-01-01 |
| 0990-10-11 |  -- (9901011) 表示 990 年 10 月 11 r
+------------+
9 rows in set (0.00 sec)

DATETIME

类型 日期格式 日期范围 字节
DATETIME YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 8
mysql> CREATE TABLE test6 (
    -> theDateTime DATETIME
    -> );
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO test6 VALUES
    -> ('1997-07-01 00:00:00'),
    -> (19970701000000),
    -> ('00-01-01 00:00:00'),
    -> (000101000000),
    -> ('70-01-01 00:00:00'),
    -> (700101000000);
Query OK, 6 rows affected (0.01 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM test6;
+---------------------+
| theDateTime         |
+---------------------+
| 1997-07-01 00:00:00 | -- -> ('1997-07-01 00:00:00'),
| 1997-07-01 00:00:00 | -- -> (19970701000000),
| 2000-01-01 00:00:00 | -- -> ('00-01-01 00:00:00'),
| 2000-01-01 00:00:00 | -- -> (000101000000),
| 1970-01-01 00:00:00 | -- -> ('70-01-01 00:00:00'),
| 1970-01-01 00:00:00 | -- -> (700101000000);
+---------------------+
6 rows in set (0.00 sec)

看过 YEAR、DATE、DATETIME,其实我们大概可以了解到,在 MySQL 时间数据类型中,年份如果写全则是字面上的年份,如果简写,那么 00~69 表示 2000 ~ 206970~99 表示 1970 ~ 1999

TIMESTAMP

类型 日期格式 日期范围 字节
TIMESTAMP YYYY-MM-DD HH:MM:SS 1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC 4

TIMESTAMP 类型和 DATETIME 类型的格式相同,存储 4 个字节(比DATETIME少),取值范围比 DATETIME 小。

使用场景

  • 仅用来存储 ,通常使用 YEAR,因为比 DATE 需要更少的空间
  • 用来存储 年月日,通常用 DATE
  • 用来存储 时分秒,通常用 TIME
  • 用来存储 年月日时分秒,通常用 DATETIME
  • 用来存储当前时间,通常使用 TIMESTAMP
  • 通常更方便的做法是用一个 INT 类型来记录时间戳

字符串类型

字符串类型 字节 描述和存储需求
CHAR(M) M M 为 0~255 的整数
VARCHAR(M) 值的长度 + 1字节 M 为 0~65535 的整数
TINYBLOB 值的长度 + 1字节 允许长度为 0~255字节
BLOB 值的长度 + 2字节 允许长度为 0~65535字节
MEDIUMBLOB 值的长度 + 3字节 允许长度为 0~167772150字节
LONGBLOB 值的长度 + 4字节 允许长度为 0~4294967295字节
TINYTEXT 值的长度 + 2字节 允许长度为 0~255字节
TEXT 值的长度 + 2字节 允许长度为 0~65535字节
MEDIUMTEXT 值的长度 + 3字节 允许长度为 0~167772150字节
LONGTEXT 值的长度 + 4字节 允许长度为 0~4294967295字节
VARBINARY(M) 值的长度 + 1字节 允许长度为 0~M字节的**变长**字节字符串
BINARY(M) M 允许长度为 0~M字节的**定长**字节字符串

CHAR 和 VARCHAR

字符串类型 字节 描述和存储需求
CHAR(M) M M 为 0~255 的整数
VARCHAR(M) 值的长度 + 1字节 M 为 0~65535 的整数

CHAR 适合一些长度固定的数据,如 MD5 编码、手机号码等; VARCHAR 适合长度不固定的数据,如备注、描述等。

eg:

CREATE TABLE test7 (
    name CHAR(18),
    note VARCHAR(500)
);
  • name 字段不管输入多少字节的数据,都占用 18 字节的空间,最长不能超过 18 字节;
  • note 字段输入多少字节的数据,就占用多少字节的数据,但不能超过限定的 500 字节。
  • CHAR 会截断尾部的空格,VARCHAR 则会保留尾部的空格。

BINARY 和 VARBINARY

BLOB

TEXT

ENUM

SET