数据库数据类型介绍,整数(有无符号),严格模式,bool类型本质,位类型(无法回显+解决方法),浮点数类型(有无符号,精度损失),字符串类型(定长和变长),日期时间类型(时间戳),集合类型(模糊查找)

目录

介绍

约束

整数类型​编辑

示例

有符号整数

括号的意义

插入超范围数据

无符号整数

括号

插入超范围数据

设置严格模式

引入

解决

示例

不同范围的用途

布尔类型(bool)

本质

位类型

bit(n)

n的含义

示例

无法回显 

ASCII码形式

解决方法

hex(属性列)

bin(属性列)

conv(属性列,原进制,转换后的进制)

浮点数类型

float(m,d) (unsigned)

m的含义

d的含义

小数部分

超出d

 不足d

整数部分

有无符号

默认下

无符号时

double(m,d) (unsigned)

和float的区别

精度损失

引入

示例 

原因 

decimal(m,d) (unsigned)

优势 -- 没有精度损失

示例

字符串类型

char(L)

L的含义

字符的含义

示例 

超出范围

定长字符串

varchar(L)

变长字符串

示例

两者关联 

最大存放空间 

示例

日期和时间类型

date

示例

datetime

timestamp

示例 -- 修改设置

枚举和集合类型 

enum('xx'...)

介绍

插入

查找

set('xx'...)

插入

数字的含义

空串和null的区别

查找 -- 模糊查找

示例 -- 单个

示例 -- 多个


介绍

  • mysql中,可以在表中定义不同的列字段,用于表示表的属性
  • 每个列都有一个数据类型,它决定了该列可以存储的数据种类和在数据库中的存储方式

约束

  • 每个类型都有自己的范围
  • mysql规定插入数据时不能超范围 -- 这属于一种约束

  • mysql约束了程序员的不合规行为,那么,数据库中存放的数据就都是合法的


整数类型

示例

有符号整数

我们这里用tinyint作为示例,有符号tinyiint的范围是-127~128

括号的意义

注意,这里类型后面的括号里是4,这是什么意思呢?

  • 实际上表示的是它的显示宽度
  • 因为它的最大值和最小值都是3位数,并且有可能为负数,所以宽度是1(负号)+3(三位数)=4
插入超范围数据

可以看到,127和-128都成功插入,但128和-129都有警告

但可以成功插入,并且插入后的值是范围临界值:

无符号整数

括号

注意新创建的属性列num_u,它的长度是3,因为无符号类型不会是负数,所以长度比有符号的-1

插入超范围数据

无符号tinyint的范围是0~255

所以,当我们插入256时会出现警告,但仍可以插入,且插入数值为范围边界值:

设置严格模式

引入

上面两种类型超出范围后,都是使用范围边界值继续进行插入(也就是将插入的数值截断了)

但如果我们不想这样,而是让他直接报错呢?

解决
  • 当前mysql中直接设置 SET sql_mode='STRICT_TRANS_TABLES'; (重新登录后失效)
  • 可以修改my.cnf配置文件,添加 sql_mode=STRICT_ALL_TABLES
  • (但不知道为什么,我修改了好多好多次配置文件,试了好几种格式,都没生效,查的方法写的格式各不相同,尊嘟很崩溃,但是set的方式确实可行(赞),大不了以后如果需要操作数据,记得加设置也行(瘫倒))
示例

当我们设置好严格模式后,插入超范围数据,就会直接报错且不进行插入操作:

可以用select查看此时的sql_mode设置

不同范围的用途

设定多种不同范围的类型,是为了减少资源浪费

  • 假设某个变量不会超过1bit,但你为他申请了8bit,那么每有一个数据就会浪费7bit,数据量越大,资源浪费越多
  • 不同范围的int同理,如果这个变量最大值不会超过100,就没有必要为他提供更大的空间,tinyint足以

布尔类型(bool)

