MySQL有少数几种存储类型使用紧凑的位存储数据。所有这些位类型,不管底层存储格式和处理方式如何,从技术上来说都是字符串类型。

BIT

在MySQL5.0之前,BIT是TINYINT的同义词。但是在MySQL5.0以及更新版本,这是一个特性完全不同的数据类型。下面我们将讨论BIT类型新的行为特性。
可以使用BIT列在一列中存储一个或多个true/false值。BIT(1)定义一个包含单个位的字段,BIT(2)存储2个位,以此类推。BIT列的最大长度是64个位。
BIT的行为因存储引擎而异。MyISAM会打包存储所有的BIT列,所以17个单独的BIT列只需要17个位存储(假设没有可为NULL的列),这样MyISAM只使用3个字节就能存储这17个BIT列。其他存储引擎如Memory和InnoDB,为每个BIT列使用一个足够存储的最小整数类型来存放,所以不能节省存储空间。
MySQL把BIT当作字符串类型,而不是数字类型。当检索BIT(1)的值时,结果是一个包含二进制0或1值的字符串,而不是ASCII码的“0”或“1”。然而,在数字上下文的场景中检索时,结果将是位字符串转换成的数字。如果需要和另外的值比较结果,一定要记得这一点。例如,如果存储一个值b’00111001’(二进制值等于57)到BIT(8)的列并且检索它,得到的内容是字符码为57的字符串。也就是说得到ASCII码为57的字符“9”。但是在数字上下文场景中,得到的是数字57:
位数据类型 - 图1
这是相当令人费解的,所以我们认为应该谨慎使用BIT类型。对于大部分应用,最好避免使用这种类型。
如果想在一个bit的存储空间中存储一个true/false值,另一个方法是创建一个可以为空的CHAR(0)列。该列可以保存空值(NULL)或者长度为零的字符串(空字符串)。

SET

如果需要保存很多true/false值,可以考虑合并这些列到一个SET数据类型,它在MySQL内部是以一系列打包的位的集合来表示的。这样就有效地利用了存储空间,并且MySQL有像FIND_IN_SET()和FIELD()这样的函数,方便地在查询中使用。它的主要缺点是改变列的定义的代价较高:需要ALTER TABLE,这对大表来说是非常昂贵的操作。一般来说,也无法在SET列上通过索引查找。

在整数列上进行按位操作

一种替代SET的方式是使用一个整数包装一系列的位。例如,可以把8个位包装到一个TINYINT中,并且按位操作来使用。可以在应用中为每个位定义名称常量来简化这个工作。
比起SET,这种办法主要的好处在于可以不使用ALTER
TABLE改变字段代表的“枚举”值,缺点是查询语句更难写,并且更难理解(当第5个bit位被设置时是什么意思?)一些人非常适应这种方式,也有一些人不适应,所以是否采用这种技术取决于个人的偏好。
一个好的包装位的应用的例子是保存权限的访问控制表(ACL)。每个位或者SET元素代表一个值,例如CAN_READ、CAN_WRITE,或者CAN_DELETE。如果使用SET列,可以让MySQL在列定义里存储位的值到映射关系;如果使用整数列,则可以在应用代码里存储这个对应关系。这是使用SET列的查询:
位数据类型 - 图2
如果使用整数来存储,则可以参考下面的例子:
位数据类型 - 图3
这里我们使用MySQL变量来定义值,但是也可以在代码里使用常量来替代。


作者:一任天然

来源:CSDN
原文:https://blog.csdn.net/yirentianran/article/details/79320491
版权声明:本文为博主原创文章,转载请附上博文链接!