您的位置:首页 > 科技 > IT业 > 站长之家产品介绍_施工企业的内容_seo教程免费_竞价托管推广公司

站长之家产品介绍_施工企业的内容_seo教程免费_竞价托管推广公司

2025/4/28 16:10:11 来源:https://blog.csdn.net/ZZY5707/article/details/147460529  浏览:    关键词:站长之家产品介绍_施工企业的内容_seo教程免费_竞价托管推广公司
站长之家产品介绍_施工企业的内容_seo教程免费_竞价托管推广公司

数据类型分类

在这里插入图片描述

数值类型

在这里插入图片描述
在MySQL中, 整型可以指定是有符号的和无符号的, 默认是有符号的. 可以通过 UNSIGNED 来说明某个字段是无符号的.

tinyint类型

以tinyint为例, 其它的整型类型都只是数据范围的区别.

数据越界

创建一个 tinyint 类型的 num 的属性, 大小为 1 字节, 不加 unsigned 修饰的话范围是[-128,127], 可以发现插入范围之外的值会越界报错:
在这里插入图片描述
插入后的结果:
在这里插入图片描述
给表添加一列 tinyint unsigned 类型的属性num2, 同样会有越界的问题, 此时的数据范围是[0, 255]:
在这里插入图片描述
所以说明向mysql中的特定类型插入不合法数据, MySQL一般会直接拦截我们(报错), 而并不像C语言, 会去做截断. 换句话说, 已经插入到表中的数据一定是合法的.
因此在mysql中, 一般而言数据类型本身也是一种约束, 倒逼程序员尽可能正确的插入.

注意:尽量不使用unsigned, 对于int类型可能存放不下的数据, int unsigned同样可能存放不下, 与其如此, 还不如设计时, 将int类型提升为 bigint 类型. 但是也不绝对, 这要取决于场景, 有些场景下取值不可能为负数, 也应该用unsigned.

bit类型

bit[(M)] : 位字段类型. M 表示每个值的位数, 范围从1 到 64. 如果 M 被忽略, 默认为 1.
现在创建一个 bit 类型的 gender 属性: 0 为 女, 1 为男
在这里插入图片描述
超出数据类型的范围依然会报错, 下面的例子因为bit(1)只能表示0,1, 插入2越界:
在这里插入图片描述
再创建一个 8 位的 bit 类型数据flag:
在这里插入图片描述
可以直接插入十进制整数, 也可以通过b’1001’的形式插入二进制, 最终select 在MySQL 8.0 中默认对于bit类型的数据是按照十六进制显示的, 而在MYSQL 5.5 中默认是 assic码 的形式显示.
在这里插入图片描述
还可以有多种格式去显示:
在这里插入图片描述

在这里插入图片描述

浮点类型

float

语法: float[(m, d)] [unsigned] : M指定显示长度, d指定小数位数, 占用空间4个字节.

(m,d)精度是可选的, 如果直接写一个 float, 精度大约7位.

有符号float

举个例子, 小数: float(4,2) 表示的范围是 [-99.99 ~ 99.99], MySQL在保存值时会进行四舍五入

现在创建一个 float(4,2) 属性的 num 列:

create table t6 ( id int, num float(4,2) );

向表中插入一些正常的数据, 注意其中 10.0 会自动精确到 10.00:
在这里插入图片描述
再插入一些非法的数据, 不满足float(4,2):
在这里插入图片描述
再插入几个形如 float(5,3) 的数据, 为什么插入成功了? 而且最终都被存为 99.99?
因为浮点数存储时, 如果精度并不严格满足定义, 但四舍五入之后数值范围仍在规定的范围内(本例为[-99.99, 99.99]), 则MYSQL会放宽约束条件.
在这里插入图片描述

无符号float

如果定义的是 float(4,2) unsigned 这时,因为把它指定为无符号的数,范围是 0 ~ 99.99. 因此无符号浮点数的取值范围很简单粗暴, 就是把有符号浮点数的负数范围去掉.

double

double 和 float用法类似, 主要是精度的区别, 默认大约是15~16位.

decimal

