MYSQL的binary解决mysql数据大小写敏感问题的方法 |
复制代码 代码如下: mysql> select binary ABCD=abcd COM1, ABCD=abcd COM2; +--------+-----------+ | COM1 | COM2 | +--------+-----------+ | 0 | 1 | +---------+-----------+ 1 row in set (0.00 sec) (仅仅有些而已!4.*以前) 复制代码 代码如下: create TABLE usertest ( id int(9) unsigned NOT NULL auto_increment, username varchar(30) NOT NULL default , primary key (id) ) 插入数据: 复制代码 代码如下: insert into usertest (username) VALUES(美文); insert into usertest (username) VALUES(美国项目); insert into usertest (username) VALUES(李文); insert into usertest (username) VALUES(老唐); insert into usertest (username) VALUES(梦漂); insert into usertest (username) VALUES(龙武); insert into usertest (username) VALUES(夏); 例如:select * from usertest where username like %夏% ,结果七条记录都出来了,比较郁闷 。 如果使用=而不是like的时候,select * from usertest where username = 夏 ,只出现一个结果 。因为mysql 的LIKE操作是按照ASCII 操作的,所以LIKE的时候是可能有问题的 。问题继续:如果再加上: 复制代码 代码如下: insert into usertest (username) VALUES(文); insert into usertest (username) VALUES(唐); 还是使用select * from usertest where username = 夏 ,结果还是出现3条记录,又郁闷了 。解决办法如下: 1.在create的时候就使用binary,而不是在query的时候加 。 复制代码 代码如下: username varchar(30) BINARY NOT NULL default , 如果表已经建好了,使用: alter table usertest modify username varchar(32) binary; 来就该表的属性 。 2.在query的时候加上binary,select * from usertest where username like binary %夏% ,就可以准确的查询出一条记录来 。 char使用固定长度的空间进行存储,char(4)存储4个字符,根据编码方式的不同占用不同的字节,gbk编码方式,不论是中文还是英文,每个字符占用2个字节的空间,utf8编码方式,每个字符占用3个字节的空间 。 如果需要存储的字符串的长度跟所有值的平均长度相差不大,适合用char,如MD5 。 对于经常改变的值,char优于varchar,原因是固定长度的行不容易产生碎片 。 对于很短的列,char优于varchar,原因是varchar需要额外一个或两个字节存储字符串的长度 。 varchar保存可变长度的字符串,使用额外的一个或两个字节存储字符串长度,varchar(10),除了需要存储10个字符,还需要1个字节存储长度信息(10),超过255的长度需要2个字节来存储 例外:Myisam引擎中使用ROW_FORMAT=FIXED时,每行使用相同的空间,造成浪费 char和varchar后面如果有空格,char会自动去掉空格后存储,varchar虽然不会去掉空格,但在进行字符串比较时,会去掉空格进行比较 复制代码 代码如下: +-------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(4) | YES | | NULL | | | addr | char(8) | YES | | NULL | | | bn | varbinary(4) | YES | | NULL | | | b | binary(8) | YES | | NULL | | +-------+--------------+------+-----+---------+----------------+ +----------------------+----------------------+ | concat("$",name,"$") | concat("$",addr,"$") | +----------------------+----------------------+ | $asdf$ | $a$ | | $asdf$ | $a$ | | $a $ | $a$ | | $a$ | $a$ | | $t a$ | $a$ | +----------------------+----------------------+ mysql> select * from zcy where name=a ; //由于name是varchar,比较时,a 自动转换为a +----+------+------+------+----------+ | id | name | addr | bn | b | +----+------+------+------+----------+ | 3 | a | a | ab | ab | | 4 | a | a | ab | a | +----+------+------+------+----------+ 2 rows in set (0.00 sec) mysql> select * from zcy where name=a; +----+------+------+------+----------+ | id | name | addr | bn | b | +----+------+------+------+----------+ | 3 | a | a | ab | ab | | 4 | a | a | ab | a | +----+------+------+------+----------+ 2 rows in set (0.00 sec) +-------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(4) | YES | | NULL | | | addr | char(8) | YES | | NULL | | | bn | varbinary(4) | YES | | NULL | | | b | binary(8) | YES | | NULL | | +-------+--------------+------+-----+---------+----------------+ +--------------------+-------------------+ | concat("$",bn,"$") | concat("$",b,"$") | +--------------------+-------------------+ | $ab a$ | NULL | | $ab $ | $ab $ | | $ab$ | $ab $ | | $ab $ | $a $ | | NULL | $a $ | | NULL | $abcde $ | | NULL | $abcd1234$ | +--------------------+-------------------+ binary保存二进制字符串,它保存的是字节而不是字符,没有字符集限制 binary(8)可以保存8个字符,每个字符占1个字节,共占8个字节 进行比较时是按字节进行比较,而不是按字符(char),按字节比较比字符简单快速 按字符比较不区分大小写,而binary区分大小写,结尾使用\0填充,而不是空格 复制代码 代码如下: mysql> select * from zcy where b=a\0\0\0\0\0\0\0; +----+------+------+------+----------+ | id | name | addr | bn | b | +----+------+------+------+----------+ | 5 | t a | a | NULL | a | +----+------+------+------+----------+ mysql> select * from zcy where b=a \0\0\0\0\0\0; +----+------+------+------+----------+ | id | name | addr | bn | b | +----+------+------+------+----------+ | 4 | a | a | ab | a | +----+------+------+------+----------+ varbinary保存变长的字符串,后面不会补\0 mysql> select * from zcy where bn=ab; +----+------+------+------+----------+ | id | name | addr | bn | b | +----+------+------+------+----------+ | 3 | a | a | ab | ab | +----+------+------+------+----------+ 1 row in set (0.01 sec) mysql> select * from zcy where bn=ab ; +----+------+------+------+----------+ | id | name | addr | bn | b | +----+------+------+------+----------+ | 2 | asdf | a | ab | ab | +----+------+------+------+----------+ 1 row in set (0.00 sec) mysql> select * from zcy where bn=ab ; +----+------+------+------+----------+ | id | name | addr | bn | b | +----+------+------+------+----------+ | 4 | a | a | ab | a | +----+------+------+------+----------+ 1 row in set (0.00 sec) MySql中Blob与Text的区别 复制代码 代码如下: mysql> SET max_sort_length = 2000; mysql> SELECT id, comment FROM tbl_name -> ORDER BY comment; 当你想要使超过max_sort_length的字节有意义,对含长值的BLOB或TEXT列使用GROUP BY或ORDER BY的另一种方式是将列值转换为固定长度的对象 。标准方法是使用SUBSTRING函数 。例如,下面的语句对comment列的2000个字节进行排序: 复制代码 代码如下: mysql> SELECT id, SUBSTRING(comment,1,2000) FROM tbl_name -> ORDER BY SUBSTRING(comment,1,2000); ·BLOB或TEXT对象的最大大小由其类型确定,但在客户端和服务器之间实际可以传递的最大值由可用内存数量和通信缓存区大小确定 。你可以通过更改max_allowed_packet变量的值更改消息缓存区的大小,但必须同时修改服务器和客户端程序 。例如,可以使用mysql和mysqldump来更改客户端的max_allowed_packet值 。 每个BLOB或TEXT值分别由内部分配的对象表示 。这与其它列类型形成对比,后者是当打开表时为每1列分配存储引擎 。 |