文章目录
第十七章 组合查询
1 组合查询
多数SQL查询都只包含一个或从多个表中返回数据的单条select语句,MySQL也允许执行多个查询,并将结果作为单个查询结果返回
2 创建组合查询
使用union操作符来组合多条SQL查询,利用union可给出多条select语句,将它们的结果组合成单个结果集
(1) 使用union
如为了检索出价格小于等于5的所有物品,还想要检索出生产商1001和1002生产的产品,可以使用where子句也可以使用union
使用where子句完成:

使用union:

这条语句中用union关键字分隔,union指示MySQL执行两条select语句,并把输出组合成单个查询结果集
上述的例子中,使用union比where子句更为繁杂,但对于更复杂的过滤条件,或者从多个表中检索数据的情形,使用union更为简单
(2) union规则
union使用时需要注意的规则:
1,union必须由两条以上的select语句组成,语句之间使用union分隔
2,union中的每个查询都必须包含相同列,表达式聚集函数
3,列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含地转换的类型
(3) 包含或取消重复的行
union会从查询结果中去掉相同的行
当两条或多条select语句使用union后同时返回某一行时,重复的行将被自动取消,这是union的默认行为,但如果需要想返回所有匹配行,可使用union all而不是union
(4) 对组合查询结果排序
select语句的输出用order by子句排序,再用union组合查询时,只能使用一条order by子句,它必须出现在最后一条select子句后
对于结果集,不存在用一种方式排序一部分,而又用另一种方式排序另一部分,因此不允许使用多条order by子句

虽然order by子句似乎只是最后一条select语句的组成部分,但实际上MySQL将用它来排序所有select语句返回的结果
第十八章 全文本搜索
1 理解全文本搜索
并非所有的引擎都支持全文本搜索:MySQL支持几种基本的数据库引擎,并非所有的引擎都支持全文本搜索,两个最常用的引擎为MyISAM和InnoDB,前者支持全文本搜索,而后者不支持
之前使用过like关键字利用通配符匹配文本,和使用正则表达式进行匹配,虽然这些搜索机制很有用,但存在几个重要的限制:
1,性能,通配符和正则表达式的匹配需要MySQL尝试匹配表中所有行,因此如果被搜索行增加时,那么就会更耗时
2,明确控制,使用通配符和正则表达式匹配,很难明确的控制匹配什么和不匹配什么
3,智能化的结果,虽然基于通配符和正则表达式提供了灵活的搜索,但它们不能提供一种智能化的选择结果的方法,如一个特殊词的搜索将会返回包含该词的所有行
所有这些限制以及更多的限制都可以使用全文本搜索来解决,在使用全文本搜索前,MySQL不需要分别查看每个行,不需要分别分析和处理每个词。MySQL创建指定列中各词的一个索引,搜索可以针对这些词进行,这样MySQL可以快速高效地决定哪些词匹配,哪些不匹配,它们地频率等
2 使用全文本搜索
为了进行全文本搜索,必须索引被搜索地列,而且要随着数据地改变不断地重新索引,在对表列进行适当设计后,MySQL会自动进行所有地索引和重新索引
在索引之后,select可以与match()和against()一起使用来搜索
(1) 启用全文本搜索支持
一般在创建表时启用全文本搜索,creat table接受fulltext子句,它给出被索引的一个逗号分隔的列表
create table productnotes
(
note_id int not null auto_increment,
prod_id char(10) not null,
note_date datetime not null,
note_text text null,
primary key(note_id),
fulltext(note_text)
)engine = MyISAM;
MySQL根据子句fulltext(note_text)的指示对它进行索引,这里的fulltext索引单个列,如有需要也可指定多个列,在定义完后,MySQL自动维护该索引,在增加,删除更新行时,索引随之自动更新
(2) 进行全文本搜索
使用match()和against()来进行全文本搜索,match()指定被搜索的列,against()指定要使用的搜索表达式

match(note_text)指示MySQL针对指定列进行搜索,against(‘raabit’)指定词rabbit作为搜索文本,由于有两行包含词rabbit,这两行被返回
传递给match()的值必须与fulltext()中的相同,如果指定多个列,那么也都需要列出且次序相同,搜索不区分大小写
全文本搜索另一个重要部分就是对结果排序,具有较高等级的行先返回,like虽然也能完成搜索的功能,但是全文本搜索提供了简单like不能提供的功能,且由于数据是索引的,全文本搜索还相当快
(3) 使用查询扩展
查询扩展用来设法放宽所返回的全文本搜索结果的范围,如想要找到anvils的注释,只有一个注释包含anvils,但还想找到可能与你搜索有关的其它所有行,即使它们不包含anvils,利用查询扩展,能找出可能相关的结果,即使它们不包含所查找的词
使用查询扩展时,MySQL:
1,进行一个基本的全文本查询,找出与搜索条件匹配的所有行
2,MySQL检查这些匹配行并选择所有有用的词
3,MySQL再次进行全文本搜索,这次不仅使用原来的条件,还使用所有有用的词
简单的全文本搜索:

使用查询扩展:

查询扩展极大增加了返回的行数,表中的行越多,使用查询扩展返回的结果就越好
(4) 布尔文本搜索
MySQL提供全文本搜索的另一种形式,称为布尔方式,以布尔方式,可以提供如下的细节:
1,要匹配的词
2,要排斥的词
3,排列提示
4,表达式分组
布尔方式即使没有定义fulltext索引,也可以使用,但这是种非常缓慢的操作