主要来看一下decimal类型, 由于 float, double 浮点数使用的是 二进制科学记数法, 也就是数字在内部会被转化成 1.xxxxx × 2^y 的形式. 所以有些十进制数在转换为二进制时会发生舍入误差, 特别是对于无法精确表示的数字, 如 0.1 .
而 DECIMAL 类型则使用 十进制数表示法, 它以精确的十进制数进行存储和运算, 不会有类似浮点数的二进制精度问题.

语法: decimal(m, d) [unsigned] : 定点数m指定长度,d表示小数点的位数, 可以看出它的用法和float基本一样.
现在插入两个相同的数据 12.12345678, 发现 float 最终的结果并不准确, 而 decimal 则一位不差:
在这里插入图片描述
float/double VS decimal 应用场景:

  • 浮点数(FLOAT / DOUBLE):
    浮点数适合进行科学计算、物理模拟、图形处理等领域, 这些领域可以容忍一定程度的误差. 而在数值要求非常精确的领域, 浮点数不适用.

  • DECIMAL:
    DECIMAL 类型适合用于需要精确表示和计算的小数的场合, 例如金融计算, 货币运算, 税务计算等. 这些应用对误差非常敏感, 要求精确到每一位.

字符串类型

char

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

MYSQL 中的字符和 C/C++等语言中的字符概念不同, 语言中我们认为一个字符为一个字节, 而MYSQL中字符是一种符号, 无论是 “ABC” 中的单个字母, 还是 “你好” 中的单个汉字, 我们都认为是一个字符, 即使底层存储需要的字节数不同.

create table t9 ( id int, name char(2), address varchar(10) );

现在往表中插入一条数据, name赋值为张三, 由于utfmb4一个字符为4字节, 这里虽然是char(2), 但是可以存下 8 字节的张三, 因为SQL中字符是指 “一个字符” :
在这里插入图片描述
如果要存储超过 256 字节的大文本就不要用char, 用BLOB或者TEXT:
在这里插入图片描述

varchar

varchar能实现变长存储的核心在于其结构是: [实际长度字节] + [实际字符串内容], 有点类似C++的 string, 其由char* str, size 和 capacity 去维护, varchar中的实际字符串内容类比char* str, varchar的长度前缀类比 size, varchar(len)的 len 类比capacity.

关于varchar(len),len到底是多大, 这个len值, 和表的编码密切相关:

  • varchar长度可以指定为 0 到 65535 之间的值, 但是有1 - 3 个字节用于记录数据大小, 所以说有效字节数是 65532 - 65534. 比如varchar(256), 那么就只需要1字节去记录大小即可.
  • 当我们的表的编码是utf8mb4时, varchar(n) 的参数 n 最大值是 65532/4=16383 [因为utf中, 一个字符占用3个字节], 如果编码是gbk, varchar(n)的参数n最大是65532/2=32766 (因为gbk中,一个字符占用2字节)
  • 注意 65535 是 MySQL 单行的 65535 字节限制, 这意味着表只有 varchar 一个元素时, 其参数 n 的最大值是 65532/3=21844, 但是如果有多个其他属性, 是所有列加起来 (包括 INT, VARCHAR等, 不包括BLOB 和 TEXT) 所占的实际存储空间, 不能超过 65535 字节, 所以在表内有多个属性时, 最终的varchar(len)的len值只会更小

可以看到 MYSQL 提示我们 max=16383, 而16383*4=65532 = 65535 - 3
在这里插入图片描述
可以看到现在添加一个int属性的id, varchar的参数只能更小:
在这里插入图片描述

char与varchar对比:
在这里插入图片描述

如何选择定长或变长字符串?

  • 如果数据确定长度都一样, 就使用定长(char), 比如: 身份证, 手机号, md5
  • 如果数据长度有变化,就使用变长(varchar),比如: 名字, 地址, 但是你要保证最长的能存的进去
  • 定长的磁盘空间比较浪费, 但是效率高; 变长的磁盘空间比较节省, 但是效率低. 定长的意义是, 直接开辟好对应的空间 变长的意义是, 在不超过自定义范围的情况下, 用多少, 开辟多少

日期和时间类型

常见的日期类型:

  • 日期 = 年月日, date : yyyy-mm-dd , 占用三字节
  • 日期时间 = 年月日时分秒, datetime: yyyy-mm-dd HH:ii:ss 表示范围从 1000 到 9999 , 占用八字节. (可以用户自定义)
  • 时间戳, 从1970年开始的. timestamp: yyyy-mm-dd HH:ii:ss 格式和 datetime 完全一致, 占用四字节

