MySQL神功2.5 数据类型的细分之二进制类型
一、什么是母语
意思是每个人的本民族语言;婴儿期和幼年期间自然学到的语言;一个人的第一语言。
例如小学生6岁左右上一年级,但是在他们上学前,就算你什么都没有教,他们听大人说话也会学会母语的发音与人正常交流。
二、计算机的母语是二进制代码
机器语言程序是用机器指令(二进制代码表示)编写的,计算机能够直接识别和执行,所以说计算机的"母语"是二进制代码。
例如:十进制的数字105,转换成二进制数字是1101001

你可能认为,这不是把三位数变成了7位数吗?那你学英语时,keep pace with the times 翻译成中文:与时俱进 你咋不说英文变长了?
1、十进制转二进制方法
十进制数转换为二进制数时,由于整数和小数的转换方法不同,所以先将十进制数的整数部分和小数部分分别转换后,再加以合并。
(1)十进制整数转二进制
以十进制数字105为例,转二进制方法

其实就是将一个整数,一直除以2,取余数,直到商为零时结束。最后将余数从下向上顺序排列:1101001
(2)十进制小数转二进制
这次我们找个简单的,以0.25为例,转成二进制是:.01

对十进制小数连续乘以2(每次只乘以积的小数部分),取整数部分,直到积的小数部分显示零为止。最后将整数位从上向下排列。
但是,大家可能对上面蓝色字不理解,我们再举个例子:十进制小数0.3怎么转换

2、二进制转十进制方法
刚才我们知道十进制数字105的二进制数字是1101001
现在我们讲一下如何把二进制数字转成十进制数字,方法:

如果有小数部分,那就整数转整数,小数转小数。整数我们学会了,就是从左向右

那你们想过没有?为什么整数都是从右向左,而小数是从左向右。
这个问题有小学四年级的基础即可理解,此处略过。

以上知识,略懂即可,也不会让你人工去转换的。
三、BIT类型(位字段类型)
BIT(M) 存储: 约等于(M+7)/ 8 字节 存储M个二进制位的值
其中M(最大长度)的范围是1~64,当省略M时,默认为1。
这个类型我们没有必要去研究他的存储空间,因为只有需要的时候才会用。
(1)应用1:布尔类型(逻辑型)
因为MySQL中没有 BOOLEAN类型(SQL Server中有)
我们通常是使用整数类型中的 TINYINT(1) 来表示 True = 1 、False = 0
但是,你考虑过一个问题吗?使用TINYINT(1) 可以输入 0~9
我们先创建一张表

在表中输入内容,当字段【是否队员】为0时,表示非队员,否则是队员

但是我在查询的时候,会出错。因为在MySQL中
True=1,False=0
True属于非0 ,False属于0
因为您写 是否队员=TRUE 这里的TRUE是一个常量 永恒=1

解决方法,写成 is TRUE

关于为什么会这样,网上有很多专业的解释,因为我的文化程度是幼儿园毕业,所以我只能用我的语言来解释。等号后面一次只能是一个值
因为你这不是变量,也不是循环
True属于非0的值,但是 True =1 (这是概念)
当你使用 is TRUE 时,表示属于True的值,那除了0都是True
孙兴华 = 青铜圣斗士
孙兴华 = 男
孙兴华 = 孙艺航的小弟
孙兴华 is (属于)青铜圣斗士、男、孙艺航的小弟
类似的问题你以后还会遇到null,因为null不是一个值,所以不能写 孙兴华=null 要写 孙兴华 is null

那如果我们使用bit类型呢?

因为bit类型是二进制的,只能输入0或1,你输入2、3...也会被强制改回1

在查询时写成 是否团员=TRUE 就没问题了

你写成 是否团员 is TRUE 同样没有问题,是不是减少错误的发生率?

(2)应用2:做标记
我先举一个例子,北宋时期包拯在开封府判了张三,后来发现不对,但是这时只能撤销不能删除。希望你们可以明白我的意思,有些东西是不能删除的。可能你的工作中没遇到。

