mysql的串列类型之 set理解
2012-03-14 20:59
375 查看
最近对mysql的 set 串列类型有点了解,拿出来分享,有不足之处欢迎各位拍砖
首先引入set的含义:
光看理论是不行的,还得以例子来说明:例如
我在本机建立了一个表:usage_flags(详细信息如下)
这里重点是set,先不要注意我的引擎和字符编码
解释:
s 字段的类型是set,包括的值有 'ls ', 'tp ', 'ns ', 'nt ', 'nb ', 'np ', 'nc ', 'si ', 'al ', 'mr ', 'e5 ', 'e4 ', 'no ', 'ph ' (这些就是所谓的成员了);
我们来回看set的含义中一点:而是每个成员对应 SET 值中的一个二进制位
这句话的理解是:刚刚建立的s字段中包括的值(也就是'ls''ls','tp','nt'......)对应set值中的一个二进制,我们来看以下内容:
为了方便查看以下贴出来s列的十进制和二进制的形式,这样可以看出set值对应的二进制关系
解释:
在这里,s+0列中的数值可以等价于s列中对应的值,我们来看一个例子:
以下所查出来的内容是完全相同的,这一点可以证明上述所叙
当然,这些需要运用到实际开发中才能更加深入的理解,我们再来看一个例子:
为了解答这个例子,我们按照上面所说的步骤来做;
首先,我们来建立一个userinf表和usertype字段并且该类型为set:
然后,我们再查看对应的十进制和二进制关系:
我们再回头看看这个例子的问题:
请问,(UserType & 2147483648)和(UserType & 1073741824)分别代表什么含义?
在这里有必要说一下这里的"&"的含义,很多朋友认为是连字符,其实不是的,这里的&属于位运算符,大概意思是:按位AND(与)如果两个操作数的对应位为1,则结果位为1,也就是说两个值相等则返回该对应的位,不等就不返回,意思有点类似于逻辑运算符"&&",和'&'一起的位运算符还有'|","<<",">>"这些运算符的含义可以去google一下,我们再回到问题,来看下面结果:
看出来了吗?UserType & 2147483648 要找的其实是 admin,同样的UserType & 1073741824要找的是nostop(注意看我两种where的写法一个是=,一个是位运算符(&):
在这些值里面('general','a1','a2','a3'....)我们可以找很多只要这些值('general','a1','a2','a3')能组合起来的字符,比如说我们找usertype&108字符:
这样我们找到了a2+a3+a5+a6=108组合的字符了(a2,a3,a5,a6)。
有不足之处希望各路高手指点,谢谢
首先引入set的含义:
对于 SET 类型,SET 列的集合成员不是顺序编号的,而是每个成员对应 SET 值中的一个二进制位。 第一个集合成员对应于 0 位,第二个成员对应于 1 位,以此类推。 数值 SET 值 0 对应于空串,SET 成员以位值保存。 每个字节的 8 个集合值可按此方式存放,因此 SET 列的存储大小是由集合成员的数目决定的,最多 64 个成员。 对于大小为 1 到 8、9 到 16、17 到 24、25 到 32、33 到 64 个成员的集合, 其 SET 值分别占用 1、2、3、4 或 8 个字节。 SET 定义中的值顺序决定了在显示由多个集合成员组成的 SET 列值时,子串出现的顺序。
光看理论是不行的,还得以例子来说明:例如
我在本机建立了一个表:usage_flags(详细信息如下)
这里重点是set,先不要注意我的引擎和字符编码
mysql> show create table usage_flags\G *************************** 1. row *************************** Table: usage_flags Create Table: CREATE TABLE `usage_flags` ( `s` set('ls','tp','ns','nt','nb','np','nc','si','al','mr','e5','e4','no','ph') default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 1 row in set (0.00 sec)
解释:
s 字段的类型是set,包括的值有 'ls ', 'tp ', 'ns ', 'nt ', 'nb ', 'np ', 'nc ', 'si ', 'al ', 'mr ', 'e5 ', 'e4 ', 'no ', 'ph ' (这些就是所谓的成员了);
我们来回看set的含义中一点:而是每个成员对应 SET 值中的一个二进制位
这句话的理解是:刚刚建立的s字段中包括的值(也就是'ls''ls','tp','nt'......)对应set值中的一个二进制,我们来看以下内容:
为了方便查看以下贴出来s列的十进制和二进制的形式,这样可以看出set值对应的二进制关系
mysql> select s,s+0,bin(s+0) from usage_flags; +-------------+------+----------------+ | s | s+0 | bin(s+0) | +-------------+------+----------------+ | ls | 1 | 1 | | tp | 2 | 10 | | ns | 4 | 100 | | nt | 8 | 1000 | | nb | 16 | 10000 | | np | 32 | 100000 | | nc | 64 | 1000000 | | si | 128 | 10000000 | | al | 256 | 100000000 | | mr | 512 | 1000000000 | | e5 | 1024 | 10000000000 | | e4 | 2048 | 100000000000 | | no | 4096 | 1000000000000 | | ph | 8192 | 10000000000000 | +-------------+------+----------------+ 14 rows in set (0.00 sec)
解释:
在这里,s+0列中的数值可以等价于s列中对应的值,我们来看一个例子:
以下所查出来的内容是完全相同的,这一点可以证明上述所叙
mysql> select s,s+0,bin(s+0) from usage_flags where s=8; +------+------+----------+ | s | s+0 | bin(s+0) | +------+------+----------+ | nt | 8 | 1000 | +------+------+----------+ 1 row in set (0.00 sec) mysql> select s,s+0,bin(s+0) from usage_flags where s='nt'; +------+------+----------+ | s | s+0 | bin(s+0) | +------+------+----------+ | nt | 8 | 1000 | +------+------+----------+ 1 row in set (0.00 sec)
当然,这些需要运用到实际开发中才能更加深入的理解,我们再来看一个例子:
数据库已连接 if (preg_match("/admin/i",$FORM_userid)) { $sql = "SELECT * FROM userinf WHERE UserId='$FORM_userid' AND Password=password('$FORM_psd') AND (UserType & 2147483648)"; } else { $sql = "SELECT * FROM userinf WHERE UserId='$FORM_userid' AND Password='$FORM_psd' AND (UserType & 1073741824)"; } 这是身份验证的一段程序。$FORM_userid和$FORM_psd'分别是上一Web页登录窗口提交的的用户名和密码。 userinf表中的UserType列类型为SET,其中的值分别为:'general','a1','a2','a3','a4','a5','a6','a7','b0','b1','b2','b3', 'b4','b5','b6','b7','c0','c1','c2','c3','c4','c5','c6','c7','d0','d1','d2','d3','d4', 'd5','nostop','admin'。 请问,(UserType & 2147483648)和(UserType & 1073741824)分别代表什么含义,为什么?
为了解答这个例子,我们按照上面所说的步骤来做;
首先,我们来建立一个userinf表和usertype字段并且该类型为set:
mysql> show create table userinf\G *************************** 1. row *************************** Table: userinf Create Table: CREATE TABLE `userinf` ( `usertype` set('general','a1','a2','a3','a4','a5','a6','a7','b0','b1','b2','b3','b4','b5','b6','b7','c0','c1','c2','c3','c4','c5','c6','c7','d0','d1','d2','d3','d4','d5','nostop','admin') default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 1 row in set (0.00 sec)
然后,我们再查看对应的十进制和二进制关系:
mysql> select usertype,usertype+0,bin(usertype+0) from userinf; +---------+------------+----------------------------------+ | usertype| usertype+0 | bin(usertype+0) | +---------+------------+----------------------------------+ | general | 1 | 1 | | a1 | 2 | 10 | | a2 | 4 | 100 | | a3 | 8 | 1000 | | a4 | 16 | 10000 | | a5 | 32 | 100000 | | a6 | 64 | 1000000 | | a7 | 128 | 10000000 | | b0 | 256 | 100000000 | | b1 | 512 | 1000000000 | | b2 | 1024 | 10000000000 | | b3 | 2048 | 100000000000 | | b4 | 4096 | 1000000000000 | | b5 | 8192 | 10000000000000 | | b6 | 16384 | 100000000000000 | | b7 | 32768 | 1000000000000000 | | c0 | 65536 | 10000000000000000 | | c1 | 131072 | 100000000000000000 | | c2 | 262144 | 1000000000000000000 | | c3 | 524288 | 10000000000000000000 | | c4 | 1048576 | 100000000000000000000 | | c5 | 2097152 | 1000000000000000000000 | | c6 | 4194304 | 10000000000000000000000 | | c7 | 8388608 | 100000000000000000000000 | | d0 | 16777216 | 1000000000000000000000000 | | d1 | 33554432 | 10000000000000000000000000 | | d2 | 67108864 | 100000000000000000000000000 | | d3 | 134217728 | 1000000000000000000000000000 | | d4 | 268435456 | 10000000000000000000000000000 | | d5 | 536870912 | 100000000000000000000000000000 | | nostop | 1073741824 | 1000000000000000000000000000000 | | admin | 2147483648 | 10000000000000000000000000000000 | +---------+------------+----------------------------------+ 32 rows in set (0.00 sec)
我们再回头看看这个例子的问题:
请问,(UserType & 2147483648)和(UserType & 1073741824)分别代表什么含义?
在这里有必要说一下这里的"&"的含义,很多朋友认为是连字符,其实不是的,这里的&属于位运算符,大概意思是:按位AND(与)如果两个操作数的对应位为1,则结果位为1,也就是说两个值相等则返回该对应的位,不等就不返回,意思有点类似于逻辑运算符"&&",和'&'一起的位运算符还有'|","<<",">>"这些运算符的含义可以去google一下,我们再回到问题,来看下面结果:
mysql> select usertype,usertype+0,bin(usertype+0) from userinf where usertype= 2147483648; +----------+------------+----------------------------------+ | susertype| usertypes+0| bin(usertype+0) | +----------+------------+----------------------------------+ | admin | 2147483648 | 10000000000000000000000000000000 | +----------+------------+----------------------------------+ 1 row in set (0.00 sec)
看出来了吗?UserType & 2147483648 要找的其实是 admin,同样的UserType & 1073741824要找的是nostop(注意看我两种where的写法一个是=,一个是位运算符(&):
mysql> select usertype,usertype+0,bin(usertype+0) from userinf where usertype&1073741824; +--------+------------+---------------------------------+ | s | s+0 | bin(s+0) | +--------+------------+---------------------------------+ | nostop | 1073741824 | 1000000000000000000000000000000 | +--------+------------+---------------------------------+ 1 row in set (0.00 sec)
在这些值里面('general','a1','a2','a3'....)我们可以找很多只要这些值('general','a1','a2','a3')能组合起来的字符,比如说我们找usertype&108字符:
mysql> select usertype,usertype+0,bin(usertype+0) from userinf where usertype&108; | usertype | usertype+0 | bin(usertype+0) | +-------------+-------------+-----------------+ | a2 | 4 | 100 | | a3 | 8 | 1000 | | a5 | 32 | 100000 | | a6 | 64 | 1000000 | +------+------+-------------------------------+ 4 rows in set (0.00 sec) +-------------+-------------+--------------- -+
这样我们找到了a2+a3+a5+a6=108组合的字符了(a2,a3,a5,a6)。
有不足之处希望各路高手指点,谢谢
相关文章推荐
- MySQL数据类型理解和优化
- 关于Mysql的Enum和Set字段类型
- MySQL 中的 SET 与 ENUM 类型使用详解
- 理解MySQL数据类型,宽度,字节
- 理解MySQL数据类型 避免数据库设计出现混乱
- 理解MySQL数据类型
- MySQL的SET字段类型
- ENUM和SET类型 mysql
- MySQL 四种特殊数据类型 ENUM、SET、BOOL/BOOLEAN、TINYINT
- mysql中被遗忘的set数据类型
- 理解MySQL——索引与优化 索引类型和锁
- setTimeStamp()与setDate()区别 如何将java中Date存入mysql中的datetime中,字符串怎么转换为日期类型
- mysql中的较少用到的数据类型的一点说明,real;enum,set;POINT,LINESTRING,POLYGON等
- 深入理解mysql SET NAMES和mysql(i)_set_charset的区别
- MySQL数据类型 ENUM和SET
- 理解MySQL数据类型
- MySQL数据类型:TINYINT,SMALLINT,MEDIUMINT,INT,INTEGER,BIGINT;text,longtext,mediumtext,ENUM,SET等字段类型区别
- MySQL中的几种类型理解
- 深入理解MySQL的数据库引擎的类型