当前位置:网站首页>【MySQL】常见数据类型总结
【MySQL】常见数据类型总结
2022-06-10 20:46:00 【yuelinghou】
文章目录
一. 数值类型
1. 概览
| 类型 | 字节 | 取值范围 |
|---|---|---|
| tinyint | 1 | 带符号:[-128, 127] 不带符号:[0, 255] |
| smallint | 2 | 带符号:[-32768, 32767] 不带符号:[0, 65535] |
| mediumint | 3 | 带符号:[-8388608, 8388607] 不带符号:[0, 16777215] |
| int | 4 | 带符号:[-2147483648, 2147483647] 不带符号:[0, 4294967295] |
| bigint | 8 | 带符号:[-9223372036854775808, 9223372036854775807] 不带符号:[0, 18446744073709551615] |
2. tinyint类型
- 类型大小:1字节
- 带符号时的数据范围:[-128, 127]
- 不带符号时的数据范围:[0, 255]
示例:
有符号的tinyint类型字段:
mysql> create table if not exists t1(
-> num tinyint);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t1 values(127);
Query OK, 1 row affected (0.01 sec)
mysql> insert into t1 values(128);
ERROR 1264 (22003): Out of range value for column 'num' at row 1
mysql> select * from t1;
+------+
| num |
+------+
| 127 |
+------+
1 row in set (0.00 sec)
无符号的tinyint类型字段:
mysql> create table if not exists t2(
-> num tinyint unsigned);
Query OK, 0 rows affected (0.03 sec)
mysql> insert into t2 values (255);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2 values (256);
ERROR 1264 (22003): Out of range value for column 'num' at row 1
mysql> select * from t2;
+------+
| num |
+------+
| 255 |
+------+
1 row in set (0.01 sec)
说明:
- 在MySQL中,数值类型都可以指定是有符号的和无符号的,默认是有符号的。可以在数值类型后面加上
unsigned来说明某个字段是无符号的。 - 注意尽量不使用unsigned,比如对于int类型可能存放不下的数据,int unsigned同样可能存放不下,与其如此,还不如设计时,将int类型提升为bigint类型。
- MySQL对于数据的存储,本身具有更严格的约束。说准确点,MySQL数据类型本身就是一种约束。

3. bit类型
基本语法:
bit(M):位字段类型。M表示每个值的位数,范围从1到64。如果M被忽略,默认为1。
示例:
原因在于:bit类型的字段在显示时,是按照ASCII码对应的值来显示的,而ASCLL码为10的是一个控制字符,自然无法显示。下面我们插入65这个数字,看看这次能否显示出来:
mysql> select * from t1;
+------+------+
| id | a |
+------+------+
| 10 |
|
+------+------+
1 row in set (0.00 sec)
mysql> insert into t1 values (65, 65);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t1;
+------+------+
| id | a |
+------+------+
| 10 |
|
| 65 | A |
+------+------+
2 rows in set (0.00 sec)
可以看到65数字插入a字段后,显示出来的是’A’,确实bit说明了bit类型的字段在显示时,是按照ASCII码对应的值来显示的。
作为一种SQL数据类型,bit也有相应的数据范围约束,即我们插入的数据二进制长度不能超过bit(M)限定的大小:
mysql> create table if not exists t2(
-> gender bit(1) comment '0:男, 1:女');
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t2 values (0);
Query OK, 1 row affected (0.02 sec)
mysql> insert into t2 values (2);
ERROR 1406 (22001): Data too long for column 'gender' at row 1
mysql>
bit使用场景:实际中,如果我们有这样的值,只存放0或1,这时可以定义bit(1)类型的字段。缺点是无法被显示出来,但是这样可以节省空间,如果这张表只是交给机器识别的话,我们可以定义bit字段。
4. float类型
语法:
float(m, d) [unsigned]: M指定显示长度,d指定小数位数,占用空间4个字节空间。
注意:MySQL在保存值时会进行四舍五入。
示例:
float(4, 2)表示的数据范围是[-99.99 ~ 99.99],下面我们来看看该类型的约束情况:
mysql> create table if not exists t1(
-> salary float(4, 2));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into t1 values (99.99);// 在规定范围之内,插入成功
Query OK, 1 row affected (0.01 sec)
mysql> insert into t1 values (99.993);// 四舍后插入成功
Query OK, 1 row affected (0.00 sec)
mysql> insert into t1 values (99.995);// 五入后插入失败
ERROR 1264 (22003): Out of range value for column 'salary' at row 1
mysql> insert into t1 values (100.00);// 超过数据类型规定的范围,插入失败
ERROR 1264 (22003): Out of range value for column 'salary' at row 1
mysql> select * from t1;// 最终只有前两个插入成功
+--------+
| salary |
+--------+
| 99.99 |
| 99.99 |
+--------+
2 rows in set (0.00 sec)
对浮点数而言,无符号类型的浮点数还是经常用到的,比如如下字段:工资、得分等。如果定义的是float(4, 2) unsigned,这时我们把它指定为无符号的数,范围是[0 ~ 99.99]。
mysql> create table if not exists t2(
-> score float(4, 2) unsigned);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t2 values (28.4);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2 values (-23.3);// 不允许插入负数
ERROR 1264 (22003): Out of range value for column 'score' at row 1
mysql> select * from t2;
+-------+
| score |
+-------+
| 28.40 |
+-------+
1 row in set (0.01 sec)
5. decimal类型
语法:
decimal[(m, d)] [unsigned]:定点数m指定长度,d表示小数点的位数。
用法:
用法上decimal与float别无二致。
- decimal(5,2) 表示的范围是 -999.99 ~ 999.99
- ecimal(5,2) unsigned 表示的范围 0 ~ 999.99
float 和 decimal的区别
float和decimal的区别在于二者表示的精度不一样:
- float表示的精度m大约是7位。
- decimal表示的最大精度位数m为65。支持小数最大位数d是30。如果d被省略,默认为0;如果m被省略,默认是10。