此文本搜索包含词heavy的所有行,其中使用了in boolean mode,但实际上没有指定布尔操作符,其结果与没有指定布尔方式的结果相同
为了匹配包含heavy但不包含任意以rope开始的词的行,可使用:

这次只返回一行,这一次仍然匹配heavy,dan -rope*指示了MySQL排除包含rope开始的词(包括ropes)
上述操作使用了两个全文本操作符,-(排除一个词) 和 *(截断操作符,可以看作末尾的一个通配符)
第十九章 插入数据
1 数据插入
insert是用来插入行到数据库表的,插入可以用几种方式使用:
1,插入完整的行
2,插入行的一部分
3,插入多行
4,插入某些查询的结果
插入及系统安全:可针对每个表或每个用户,利用MySQL的安全机制禁止使用insert语句
2 插入完整的行
把数据插入表中最简单的方式是使用最基本的insert语法,它要求指定表明和被插入到新行中的值,insert语句一般不会产生输出
insert into customers(cust_name,
cust_address,
cust_city,
cust_state,
cust_zip,
cust_country,
cust_contact,
cust_email)
values('pep e.lapew',
'100 main street',
'la',
'90046',
'usa',
null,
null);
在表名后的括号内明确给出了列名,在插入行时,MySQL将用values列表中的相应值填入表中的对应项,values中的第一个值对应第一个指定列名,以此类推
因为提供了列名,values必须以其指定的次序匹配指定的列名,不一定按照各个列出现在表中的次序。其优点是:即使表的结构发生了变化,此insert语句仍然能够正常工作
省略列:如果表的定义允许,则可以在insert操作中,省略某些列,省略的列必须满足以下条件:
1,该列定义允许为null值
2,在表定义中给出默认值,这表示如果不给出值将给出默认值
如果对表中不允许null值且没有默认值的列不给出值,那么MySQL会报错,且插入操作失败
提高整体性能:数据库经常被多个客户访问,对处理什么请求以及用什么次序处理进行管理是MySQL的任务,insert操作可能很耗时,且可能降低待处理的select语句的性能
如果数据检索是最重要的,那么可以在insert 和into 之间添加关键字low_priority,指示MySQL降低insert的优先级
3插入多个行
insert想插入到多个行可以使用多条insert语句,可以一次提交,每条语句用一个分号结束
insert into customers(
cust_name,
cust_address,
cust_state,
cust_zip,
cust_country)
values(
'xxx',
'xxx',
'xxx',
'xxx',
'xxx'
),
(
'xxx',
'xxx',
'xxx',
'xxx',
'xxx'
);
单条insert语句有多组值,每组值用一对圆括号括起,用 , 分隔
4 插入检索出的数据
insert语句除了给表插入一个指定行外,还可以用它将一条select语句的结果插入表中
如想从另一表中合并客户列表到你的customers表,不需要每次读取一行使用insert插入,可以:
insert into customers(
cust_id,
cust_contact,
cust_email,
cust_name,
cust_address,
cust_city,
cust_state,
cust_zip,
cust_country)
select cust_id,
cust_contact,
cust_email,
cust_name,
cust_address,
cust_city,
cust_state,
cust_zip,
cust_country
from custnew;
select语句从custnew检索出要插入的值,而不是列出它们,select中列出的每个列对应于customers表名后所跟的列表中的每一列,这条语句将插入多少行有赖于custnew表中有多少行
第二十章 更新和删除数据
1 更新数据
为了更新(修改)表中的数据,可使用update语句,可采用两种方法使用update语句:
1,更新表中特定行
2,更新表中所有行
update语句由3部分组成:
1,要更新的表
2,列名和它们的新值
3,确定要更新行的过滤条件
如更新客户10005的电子邮件地址:
update customers
set cust_email = 'xxxx'
where cust_id = 10005;
update语句总是以要更新的表的名字开始,set命令用来将新值赋给被更新的列,update语句以where子句结束,它告诉MySQL更新哪一行,没有where子句,MySQL会用这个电子邮件地址更新所有的行,这不是我们需要的
更新多个列:
update customers
set cust_name = 'xxx',
cust_email = 'xxxx'
where cust_id = 10005;
update也具备删除的功能,只要将值置为null即可:
update customers
set cust_email = null,
where cust_id = 10005;
2 删除数据
为了从一个表中删除一个数据,使用delete语句:
1,从表中删除特定的行
2,从表中删除所有行
从customers表中删除一行:
delete from customers
where cust_id = 10006;
delete不需要列名或通配符,delete删除整行,如果要删除指定的列使用update
delete删除的是表的内容,而不是表本身
如果想要删除表中所有行,可以使用 truncate table语句,它的速度比delete更快,但 truncate table的本质是删除原来的表并重新创建一个表,而delete是逐行删除表的内容
3 更新和删除的指导原则
update和delete语句全都具有where子句,这样做因为如果省略了where子句,则update或delete将被应用到所有的行,极易更新或删除表中所有数据
使用update和delete遵循的原则:
1,除非确实打算更新和删除每一行,否则绝对不要使用不带where子句的delete或update语句
2,保证每个表都有主键,尽可能像where子句那样使用它
3,在对update或delete语句使用正确的where子句前,应该先用select语句进行测试,保证它过滤的结果正确
4,MySQL没有撤销,谨慎使用update和delete
4192

被折叠的 条评论
为什么被折叠?