本质

  • 从图中可以看到,虽然我们设置了bool类型,但在查看属性的时候,显示的却是tinyint(1)
  • 所以,其本质就是tinyint,只不过长度是1(所以,虽然他可以插入0和1以外的一位数字,但我们一般不这么使用)

位类型

bit(n)

n的含义

  • n代表有n位bit
  • n的范围 : 1~64
  • 如果不输入n,则默认为1
  • 该属性列插入的数值不能超过n位bit可以表示大小的范围(也就是2^n-1)
示例

我们设置了2位bit大小的address,所以它表示的范围为0~3

所以插入4时会报错:

无法回显 

ASCII码形式

select查看时,不能回显,因为它以ASCII码的形式显示

  • 我们可以先试着插入97(我们都知道它代表的是字母a):
  • 查询ASCII码表后,我们会发现,先前插入的是0,1,3,这三个数字代表的ascii码都不是可以回显的字符
  • 从32开始,才是可以看到的
  • 比如我们插入32,会看到,他比插入无法回显的字符多了一个格,那个格就是空格字符
解决方法
hex(属性列)

返回二进制数据的十六进制表示

bin(属性列)

将二进制数值转换为二进制字符串

conv(属性列,原进制,转换后的进制)

指定进制转换

浮点数类型

float(m,d) (unsigned)

m的含义

表示显示长度(是整个数字的长度)

  • eg:25.1的显示长度为3

d的含义

表示小数位数

  • eg:25.1的小数长度为1

下面使用(4,2)作为例子:

小数部分

超出d

遵循四舍五入(在边界值内)

 不足d

会用0填充

整数部分

不可以超出m-d

  • 四舍五入导致整数部分超过(m-d)也不行:

有无符号

默认下

默认情况下是有符号

  • 所以,上面的(4,2)可以表示的范围就是 -99.99 ~ 99.99:
无符号时

只允许插入0和正数 

  • eg:float(4,2) -- 0 ~ 99.99

double(m,d) (unsigned)

用法和float一样

和float的区别

实际上,区别只在于占据的空间不同

  • float占用4字节
  • double占用8字节(可以表示更大的精度)

精度损失

引入

我们新创建两个使用默认范围的float和double类型的属性:

使用默认范围时: 整数和小数均有精度损失

因为float和double类型存储时,都需要转为二进制(也就是标准格式)

示例 

当我们插入整数和小数部分均很大的数字时

  • 会发现float只有整数部分,double的存储情况良好

当插入只有小数部分大的数据:

  • 整数部分均正确,但float仅存了3位小数,double存放良好

小数部分更大时:

  • 会发现double的最后一位小数存储错误

原因 

以上就是float和double存在精度损失的示例

究其根本,是因为这两种类型都是以IEEE标准格式存放的:

  • 需要进行十进制->二进制的转换,但是小数部分的转换是每次*2取整,不是每个数字的转换都会刚刚好,所以必然会存在精度损失

decimal(m,d) (unsigned)

优势 -- 没有精度损失

它的用法和前两种类型是相同的,但是,他有一个独特的优势 -- 没有精度损失 

  • 为相同范围的float和decimal插入同样的数据
  • 一旦数字长度较长,float因为一些原因,会产生精度损失,导致数据数值变化(double也同理)
  • 而decimal并不会

示例

创建相同范围的float和decimal属性列:

插入相同的数据,会发现float类型的后两位小数不正确,而decimal类型的数据完全相同:

字符串类型

char(L)

L的含义

L为该字符串的最大字符数

最大为255

字符的含义

  • 之前认识的字符 -- 一个字节
  • mysql中的字符 -- 一个符号(无论是字母/数字/中文字符,都属于一个字符),所以,一个字符的大小被设置为3个字节(为了可以容纳最大的字符)

示例 

插入数值:

插入字母和中文:

超出范围

如果不是严格模式:

它会自动截断,插入内容的长度为L

严格模式下:

​​​​​​​​​​​​​​

定长字符串