使用场景:如果希望小数的精度高,推荐使用decimal。
二. 字符串类型
1. char类型
语法:
char(len): 固定长度字符串,len是可以存储的字符长度,最大值可为255。
说明:
1、定义char类型字段时,最大长度不能超过255,否则会报错:
mysql> create table if not exists t1(
-> name char(256));
ERROR 1074 (42000): Column length too big for column 'name' (max = 255); use BLOB or TEXT instead
2、固定长度的字符串,其长度本身也是一种约束:
mysql> create table if not exists t1(
-> name char(2));// name字段限定存储两个自存
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t1 values ('a');// 插入成功
Query OK, 1 row affected (0.00 sec)
mysql> insert into t1 values ('ab');// 插入成功
Query OK, 1 row affected (0.00 sec)
mysql> insert into t1 values ('abc');// 插入失败,超过了name字段限定的长度
ERROR 1406 (22001): Data too long for column 'name' at row 1
mysql> select * from t1;
+------+
| name |
+------+
| a |
| ab |
+------+
2 rows in set (0.00 sec)
mysql>
3、MySQL中的字符指的是:一个普通的字母、一个符号或一个汉字,这些字符不一定非得是1个字节,也可能是2字节或3字节,具体多大与字符集的种类有关,即MySQL限定“字符”的概念不是字节大小,这有一个非常大的好处,就是不需要让用户再关心复杂的编码的细节了。最后注意区别C/C++中的char类型,在哪里一个字符的大小是固定的一个字节。
mysql> create table if not exists t2(
-> name char(2));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into t2 values ('中');// 插入成功
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2 values ('中国');// 插入成功
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2 values ('中国人');// 插入失败
ERROR 1406 (22001): Data too long for column 'name' at row 1
mysql> select * from t2;
+--------+
| name |
+--------+
| 中 |
| 中国 |
+--------+
2 rows in set (0.00 sec)
mysql>
4、在MySQL中,char(len)类型也叫作固定长度字符串,这里的“定长”指的是直接分配给你长度为len字符空间,实际你要使用多少字符那是你的事,至于一个字符是多少字节与字符集种类有关。
2. varchar类型
varchar(len):可变长度字符串,len表示字符长度,最大长度65535个字节,最大字符个数由字符集种类决定。
varchar能存储的最大字符个数
- varchar能存储的字节大小范围是[0, 65535],但其中得有1 - 3个字节用于记录数据大小,所以说最少有效字节数个是65532。
1、当我们表的字符集编码是utf8时,varchar(n)的参数n最大值是65533/3=21844(因为utf8中,一个字符占用3个字节,需要2个字节来记录字符个数):
2、如果字符集编码是gbk的话,varchar(n)的参数n最大是65533/2=32766(因为gbk中,一个字符占用2字节,需要2个字节来记录字符个数):
char和varchar比较
- 相同点:二者最大存储的字符长度不能超过定义时给定的值len。
- 不同点:
- varchar(len)按实际存储的字符个数以及字符集种类分配内存空间。
- char(len)按len的大小以及字符集种类分配内存空间。

