文章目录
一、数据类型的分类
数值大小
补充:
-
在MySQL中,整型可以指定有/无符号,默认是有符号的;通过unsigned来说明某个字段是无符号的。
-
bit (M) 在显示时,是按照ASII码对应的值显示。ASSII码表
-
float(M,D) M表示显示的总长度,D表示指定的小数位数,超出的会直接被舍弃。
-
decimal和float相比,decimal精度更高。float的小数最大位数D=7,而decimal的整数最大位数M=65,小数最大位数D=30,decimal默认M=10,D=0。注意:M>D
二、小数类型
2.1 float 类型
float(M,D) [unsigned]; M指定显示长度,D指定小数位数,占用4个字节的空间
注意: MySQL在保存值时会进行四舍五入 (M>D)
实例: float(4,2) 表示的范围是 -99.99~99.99;float(4,2) unsigned 表示的范围是 0~99.99
2.2 decimal 类型
decimal(M,D) [unsigned]; M指定显示长度,D指定小数位数
实例: decimal(5,2) 表示的范围是 -999.99~999.99;decimal(5,2) unsigned 表示的范围是 0~999.99
补充: float和decimai虽然都是浮点类型,但是表示的精度不一样。float表示的精度大约是7位。
decimal的显示长度M最大为65位,小数位数D最大为30位。如果M和D被省略,默认decimal(10,0)。
2.3 /etc/my.cnf
如果插入的数值超出表示范围,MySQL会显示能够表示的最大值。
为了防止超出显示范围的值插入,我们需要在MySQL的配置文件中配置一下。路径: /etc/my.cnf
mysqld就是配置MySQL服务端启动时所需要读到的参数信息,添加sql_mode的校验。
再来验证一下,此时,插入超出显示范围的值就会直接报错,提示所插入的值超出范围。
三、字符串类型
3.1 char 类型
char(L); 固定长度字符串,L是可以存储的长度,单位字符,最长255个字符(L个字符长度)
实例:
create database class_info charset=utf8 collate utf8_general_ci;
create table test1(name char(3));
insert into test1 values('jon');
请问:此次向表中插入的数据所占内存为几个字节? 9字节
"长度" :长度不等同于字节数量。
"固定" :一旦长度L确定,需要结合字符集来考录占用内存大小的。“固定” 的本质是已经将内存开辟好了,消耗的内存是一样大的。
注意:utf8字符集每一个字符是使用1-3个字节表示的。
utf8mb4字符集每一个字符是使用1-4个字节表示的。
推荐博文:【MySQL】数据库的存储引擎、字符集、校验规则(InnoDB、ACID、utf8、utf8mb4)
3.2 varchar 类型
varchar(L); 可变长度字符串,L表示字符长度,单位字符,最长12844个字符,最大65535个字节
varchar类型占用内存的大小=字符串真实占用内存大小 + 1~2个字节(表示字符串的长度)
当前字符串占用的内存<255的,那么+1个字节;当前字符串占用的内存>=255的,那么+2个字节。
实例:
create database class_info charset=utf8 collate utf8_general_ci;
create table test2(name varchar(2));
insert into test2 values('李明');
请问:此次向表中插入的数据所占内存为几个字节? 5字节(2+2+1)
varchar类型最大可占用65535个字节,那么L最大是(65535-[1,2])/3 ≈ \approx ≈ 12844
char和varchar的对比
实际存储 | char(4) | varch(4) | char所占字节 | varchar所占字节 |
---|---|---|---|---|
abcd | abcd | abcd | 4$\times$3=12 | 4$\times$3+1=13 |
A | A | A | 4$\times$3=12 | 1$\times$3+1=4 |
ABCDE | × | × | 数据超过指定长度 | 数据超过指定长度 |
3.3 如何选择固定长度还是变长字符串
- 如果数据确定长度都一样,就使用定长(char),比如:身份证,手机号,md5
- 如果数据长度有变化,就使用变长(varchar), 比如:名字,地址,但是你要保证最长的能存的进去
- 定长的磁盘空间比较浪费,但是效率高
- 变长的磁盘空间比较节省,但是效率低
四、时间日期类型
4.1 date
date:日期"yyyy-mm-dd",占用三字节
4.2 datetime
datatime :时间日期格式"yyyy-mm-dd hh:mm:ss" 表示范围从1000到9999,占用八字节
4.3 timestamp
timestamp:时间戳,从1970年开始的 yyyy-mm-dd hh:mm:ss格式和datetime完全一致,占用四字节
实例:
MariaDB [class_info]> create table time(t1 date,t2 datetime,t3 timestamp);
Query OK, 0 rows affected (0.01 sec)
MariaDB [class_info]> desc time;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+-------------------+-----------------------------+
| t1 | date | YES | | NULL | |
| t2 | datetime | YES | | NULL | |
| t3 | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+
3 rows in set (0.00 sec)
insert into time values('2021-03-31','2021-03-31 17:17:00','2021-03-31 17:17:00');
Query OK, 1 row affected (0.01 sec)
MariaDB [class_info]> select * from time;
+------------+---------------------+---------------------+
| t1 | t2 | t3 |
+------------+---------------------+---------------------+
| 2021-03-31 | 2021-03-31 17:17:00 | 2021-03-31 17:17:00 |
+------------+---------------------+---------------------+
1 row in set (0.00 sec)
MariaDB [class_info]> insert into time(t1,t2) values('2021-03-31','2021-03-31 17:21:00');
Query OK, 1 row affected (0.01 sec)
MariaDB [class_info]> select * from time;
+------------+---------------------+---------------------+
| t1 | t2 | t3 |
+------------+---------------------+---------------------+
| 2021-03-31 | 2021-03-31 17:17:00 | 2021-03-31 17:17:00 |
| 2021-03-31 | 2021-03-31 17:21:00 | 2021-03-31 17:21:18 |
+------------+---------------------+---------------------+
2 rows in set (0.00 sec)
补充:
MariaDB [class_info]> show create table time\G
*************************** 1. row ***************************
Table: time
Create Table: CREATE TABLE `time` (
`t1` date DEFAULT NULL,
`t2` datetime DEFAULT NULL,
`t3` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
在查看time表的t3字段时,有这样DEFAULT CURRENT_TIMESTAMP 和ON UPDATE CURRENT_TIMESTAMP两个选项。这两个同时存在时表示不论是插入还是修改都会更新时间戳。
- DEFAULT CURRENT_TIMESTAMP 表示在第一次插入数据的时候会更新时间戳
- ON UPDATE CURRENT_TIMESTAMP 表示在修改数据时会更改时间戳
五、string类型
5.1 enum类型
enum(‘选项1’,‘选项2’,‘选项3’, …); 枚举是“单选”类型,实际只存储了其中一个值
5.2 set类型
set(‘选项值1’,‘选项值2’,‘选项值3’, …); 集合是“多选”类型 ,实际存储了其中任意多个值
实例: 如果插入的值不在集合中,则插入失败。
MariaDB [class_info]> create table string(sex enum('男','女'),hobby set('登山','越野','推本','篮球'));
Query OK, 0 rows affected (0.01 sec)
MariaDB [class_info]> show create table string;
+--------+-----------------------------------+
| Table | Create Table |
+--------+-----------------------------------+
| string | CREATE TABLE `string` (
`sex` enum('男','女') DEFAULT NULL,
`hobby` set('登山','越野','推本','篮球') DEFAULT NULL)
ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------+------------------------------------+
1 row in set (0.00 sec)
MariaDB [class_info]> insert into string(sex) values('男');
Query OK, 1 row affected (0.00 sec)
MariaDB [class_info]> insert into string(sex) values('女');
Query OK, 1 row affected (0.00 sec)
MariaDB [class_info]> insert into string(sex) values('中性');
ERROR 1265 (01000): Data truncated for column 'sex' at row 1
MariaDB [class_info]> select * from string;
+------+-------+
| sex | hobby |
+------+-------+
| 男 | NULL |
| 女 | NULL |
+------+-------+
2 rows in set (0.00 sec)
MariaDB [class_info]> insert into string(hobby) values('推本');
Query OK, 1 row affected (0.00 sec)
MariaDB [class_info]> insert into string(hobby) values('推本,越野');
Query OK, 1 row affected (0.00 sec)
MariaDB [class_info]> select * from string;
+------+---------------+
| sex | hobby |
+------+---------------+
| 男 | NULL |
| 女 | NULL |
| NULL | 推本 |
| NULL | 越野,推本 |
+------+---------------+
4 rows in set (0.00 sec)
MariaDB [class_info]> insert into string(hobby) values('游泳');
ERROR 1265 (01000): Data truncated for column 'hobby' at row 1