(3)应用3:表示状态
去年我发了一篇文章:https://www.bilibili.com/read/cv18587006
关于RFM模型分析


在我的那篇文章中,只需要考虑RFM三个状态,所以我们可以使用BIT(3)这个类型
假设你有一个项目,需要各部门审批,01101010 可以使用BIT(8) 表示8个部门,其中0代表未审批,1代表已审批。
假设BIT(4) ,你只输入1 ,会显示0001;你输入11,会显示0011;你输入111,会显示0111。不用关心存储空间,还是去关心一下自己的使用场景吧。
四、BINARY(M)与VARBINARY(M)
BINARY 和 VARBINARY 类似于 CHAR 和 VARCHAR,存储的是二进制字节串而不是字符串,这意味着它没有字符集校验的概念,排序和比较都是基于字节中的实际数值大小进行的。
理论上讲二进制是计算机“母语”,读取应该快,但是实际速度测试中BINARY 和 VARBINARY的确快于CHAR 和 VARCHAR,只是区别不明显,例如跑1000米,你跑3分37秒,我跑3分38秒。

我个人一般情况下是不会把数据存成这两个类型的
原因一:我看不懂呀:)
比如我给你一串二进制数,你能看出下面这串数字代表:哈罗雷球白夕尚 吗?
11100101 10010011 10001000 11100111 10111101 10010111 11101001 10011011 10110111 11100111 10010000 10000011 11100111 10011001 10111101 11100101 10100100 10010101 11100101 10110000 10011010
我们使用网上的翻译器就能翻译出来

原因二:高风险
实际应用的时候 varbinary 存储单位的改变给开发带来更多的迷惑性,尤其是使用 varbinary 存储汉字时,开发需要更多的考虑具体设计多长才能满足业务需求,存在被截断的风险。
那有什么用处呢?
上文我们提到,因为binary和varbinary存储的是二进制字节串而不是字符串,这意味着它没有字符集校验的概念,排序和比较都是基于字节中的实际数值大小进行的。而char和varchar类型存储的列在比较的时候是通过字符集的方式进行的,例如:"English"和"ENGLISH"是一致的。
我们新建一张表,使用varchar和char类型建立两个字段

输入数据

使用查询:它是不区分大小写的


那怎么处理呢?

MySQL可以在SQL语句中加入 binary来区分大小写。这里的binary不是函数,是类型转换运算符,它用来强制它后面的字符串为一个二进制字符串,来弥补非二进制字符串类型不区分大小写的问题。
看到这里,小伙伴都应该明白一个道理,原因和语法不能一起讲(这就是为什么市面上会有不同知识层次的书籍),我在3年前讲的MySQL基础篇
https://www.bilibili.com/video/BV1Dk4y1d71j
现在讲原理,没有基础语法的知识积累,你能看懂 SELECT * FROM 测试表1 where v="A" 这句话的意思吗?如果没看懂,那谈什么原理?
五、BLOB类型

BLOB与我们上节课讲的TEXT的四种类型类似,区别在于:
BLOB:二进制字符串、可以保存照片、音乐、视频、文件等、没有字符集
TEXT:非二进制字符串、只可以存纯文本、有字符集
但是,我个人一般是不会用这个类型的,图片、视频、音频、文件等,通常情况下是不会直接存到数据库中的,而是保存到文件夹下,在数据库中存放一个路径。我们在学Access中就会发现,你在一个数据库中附件存上1GB的视频,哪怕这个库中只有一个表,一行记录,你打开都会很慢,但是你把视频放在文件夹里,在表中做个链接不是更好吗?
谨记:数据库容量越小越好,否则你就要配更高级的电脑;如果数据库不合理,可能需要N年以后的电脑来使用了。就好比我们玩《霍格沃兹遗产》PC端16G内存不够、8G显存不够...买了新电脑玩不爽,又回到PS5主机上面玩去了。这就是优化问题。

MySQL神功文字版合集:https://www.bilibili.com/read/readlist/rl581425