如何选择定长或变长字符串?
- 如果字段确定好了固定的长度,就使用定长(char),比如:身份证号,手机号。
- 如果字段的长度有变化,就使用变长(varchar),,比如:名字,地址,但是你要保证最长的能存的进去。
- 定长字符串的磁盘空间比较浪费,但是效率高。因为直接按照len字符长度的大小读取内存空间就行。
- 变长的磁盘空间比较节省,但是效率低。因为读取之前要事先确定好有效字符长度。
- 定长的意义是,直接开辟好对应的内存空间。
- 变长的意义是,在不超过自定义范围的情况下,用多少,开辟多少。
三. 时间日期类型
常用的日期有如下三个:
date:格式 ‘yyyy-mm-dd’ 。仅表示日期,占用三字节。datetime:格式 ‘yyyy-mm-dd HH:ii:ss’ 。表示日期时间,占用八字节。timestamp:表示时间戳,该字段不需要手动添加,MySQL会自动补上当前的日期时间且表中该条数据的其他字段内容改变时,这个时间戳也会自动更新。
举例:
// 1、创建一张表示生日信息的表
mysql> create table if not exists birthday(
-> t1 date,
-> t2 datetime,
-> t3 timestamp);
Query OK, 0 rows affected (0.03 sec)
// 2、向表中插入一条数据(时间戳那个字段使用timestamp类型提供的默认值)
mysql> insert into birthday (t1, t2) values ('2001-07-29', '2001-07-29 00:00:00');
Query OK, 1 row affected (0.00 sec)
// 3、显示前面插入的那条数据
mysql> select * from birthday;
+------------+---------------------+---------------------+
| t1 | t2 | t3 |
+------------+---------------------+---------------------+
| 2001-07-29 | 2001-07-29 00:00:00 | 2022-05-28 13:05:11 |
+------------+---------------------+---------------------+
1 row in set (0.00 sec)
// 4、更改数据信息,发现时间戳的值自动更新了
mysql> update birthday set t1='1999-07-29';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from birthday;
+------------+---------------------+---------------------+
| t1 | t2 | t3 |
+------------+---------------------+---------------------+
| 1999-07-29 | 2001-07-29 00:00:00 | 2022-05-28 13:08:45 |
+------------+---------------------+---------------------+
1 row in set (0.00 sec)
四. enum和set
枚举:
enum:枚举,“单选”类型。该设定只是提供了若干个选项的值,最终一个单元格中实际只存储了其中一个值;而且出于效率考虑,这些值实际存储的是“数字”,因为这些选项的每个选项值依次对应如下数字:1,2,3,…最多65535个;当我们添加枚举值时,也可以用数字编号代替。
枚举语法:enum(‘选项1’, ‘选项2’, ‘选项3’,…);
集合:
set:集合,“多选”类型。该设定只是提供了若干个选项的值,最终一个单元格中可存储其中任意多个值;而且出于效率考虑,这些值实际存储的仍是“数字”;最后这些选项的每个选项值依次对应如下数字:1,2,4,8,16,32,… 最多64个。
集合语法:set(‘选项值1’, ‘选项值2’, ‘选项值3’, …);
PS:注意在插入set类型的字段时,把需要的每一个选项写到一个共同的分号中用逗号隔开,且逗号后面不能有空格。
举例:
- 如果你给出了enum的范围,那在插入时只能多选一,且插入的字段必须在enum中出现。
- 如果你限定了set的范围,那么可以多选多(一),同样插入的字段必须在set中出现。
PS:如果不满足上述要求,MySQL会直接终止你的sql语句,这也是一种约束的体现。
mysql> create table if not exists Hero(
-> name varchar(4),
-> gender enum('男', '女'),
-> property set('战士', '法师', '坦克', '刺客', '射手', '辅助'));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into Hero values ('赵云', '男', '战士,刺客');
Query OK, 1 row affected (0.01 sec)
mysql> insert into Hero values ('钟馗', '男', '辅助,法师');
Query OK, 1 row affected (0.00 sec)
mysql> select * from Hero;
+--------+--------+---------------+
| name | gender | property |
+--------+--------+---------------+
| 赵云 | 男 | 战士,刺客 |
| 钟馗 | 男 | 法师,辅助 |
+--------+--------+---------------+
2 rows in set (0.00 sec)
关于插入数据的一些说明
1、在向enum中插入的时候,我们可以采用数字的方案:1,2,3,4…,这些数字可以看做选项的下标,这些下标对应的的内容就是enum中一个一个枚举出来的元素。

