MySQL支持的数据类型
1、数值类型
整数类型 | 字节 | 最小值 | 最大值 |
---|---|---|---|
TINYINT | 1 | 有符号:-128 无符号:0 |
有符号:127 无符号:255 |
SMALLINT | 2 | 有符号:-32768 无符号:0 |
有符号:32767 有符号:65535 |
MEDIUMINT | 3 | 有符号:-8388608 无符号:0 |
有符号:8388607 无符号:1677215 |
INT、INTEFRE | 4 | 有符号:-2147483648 无符号:0 |
有符号:2147483647 无符号:4294967295 |
BIGINT | 8 | - | - |
浮点数类型 | 字节 | 最小值 | 最大值 |
FLOAT | 4 | - | - |
DOUBLE | 8 | - | - |
定点数类型 | 字节 | 最小值 | 最大值 |
DEC(M,D) DECIMAL(M,D) |
M+2 | - | - |
位类型 | 字节 | 最小值 | 最大值 |
BIT(M) | 1~8 | BIT(1) | BIT(8) |
1.1、整数类型
对于整数类型,MySQL 还支持在类型名称后面的小括号内指定显示宽度,例如 int(5) 表示当数值宽度小于 5 位的时候在数字前面填满宽度,如果不显示指定宽度则默认是 int(11)。一般配合 zerofull 使用,就是用 “0” 填充。举例:
1、创建表 t1,有 id1 和 id2 两个字段,指定其数值宽度分别为 int 和 int(5):
mysql> create table t1 (id1 int,id2 int(5));
Query OK, 0 rows affected (0.01 sec)
mysql> desc t1;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id1 | int(11) | YES | | NULL | |
| id2 | int(5) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.02 sec)
2、id1 和 id2 都插入数值1,没有异常:
mysql> insert into t1 values (1,1); #id1 和 id2 都插入数值1,没有异常
Query OK, 1 row affected (0.00 sec)
mysql> select * from t1;
+------+------+
| id1 | id2 |
+------+------+
| 1 | 1 |
+------+------+
1 row in set (0.00 sec)
3、分别修改 id1 和 id2 的字段类型,加入 zerofill 参数:
mysql> alter table t1 modify id1 int zerofill;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> alter table t1 modify id2 int(5) zerofill;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> select * from t1;
+------------+-------+
| id1 | id2 |
+------------+-------+
| 0000000001 | 00001 |
+------------+-------+
1 row in set (0.00 sec)
整数类型还有一个属性:AUTO_INCREMENT。在需要产生唯一属性标识符或顺序值时,可利用此属性,这个属性只用于整数类型。AUTO_INCREMENT 值一般从 1 开始,每行增加 1。一个表中最多只能有一个 AUTO_INCREMENT 列。对于任何想成为 AUTO_INCREMENT 的列,应该设置为 NOT NULL,并定义为 PRIMARY KEY 或定义为 UNIQUE 键。可按照下列方式定义 AUTO_INCREMENT 列:
mysql> create table AI (ID int auto_increment NOT NULL Primary key);
Query OK, 0 rows affected (0.00 sec)
#create table AI (ID int auto_increment NOT NULL,Primary key(ID));
#create table AI (ID int auto_increment NOT NULL,unique(ID));
mysql> desc AI;
+-------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
+-------+---------+------+-----+---------+----------------+
1 row in set (0.00 sec)
1.2、小数类型
对于小数的表示,MySQL 分为两种方式:浮点数和定点数。定点数在 MySQL 中采用字符串形式存放,比浮点数更精确,适合用来存放货币等精度高的数据。
浮点数和定点数都可以用类型名称加上 “(M,D)” 的方式来进行表达,"(M,D)" 表示该值一共显示 M 位数字(整数位+小数位),其中 D 位位于小数点后面有几位,M 和 D 又称为精度和标度。值得注意的是:浮点数后面跟 “(M,D)” 是非标准用法,如果要用于数据库迁移,则最好不要这么使用。float 和 double 在不指定精度时,默认会按照实际的精度(由实际的硬件和操作系统决定)来显示,而 decimal 在不指定精度时,默认的整数位为 10,默认的小数位为 0。
通过一个例子来比较 float、double 和 decimal 三者之间的不同:
1、创建表,分别将 id1,id2,id3 字段设置为 float(5,2),double(5,2),decimal(5,2):
mysql> create table t2 (
-> id1 float(5,2) default null,
-> id2 double(5,2) default null,
-> id3 decimal(5,2) default null);
Query OK, 0 rows affected (0.01 sec)
mysql> desc t2;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id1 | float(5,2) | YES | | NULL | |
| id2 | double(5,2) | YES | | NULL | |
| id3 | decimal(5,2) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
2、往 id1,id2,id3 这 3 个字段插入数据 1.23:
mysql> insert into t2 values(1.23,1.23,1.23);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t2;
+------+------+------+
| id1 | id2 | id3 |
+------+------+------+
| 1.23 | 1.23 | 1.23 |
+------+------+------+
1 row in set (0.00 sec)
3、再向 id1 和 id2 字段中插入数据 1.234,而 id3 中插入 1.23:
mysql> insert into t2 values(1.234,1.234,1.23);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t2;
+------+------+------+
| id1 | id2 | id3 |
+------+------+------+
| 1.23 | 1.23 | 1.23 |
| 1.23 | 1.23 | 1.23 |
+------+------+------+
2 rows in set (0.00 sec)
可以发现,id1 和 id2 由于精度的原因,舍弃了一位。
4、将id1,id2,id3 字段的精度和标度都去掉,再次插入 1.23:
mysql> alter table t2 modify id1 float;
Query OK, 0 rows affected (0.00 sec)
mysql> alter table t2 modify id2 double;
Query OK, 0 rows affected (0.00 sec)
mysql> alter table t2 modify id3 decimal;
Query OK, 3 rows affected, 3 warnings (0.00 sec)
mysql> desc t2;
+-------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| id1 | float | YES | | NULL | |
| id2 | double | YES | | NULL | |
| id3 | decimal(10,0) | YES | | NULL | |
+-------+---------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> insert into t2 values(1.234,1.234,1.234);
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> show warnings;
+-------+------+------------------------------------------+
| Level | Code | Message |
+-------+------+------------------------------------------+
| Note | 1265 | Data truncated for column 'id3' at row 1 |
+-------+------+------------------------------------------+
1 row in set (0.00 sec)
mysql> select * from t2;
+-------+-------+------+
| id1 | id2 | id3 |
+-------+-------+------+
| 1.23 | 1.23 | 1 |
| 1.23 | 1.23 | 1 |
| 1.23 | 1.23 | 1 |
| 1.234 | 1.234 | 1 |
+-------+-------+------+
4 rows in set (0.00 sec)
1.3、BIT(位)类型
对于 BIT(位)类型,用于存放位字段值,BIT(M) 可以用来存放多位二进制数,M 的范围从 1~64,如果不写则默认为 1 位。对于位字段,直接使用 SELECT 命令将看不到结果,可以用 bin() 或者 hex() 函数读取。
mysql> create table t3 (id BIT);
Query OK, 0 rows affected (0.00 sec)
mysql> desc t3;
+-------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| id | bit(1) | YES | | NULL | |
+-------+--------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> insert into t3 values(1);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t3;
+------+
| id |
+------+
| |
+------+
1 row in set (0.00 sec)
可以发现,直接 select * 的结果为 NULL。改用 bin() 和 hex() 函数试试:
mysql> select bin(id),hex(id) from t3;
+---------+---------+
| bin(id) | hex(id) |
+---------+---------+
| 1 | 1 |
+---------+---------+
1 row in set (0.00 sec)
数据插入 bit 类型字段时,首先转换为二进制,如果位数允许,将成功插入。否则,将报错。
mysql> insert into t3 values(2);
ERROR 1406 (22001): Data too long for column 'id' at row 1 #因为 2 的二进制为 “10”,两位
2、日期时间类型
日期类型的主要区别如下:
- 如果想用来表示年月日,通常用 DATE 来表示;
- 如果要用来表示年月日时分秒,通常用 DATETIME 来表示;
- 如果只用来表示时分秒,通常用 TIME 来表示。
日期和时间类型 | 字节 | 最小值 | 最大值 |
---|---|---|---|
DATE | 4 | 1000-01-01 | 9999-12-31 |
DATETIME | 8 | 1000-01-01 00:00:00 | 9999-12-31 23:59:59 |
TIMESTAMP | 4 | - | - |
TIME | 3 | -838:59:59 | 838:59:59 |
YEAR | 1 | 1901 | 2155 |
如果经常插入或者更新日期为系统时间,通常建议使用 DATESTAMP 来表示。
1、首先创建表 t ,字段分别为 date,time,datetime 三种日期类型:
mysql> create table t (d date,t time,dt datetime);
Query OK, 0 rows affected (0.00 sec)
mysql> desc t;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| d | date | YES | | NULL | |
| t | time | YES | | NULL | |
| dt | datetime | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
2、用 now() 函数插入当前日期:
mysql> insert into t values(now(),now(),now());
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> select * from t;
+------------+----------+---------------------+
| d | t | dt |
+------------+----------+---------------------+
| 2020-08-12 | 08:37:42 | 2020-08-12 08:37:42 |
+------------+----------+---------------------+
1 row in set (0.00 sec)
3、增加一个字段 ts 数据类型为 DATESTAMP:
mysql> alter table t add ts timestamp;
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc t;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+-------------------+-----------------------------+
| d | date | YES | | NULL | |
| t | time | YES | | NULL | |
| dt | datetime | YES | | NULL | |
| ts | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+
4 rows in set (0.00 sec)
默认值为 CURRENT_TIMESTAMP(系统日期),插入一个 NULL 试试:
mysql> insert into t(ts) values(NULL);
Query OK, 1 row affected (0.00 sec)
mysql> select ts from t;
+---------------------+
| ts |
+---------------------+
| 2020-08-12 08:42:02 |
+---------------------+
2 rows in set (0.00 sec)
3、字符串类型
字符串类型 | 字节 | 说明 |
---|---|---|
CHAR(M) | M | M 为 0~255 之间的整数 |
VARCHAR(M) | - | M 为 0~65535 之间的整数,值的长度 +1 个字节 |
TINYBLOB | 允许长度 0~255 字节,值的长度 +1 个字节 | |
BLOB | 允许长度 0~65535 字节,值的长度 +2 个字节 | |
MEIUMBLOB | 值的长度 +3 个字节 | |
LONGBLOB | 值的长度 +4 个字节 | |
TINYTEXT | 值的长度 +2 个字节 | |
TEXT | 值的长度 +2 个字节 | |
MEDIUMTEXT | 值的长度 +3 个字节 | |
LONGTEXT | 值的长度 +4 个字节 | |
VARBINARY(M) | 允许 0~M 个字节的变长字节字符串,值的长度 +1 个字节 | |
BINARY(M) | M | 允许 0~M 个字节的变长字节字符串 |
3.1、CHAR 和 VARCHAR 类型
1、创建表 vc,并定义两个字段 “v VARCHAE(4)” 和 “c CHAR(4)”:
mysql> create table vc (v varchar(4),c char(4));
Query OK, 0 rows affected (0.00 sec)
mysql> desc vc;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| v | varchar(4) | YES | | NULL | |
| c | char(4) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
2、同时插入字符串 “ab“:
mysql> insert into vc values("ab","ab");
Query OK, 1 row affected (0.00 sec)
mysql> select * from vc;
+------+------+
| v | c |
+------+------+
| ab | ab |
+------+------+
1 row in set (0.00 sec)
mysql> select length(v),length(c) from vc;
+-----------+-----------+
| length(v) | length(c) |
+-----------+-----------+
| 2 | 2 |
+-----------+-----------+
1 row in set (0.00 sec)
mysql> select CONCAT(V,'+'),CONCAT(C,'+') from vc;
+---------------+---------------+
| CONCAT(V,'+') | CONCAT(C,'+') |
+---------------+---------------+
| ab+ | ab+ |
+---------------+---------------+
1 row in set (0.00 sec)
4、ENUM 类型
枚举类型,它的值需要在创建表的时候通过枚举方式显示指定。
1、创建表 e,定义 gender 字段为枚举类型,成员为 “M” 和 “F”:
mysql> create table e (gender ENUM('M','F'));
Query OK, 0 rows affected (0.00 sec)
mysql> desc e;
+--------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------------+------+-----+---------+-------+
| gender | enum('M','F') | YES | | NULL | |
+--------+---------------+------+-----+---------+-------+
1 row in set (0.00 sec)
2、插入 4 条不同的数据:
mysql> insert into e values('M'),('1'),('f'),(NULL);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from e;
+--------+
| gender |
+--------+
| M |
| M |
| F |
| NULL |
+--------+
4 rows in set (0.00 sec)
ENUM 是忽略大小写的,在存储 “M” 和 “F” 时将它们都转成了大写,还可以看出对于插入不在 ENUM 指定范围内的值时,并没有警告,而是插入了 ENUM(‘M’,‘F’) 的第一个值 “M”!
5、SET 类型
SET 类型可以包含 0~64 个成员,每 8 个成员占 1 字节。SET 和 ENUM 类型除了在存储不同之外,最主要的区别在于 SET 类型一次还可以选取多个成员,而 ENUM 只能选一个:
mysql> alter table e add col set('a','b','c','d');
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc e;
+--------+----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+----------------------+------+-----+---------+-------+
| gender | enum('M','F') | YES | | NULL | |
| col | set('a','b','c','d') | YES | | NULL | |
+--------+----------------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> insert into e(col) values('a,b'),('a,b,a'),('a,c'),('a'),('c,d,d');
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select col from e;
+------+
| col |
+------+
| a,b |
| a,b |
| a,c |
| a |
| c,d |
+------+
9 rows in set (0.00 sec)
请注意,SET 类型不允许重复!