首页 > 代码库 > MySQL Cookbook读书笔记第5章

MySQL Cookbook读书笔记第5章

1,字符串属性

查看系统拥有那些字符集:

image

若需要来自多种语言存放到同一列中,会考虑Unicode字符集(utf8或ucs2),只有它能表示多语言的字符

有些字符集支持多字节,有些只包含单字节,判断是否支持多字节的方法是对比Length()h和char_length函数的返回值来判定字符串中是否有多字节。例如使用ucs2的字节长度为6,字符数目为3.

image

另外虽然Unicode字符集utf8包含多字节字符,但是一个具体的字符串有可能只包含单字节字

image

非二进制字符串另一特征是collation,决定字符集中字符排序的次序。

image

名称以ci,cs或bin结尾的collation分别是大小写不敏感,大小写敏感和二进制的。

Collation是如何影响排序的:

image

大小写不敏感(AAA,aaa和bbb,BBB相对次序不同):

image

大小写敏感:

image

二进制collation:

image

2,选择字符串的数据类型

image

当binary和char数据类型的列值中较短时,会被填满以达到要求的长度,填充值是0x00

而varbinary,varchar和blob,text类型,不需要添加或者去除填充值:

image

如果需要存储utf8(Unicode)和sjis(Japanese)字符串,可以以如下的方式来定义:

create table mytb1(

utf8data varchar(100) character set utf8 collation utf8_danish_ci,

sjisdata varchar(100) character set sjis collation sjis_japanese_ci

);

3,正确设置客户端连接的字符集

a,更改选项配置文件:

[mysql]

default-character-set=utf8

b,建立连接后执行set names语句

set names utf8

指定连接的collation:

set names ‘utf8’ collate ‘utf8-general_cl’

c,编程接口提供它们自己的方法来设置字符集

4,检查一个字符串的字符集或字符排序

image

使用charset()和collation()函数。

当配置变化时,从当前配置中获取字符集和collation属性也会发生变化。

image

5,改变字符串的字符集和字符排序

使用convert()函数改变字符串的字符集

image

使用collate操作符改变字符串的collation

image

需要同时改变字符串的字符集和collation,则首先使用convert来更改字符集然后使用collate操作符来更改排序

image

6,更改字符串字母的大小写

使用upper()和lower():

image

若只更改字符串str的第一个字符为大写,其他部分保持不变:

concat(upper(left(str,1),mid(str,2)))

为防止多次输入冗长表达式,可以定义一个函数:

image

更改大小写出现错误的情况:

当这两个函数失效时,通常是因为需要转换的是二进制串,在MySQL4.1之后,二进制串无法进行大小写转换,因为没有默认的字符集,而此时要想进行转换,必须先将字符串转换为使用字符集,然后对其使用大小写转换。

7,MySQL进行模式匹配

MySQL提供两种模式匹配的方法:基于SQL模式和基于正则表达式

a,使用SQL模式

SQL模式使用操作符like和not like来匹配字符串和模式串,通常使用两个匹配符:_用来匹配任意一个字符,%用来匹配任意一个字符串(包括空串)。

imageimage

imageimage

not like用来匹配和like相反的模式匹配过程。

b,使用正则表达式进行模式匹配

使用REGEXP操作符和正则表达式,下图为常用的模式字符:

image

如,以特定子串开头:

image

以特定子串结尾:

image

含有特定子串:

image

特定子串出现在某一位置(开头数第三个位置):

image

使用正则表达式还可以实现很多MySQL模式不具有的功能如匹配某一字符集和的任一字符,MySQL也支持使用POSIX字符集定义正则表达式:

image

MySQL和vi,linux中的正则表达式基本一致,需要好好学习,上次去中国电信游戏的时候笔试当中就有使用正则表达式匹配邮件格式的题目所以这方面得多花下时间。

image

定义选择性匹配:

匹配以aeiou开头或者以er结尾的name字符串:

image

匹配完全由数字组成或者完全由字母组成的字符串:

image

可以发现结果并不正确,因为优先级的关系匹配的是以数字开头或者以字符结尾的字符串。需要使用括号,将匹配选项归为一组:

image

模式匹配中的大小写敏感问题同样是更改字符集(非二进制)和collation来匹配是否是敏感。一般collation以ci结尾是大小写不敏感,cs结尾的是大小写敏感。

8,分割或者串联字符串

使用substring-extraction函数取得子串,使用concat()函数串联字符串

常用的substring-extraction函数包括left()函数,right()函数和mid()函数。

image

substring()函数从指定为开始向右返回整个子串,如果mid()省略第三个参数,其执行结果与substring()相同/

substring_index(str,c,n)返回str中任意指定字符左侧或右侧的整个子串,str左侧查找字符c第n次出现的位置,并且返回该位置左侧的整个子串,如果n为负数,则为右侧相同处理。

使用concat()函数,将字符串串联:

image

image

9,查询子串

如何确定一个字符串中是否含有某个子串? locate()函数返回子串在字符串中第一次出现的位置。第三个参数指定查找开始位置。

image

locate()同样也需要collation的支持来判断是否大小写敏感

10,使用FULLTEXT查询

如何对大量文本进行查询?使用FULLTEXT索引

当数据量较大时,使用模式匹配进行查询虽然也能得到结构,但是效率会很低,也可以使用模式匹配从多个列中查询相同的字符串,但是效率一样不高。

对于大量文本或者多列,可以使用fulltext代替模式匹配。要使用fulltext查询,首先要给表加上fulltext索引,然后使用match操作符查询作为索引的列。fulltext可以作用于MyISAM表中的非二进制类型字符串

a,创建表kjv

image

b,从已经处理的txt文件中,导入数据到表kjv中

image

c,使用fulltext索引来准备使用fulltext检索

image

d,如想知道kjv.txt中某个名字出现多少次,那么只需要使用match()函数来指定索引,并使用against()函数来定义要查询的文本

image

或者查询细节:

image

如果在标准查询中频繁地包含其他一些非fulltext的列,可以通过在这些列加上规则的索引来提高相关的查询性能

如更改:alter table kjv add index (bnum), add index (cnum), add index (vnum);

如想使用fulltext同时对多列进行查询,则

alter table tbl_name add fulltext (col1, col2, col3)

查询时, select …from tbl_name where match(col1, col2, col3) against(‘search string’);

11,用短语进行fulltext查询

在类似于kjv文本中比如“God”这些文本很重要,但是如果在kjv表中针对这几个单词进行fulltext查询,会发现查询不到

image

原因是索引引擎会会略太常见的词(即一般以上的行中出现的词),要想查询此时短语需要使用SQL模式匹配统计包含这两个单词的行数

image

或者修改配置文件中ft_min_word_len的值来更改。

使用boolean来搜索单词

当使用如下查询时,会查询含有名字David或Goliath的行:

image

而我们想查询的是同时含有这两个名字的行,可以如下解决:使用and联合查询条件:

image

另一种更方便的方法是使用boolean模式:

image

+表示符合某些词,-表示排除某些词,*充当通配符

image

boolean模式中使用双引号把词组括起来,可以支持词组搜索

image