无论你使用了多少空间,都会直接开辟3*L个字节的空间,来完整容纳L个字符

 

varchar(L)

用法和char类似,唯一不同的就是verchar是变长字符串

变长字符串

  • 也就是说,你插入了几个字符,就开辟几个字符的空间
  • 最大空间为65535个字节(具体对应的符号数,取决于此时的编码格式,编码格式决定了一个字符=多少个字节)

  • 为了知道此时的字符数,需要1-3个字节来存放字符数,所以有效字节数为65532
  • (1-3个字节的范围,是按照数据量的大小,来确定实际用几个字节来存储的)
示例
  • 当我们的表的编码是 utf8 时, varchar(n) 的参数 n 最大值是65532/3=21844(因为 utf 中,一个字符占用3 个字节)
  • 如果编码是 gbk varchar(n) 的参数 n 最大是 65532/2=32766 (因为 gbk 中,一个字符占用2 字节)

两者关联 

char和varchar类似于char数组和string的关系

那么定长和变长也就不难理解了

最大存放空间 

除了由自身决定(char和varchar表示的范围不同),也由其他属性列的大小决定

示例

当我们已经存在其他属性列时,再使用varchar类型,就不能开辟其理论上的最大值了:

因为mysql是按照行存储的

日期和时间类型

date

可以存储日期

数据格式为'yyyy-mm-dd' ,占用3字节

示例

插入数据时,如果不足指定位数,由0填充:

datetime

可以存储日期和时间

格式为 'yyyy-mm-dd HH:ii:ss' ,占用八字节

timestamp

时间戳,格式和 datetime 一致,占用四字节

它会自动更新(在插入数据/更新其他数据时,自动更新),不需要自行插入

可以记录该行数据上次添加/修改的时间

示例 -- 修改设置

如果没有自动更新的话,需要修改一下timestamp类型的设置:

​​​​​​​

alter table t_test modify ts timestamp default current_timestamp on update current_timestamp;

修改完后,插入某个数据,时间戳会自动更新其数据:

枚举和集合类型 

enum('xx'...)

介绍

它允许你在列中定义一个有限的可能值集合,列中的值必须是预定义的枚举值之一
  • 需要在创建该列时,就给出包含的选项 格式('xx','xx' ...)
  • 虽然提供了若干个选项,但最终在一个单元格中只存储其中一个值(也就是说,只能单选)

插入

可以直接插入之前提供的选项:

也可以插入限定的常量/常量代表的下标(从1开始):

查找

如果我们想要查找所有选择了某个选项的数据:

select * form 表名 + where 列名='xx' / 下标

 

set('xx'...)

和enum基本一样,唯一区别就是,set可以允许一个实体具有多个属性(也就是可以多选)

插入

我们这里设置了三个选项:

插入数据时,将多个数据以,分隔 -- 'xx,yy,zz':

也可以插入数字,但这里数字表示的含义和enum中的并不相同

数字的含义

如果有3个常量,就对应3个bit位

eg:

插入0:000 (插入的是空串):

空串和null的区别
  • 注意,空串和null本质上是不一样的,mysql看见两者的也是不一样的
  • 空串是有内容,但内容为空
  • null是内容不存在

插入3(011):

插入4(100):

插入7(111):

  • 这样就是将选项全部插入了

查找 -- 模糊查找

可以采用enum中的形式,但那样是精准查询:

如果我们想要模糊查询呢?

find_in_set(元素,集合)

  • 这个函数可以查询某一个元素是否在集合中
  • 只要存在,就返回真
  • 所以我们需要模糊查询表中元素的时候:
  • select * form 表名 + where find_in_set(值,列名)
  • where类似于条件判断if
示例 -- 单个

可以看到,这样查询出来的结果,就是找到所有包含'看漫画'的数据:

如果想要查找同时包含多个值呢?

select * form 表名 + where find_in_set(值1,列名) and find_in_set(值2,列名)

and类似于c语法中的&&

示例 -- 多个

  • 25
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值