MySQL的数据类型

目录

数据类型分类

数值类型

tinyint

bit

[​编辑 小数(float)](#编辑 小数(float))

小数(decimal)

字符串类型

char

varchar

日期和时间类型

String类型

enum

set

[find_ in_ set函数](#find_ in_ set函数)


我们今天来学习MySQL的数据分类。

数据类型分类

MySQL的字符型就是相当于字符串类型,所以MySQL没有字符这种说法,这个是和其他语言不一样的地方,单引号和双引号引起来的都是字符串。

数值类型

MySQL数值类型中整型的取值范围和C语言中的是一样的。我们接着只选择一些有代表性的类型进行讲解。

tinyint

我们可以称tinyint为微整型,从上表来看这个是整型里面最小的。单写tinyint的范围是-128~127,表示有符号微整型的范围,tinyint unsigned是无符号微整型,范围是0~255。

创建一个counter表,内列字段只有一个num,且类型为tinyint。

复制代码
insert into counter values(-128);
insert into counter values(127);
insert into counter values(1);
insert into counter values(0);

我们依次插入了几个数,当我们插入的数据不合法时,MySQL会进行拦截,也就是说MySQL中的数据都是合理合法的,这样确保了数据是可预期的,完整的。所以MySQL中,一般而言数据类型本身也是一种约束。

无符号的tinyint unsigned这里就不试了。尽量不使用unsigned,比如对于int类型可能存放不下的数据,int unsigned同样可能存放不 下,与其如此,还不如设计时,将int类型提升为bigint类型。

bit

bit(M) : 位字段类型。M表示每个值的位数,范围从1到64。如果M被忽略,默认为1。

bit是一种为字段类型,(M)内表示bit能存储的值所需的可能最大位数。如果存储的最大位数不满M位就会在前面补0以达到M位。对于整型直接转换成二进制进行填充判断,对于字符串先转换成对应的ASCll码然后再转换成二进制进行填充判断。

重新创建counter表

由于1和0的二进制表示为1/0,只占1位,刚好我们的bit也就一位,所以可以存下而不会发生数据偏差。

由于10的二进制编码的1010,所以不够8位,所以在前面补4个0。

有不少人认为bit在存储的时候是采用的截断式存储的,而不是补0式存储,这个判断是错的,因为如果bit最大存储是8位,那如果是截断式的存储,那无论如何300都是可以存下的,只是有效数字部分被截断了,但是如下报错显示300的二进制太长了导致存不下,由于300的二进制长度大于8,所以MySQL为了使数据精确就不让其存储。说明bit只能存下二进制位数小于等于M的数字,以及翻译成ASCll码后再转换成二进制位数小于等于M的任何字符串。

最后,如果我们有这样的值,只存放0或1,这时可以定义bit(1),这样可以节省空间。如果字符串内部字符个数大于1的化(C语言认定的字符串格式)我们就不使用bit类型进行接收了,这是转化的ASCll码很大的,大概率存不下,使用varchar/char这种字符串型才是正解,而不是在这里没苦硬吃!!!

hex(字符/数字); //将字符串或数字转换为十六进制表示

小数(float)

float(m, d) [unsigned] : m表示指定显示的总长度(不包括小数点),d表示指定小数位数,占用空间4个字节

小数:float(4,2)表示的范围是-99.99 ~ 99.99,MySQL在保存值时会进行四舍五入。这个m的最大值是7。

cpp 复制代码
create table counter(
	num float(4, 2)
);

重新创建counter表。

可以看到,当插入的数据的长度小于等于m时是可以插入的,当小数位的长度小于d时会在后面自动补0以达到m位。

对于插入的数据的总长度为m + 1时,float会进行适当的舍去最后一位小数位四舍五入保留。所以float类型由于四舍五入会产生精度丢失的问题。

对于float unsignal无符号小数和float的区别仅仅是去掉了负数的部分,相当于范围变小了。如果定义的是float(4,2) unsigned 这时,因为把它指定为无符号的数,范围是 0 ~ 99.99

小数(decimal)

decimal(m, d) [unsigned] : 定点数m指定长度,d表示小数点的位数

decimal(5,2) 表示的范围是 -999.99 ~ 999.99 ,decimal(5,2) unsigned 表示的范围 0 ~ 999.99 ,decimal和float很像,但是有区别,decimal的精度比float更高。 decimal的精度更准确,因此如果我们希望某 个数据表示高精度,选择decimal。

decimal整数最大位数m为65。支持小数最大位数d是30。如果d被省略,默认为0.如果m被省略, 默认是10。

插入数据的规则和float一样的。修改counter表使两者长度一致

可以看到当插入数据一致时,float表示的精度大约是6位左右,选择不同的存储引擎会对float的精度有一点影响。decimal不受存储引擎的影响,属于高精度。如果希望小数的精度高,推荐使用decimal。

字符串类型

char

char(L): 固定长度字符串,L是固定存储的长度,单位为字符,最大长度值可以为255

MySQL的字符串长度是不算最后的\0的,并且L表示的是长度,无论是中文字符串还是英文字符串还是中英文混编的字符串都是一样的,L只计算字符串字符个数,中英文字符所占长度对于L来说是一致的。

所以你就可以看到当L=2时'ab','中国'都能插入,因为长度都是2。

当插入长度小于L时,可以插入,但是由于是定长字符串会在尾部添加定量的空格来保证插入的字符串长度为L,但是这些空格不会显示出来,当插入长度大于L时,不可以插入,所以是定长字符串。

varchar

varchar(L): 可变长度字符串,L表示可以存储的字符长度,最大长度65535个字节

注意这个L是字符长度,而最大长度标注的长度是字节,所以我们需要计算L的最大值。varchar长度可以指定为0到65535之间的值,但是有1 - 3 个字节用于记录数据大小,所以说有效字 节数是65532。当我们的表的编码是utf8时,varchar(n)的参数n最大值是65532/3=21844[因为utf中,一个字符占 用3个字节],如果编码是gbk,varchar(n)的参数n最大是65532/2=32766(因为gbk中,一个字符 占用2字节)。

varchar存储字符串时实际上存储的是:字符串长度+字符串内容,就是会在存储的字符串前面多开辟1-2字节的空间进行存储该字符串的长度,所以这个L是实际存储字符串的内容,varchar实际的存储长度会大于L,这个字符串长度不用管是MySQL自己加的,其他的语法和char都一样。varchar不会在字符串后面添加空格,而是显示实际长度,所以是可变字符串。

日期和时间类型

date :插入日期格式: 'yyyy-mm-dd' ,占用三字节
datetime:插入时间日期格式:'yyyy-mm-dd HH:ii:ss' 表示范围从 1000 到 9999 ,占用八字节
timestamp:时间戳,从1970年开始的 yyyy-mm-dd HH:ii:ss 格式和 datetime 完全一致,占用四字节

用到日期时间类型需要插入合理的时间。

date,datetime都是字符串,而由于timestamp是系统自增的,时间戳可以不需要手动的插入,会自己显示出当前的时间戳,在 MySQL 中,TIMESTAMP 类型存储在内部确实是整数(时间戳秒数) ,但是对外显示时是"标准日期时间格式" ,比如 2025-04-28 15:00:00。所以插入时间戳时和插入datetime是一样的,注意格式。

时间戳需要单独设置默认约束CURRENT_TIMESTAMP表示默认当前时间戳才会自动填充当前时间,这个默认会随着表的数据更新而动态改变,因为当前时间在不断改变,这个时间戳记录的是修改表的时间,插入也算一种修改。

建议验证时间戳使用Linux系统!!!

String类型

enum

enum算一种集合类型,enum:枚举,"单选"类型。

enum('选项1','选项2','选项3',...); //允许在多个选项选填一个

该设定只是提供了若干个选项的值,最终一个单元格中,实际只存储了其中一个值;而且出于效率考 虑,这些值实际存储的是"数字",因为这些选项的每个选项值依次对应如下数字:1,2,3,....最多65535 个;当我们添加枚举值时,也可以添加对应的数字编号。

可以看出这个列元素只能是enum里面的值,所以这一列的类型表项固定是字符串。

对于enum可选集合来说,插入多个值以及插入不存在于enum的值都是不行的,只能插入一个。当一个元素是多选1,非黑即白的时候的时候可以使用enum,方便观看。

可以使用下标进行元素的访问,下标从1开始依次递增指代enum开始到结尾的元素,如上面的counter表中,1指代的就是男,2就是女。0下标对应的是NULL。

set

set:集合,"多选"类型;

set('选项值1','选项值2','选项值3', ...); //允许多个中选择多个

set和enum一样都是组合类型,同样是只允许该列元素只存在于set中,这次可以选择多个连续的字符串以,连接成一字符串填入。

该设定只是提供了若干个选项的值,最终一个单元格中,设计可存储了其中任意多个值;而且出于效率 考虑,这些值实际存储的是"数字",因为这些选项的每个选项值依次对应如下数字:1,2,4,8,16,32,.... 最多64个。

同样的不允许插入不存在于set中的元素。

这里SET类型插入时,不要有空格!不然空格会被识别进下一个元素导致匹配出错。

我们也可以使用下标指代元素,0下标照样是NULL,MySQL的SET类型 没有下标访问 的操作,

这里使用下标指代的本质是一个**用逗号分隔的字符串 + 位图(bitmap)内部表示。**元素如果被选中了所对应的位就是1,像如果有如上n个元素位图结构就有n位,选中填入的元素位置就是1没有选中的就是0,然后这个下标就是这个位图二进制转化成10进制的结果,比如上面set里面有5个元素位图结构就是5位,如果我同时选了a和b那此时位图就是11000,然后根据这个位图得到a,b这种组合的下标为3,所以3在这个set里面就指代a,b。可以使用下标访问了。

find_ in_ set函数

集合查询使用find_ in_ set函数,find_in_set(sub,str_list) :如果 sub 在 str_list 中,则返回下标;如果不在,返回0; str_list 用逗号分隔的字符串。这个函数的作用可以用来做set元素的查找。

可以查询某个元素是否在选项里面的成员,利用其查到结果就返回真的特点可作为where的判断条件!!!

相关推荐
MeAT ITEM2 分钟前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
dovens6 分钟前
PostgreSQL 中进行数据导入和导出
大数据·数据库·postgresql
IOT.FIVE.NO.17 分钟前
claude code desktop cowork报错解决和记录Workspace..The isolated Linux environment ...
linux·服务器·数据库
Rick199315 分钟前
mysql 慢查询怎么快速定位
android·数据库·mysql
科技小花7 小时前
全球化深水区,数据治理成为企业出海 “核心竞争力”
大数据·数据库·人工智能·数据治理·数据中台·全球化
X56618 小时前
如何在 Laravel 中正确保存嵌套动态表单数据(主服务与子服务)
jvm·数据库·python
虹科网络安全10 小时前
艾体宝干货|数据复制详解:类型、原理与适用场景
java·开发语言·数据库
2301_7717172110 小时前
解决mysql报错:1406, Data too long for column
android·数据库·mysql
绘梨衣54710 小时前
Docker+FastAPI+MySQL 项目部署报错汇总
mysql·docker·fastapi
小江的记录本10 小时前
【Kafka核心】架构模型:Producer、Broker、Consumer、Consumer Group、Topic、Partition、Replica
java·数据库·分布式·后端·搜索引擎·架构·kafka