2、使用数字的方案向set类型的字段中插入元素时,这时数字不代表元素下标,而可以看做一个位段。

总结:不推荐在添加枚举值,集合值的时候采用数字的方式,因为这样会导致sql语句的可读性差,从而也不好对其进行维护工作。
查询包含某个集合元素的数据的方法
1、广泛查询
这里需要介绍一下查询相关的find_in_set函数。
find_in_set(sub, str_list):如果 sub 在 str_list 中,则返回下标;如果不在,返回0;其中str_list 是用逗号分隔的字符串:
mysql> select find_in_set('a', 'a,b,c');
+---------------------------+
| find_in_set('a', 'a,b,c') |
+---------------------------+
| 1 |
+---------------------------+
1 row in set (0.00 sec)
mysql> select find_in_set('c', 'a,b,c');
+---------------------------+
| find_in_set('c', 'a,b,c') |
+---------------------------+
| 3 |
+---------------------------+
1 row in set (0.00 sec)
mysql> select find_in_set('d', 'a,b,c');
+---------------------------+
| find_in_set('d', 'a,b,c') |
+---------------------------+
| 0 |
+---------------------------+
1 row in set (0.00 sec)
查询Hero表中,属性包含“辅助”的英雄:
2、严格查询:select * from 表名 where 集合字段='需要查询的选项';

边栏推荐
- Leetcode advanced road - 169 Most elements
- SoC development environment and hardware development preparation
- Exec function of PHP
- [nk] Niuke monthly competition 51 f-average question
- AI blessing real-time interaction | analysis of zegoavatar facial expression following technology
- C language ---6 first knowledge of selection statement, loop statement, function and array
- Intelligent robot making progress in imitation learning
- 解读创客空间下的教育新生态
- MySQL数据库如何查看表占用空间大小
- 2021年平均工资出炉,IT行业不出所料
猜你喜欢

Quick start to VISSIM simulation

Abbexa 8-OHdG CLIA kit solution

你的公司会选择开发数据中台吗?

Practical | how to use burp suite for password blasting!

Which city should I go to after I graduate from it? Which position has a high salary? Which companies have good treatment?

Qingniao Changping campus of Peking University: can I learn UI with a high school degree?

Understanding of related concepts of target detection

If else is too easy to use? (understanding this article will further improve your logic)

C language -- 8 familiar keywords

Abbexa AML1 DNA binding ELISA Kit instructions
随机推荐
MySQL inserts query results into other tables
Record today's MySQL failures
Qingniao Changping campus of Peking University: can I learn UI with a high school degree?
Anti shake and throttling
旋转菜单3.0
Quick start to VISSIM simulation
Rotate navigation bar
MySQL数据库如何查看表占用空间大小
Explain in detail the arithmetic operators related to matrix operation in MATLAB (addition, subtraction, multiplication, division, point multiplication, point division, power)
[nk] Niuke monthly race 51g calculation problem
Leetcode advanced path - the first unique character in a string
ThinkPHP v6.0. X deserialization vulnerability recurrence
在模仿学习中进步的智能机器人
Redis cache penetration
Summary of common mysql8 commands in centos7 environment
Leetcode advanced road - 167 Sum of two numbers II - input ordered array
初中毕业生,选择中职学校也可以升入高等学府
Tableau auto - fabriqué
Can I make up the exam if I fail the soft exam? Here comes the answer
目标检测相关概念的理解