日期和时间戳的区别是:

  1. 时间戳会随时间变化, 而 datatime 则是固定的.
  2. 在MYSQL 5.x 中, 当向表插入(insert)数据时, 不需要去关心 timestamp 类型的数据, 它会自动被插入, 而datetime 需要手动插入. 在更新(update)数据时, 不需要去关心 timestamp 数据, 它会自动更新, 而datetime需要手动更新…; 在MYSQL 8.0 中, 需要在 timestamp 类型后添加 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 去保证默认插入和自动更新, 否则也必须自己手动插入.

举个例子, 现在有 t1 date, t2 datetime, t3 timestamp 三个数据, timestamp 类型没有约束条件, 因此没有被默认插入:
在这里插入图片描述
通过show create table t10 也可以验证, timestamp默认是NULL:
在这里插入图片描述
现在我们加上 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 约束条件:
在这里插入图片描述
在这里插入图片描述
现在更新一下 t11 表, 发现 t3 自动更新为当前的时间戳:
在这里插入图片描述

enum和set

  • enum: 枚举, “单选”类型;
    enum(‘选项1’,‘选项2’,‘选项3’,…);
    该设定只是提供了若干个选项的值, 最终一个单元格中, 实际只存储了其中一个值;而且出于效率考虑, 这些值实际存储的是“数字”, 因为这些选项的每个选项值依次对应如下数字: 1,2,3,…最多65535个; 当我们添加枚举值时, 也可以添加对应的数字编号.
  • set: 集合, “多选”类型
    set(‘选项值1’,‘选项值2’,‘选项值3’, …);
    该设定只是提供了若干个选项的值, 最终一个单元格中, 实际可存储了其中任意多个值; 而且出于效率考虑, 这些值实际存储的是“数字”, 因为这些选项的每个选项值依次对应如下数字: 1,2,4,8,16,32,…最多64个.

先创建一个 votes 表, set类型表示hobby, enum类型表示gender:

create table votes(-> username varchar(30),-> hobby set('登山','游泳','篮球','足球','武术'),-> gender enum('男','女')-> );

然后用不同的几种风格向表中插入数据:

insert into votes values('张三', '登山', '男');
insert into votes values('李四', '游泳', 2);
insert into votes values('王五', '游泳, 篮球, 足球', 1);
insert into votes values('赵六', 23, 1);

第一行就正常输入字符串插入, 很容易理解;
第二行的枚举类型我们使用了下标去插入, 因为 enum 实际存储的就是从1开始的数字;
第三行演示了如何正常地插入 set 类型的数据, 在一对单引号内部以逗号分隔开选项即可, 然后也改变了enum的插入风格;
第四行我们主要改变了set的插入风格, 23 的二进制是10111, 但是SET 类型中的 第一个元素是最低位, 因此要反过来去解释:
在这里插入图片描述

结论:

  • 对于枚举类型, 在插入时既可以用定义时的枚举选项常量, 也可以用从 1 开始的下标:
  • 对于集合类型, 在插入时既可以用定义时的集合选项常量, 也可以用一个被看作位图的整型.
enum 和 set 的查询

集合查询使用 find_ in_ set 函数:
find_in_set(sub,str_list) : 如果 sub 在 str_list 中, 则返回下标; 如果不在, 返回0; str_list 用逗号分隔的字符串

在这里插入图片描述
查找喜欢游泳和篮球的男生, 第一种写法比较容易理解, 用and连接多个条件即可, 但是比较长; 我们可以利用set的位运算, 由于’篮球,游泳’的二进制是 110, 因此我们可以用 hobby & 6 = 6去表示:

select * from votes where gender='男' and find_in_set('游泳',hobby) 
and find_in_set('篮球',hobby);select * from votes where gender='男' and hobby & 6 = 6;

在这里插入图片描述
如果想找出只喜欢登山的人, 而不是喜欢登山, 那么用 hobby=1 或者 hobby=‘登山’ 去比较:
在这里插入图片描述

总结: 数据类型天然是一种约束, 如果不满足约束条件不允许被插入, 除了 float 可以宽松一点采用四舍五入.

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com