第18章 全文本搜索
18.1 理解全文本搜索
MySQL支持几种基本的数据库引擎。并非所有的引擎都支持本书所描述的全文本搜索。两个最常使用的引擎为MyISAM和InnoDB,前者支持全文本搜索,而后者不支持。
在使用全文本搜索时,MySQL不需要分别查看每个行,不需要分别分析和处理每个词。MySQL创建指定列中各词的一个索引,搜索可以针对这些词进行。这样,MySQL可以快速有效地决定哪些词匹配(哪些行包含它们),哪些词不匹配,它们匹配的频率,等等。
18.2 使用全文本搜索
18.2.1 启用全文本搜索
CREATE TABLE product_notes ( note_id int NOT NULL AUTO_INCREMENT, note_date datetime NOT NULL, note_text text NULL, PRIMARY KEY(note_id), FULLTEXT(note_text) ) ENGINE=MyISAM; //在note_text列进行了全文搜索。FULLTEXT表示该列启用全文搜索 //不要在导入数据时使用FULLTEXT
18.2.2 进行全文本搜索
SELECT note_text FROM product_notes WHERE Match(note_text) Against(‘rabbit’); //检索单个列note_text。Match表示对指定列搜索,而rabbit为指定文本 //因此,包含rabbit的行会被返回 其实也可以用LIKE子句完成 SELECT note_text FROM product_notes WHERE note_text LIKE '%rabbit%'; //%匹配0或多个字符 /*但是,全文本会以文本匹配的良好程度排序。 全文本搜索的一个重要部分就是对结果排序。具有较高等级的行先返回(因为这些行很可能 是你真正想要的行)。 1:A fat rabbit 2:A rabbit 用全文本搜索出来就的排序就会下面这样(rabbit在前面),like就可能是上面的。 2:A rabbit 1:A fat rabbit */
18.2.3 使用查询扩展
查询扩展用来设法放宽所返回的全文本搜索结果的范围。只用于MySQL版本4.1.1或更高级的版本
使用查询扩展可能会找到一些你不需要的行。
SELECT note_text FROM product_notes WHERE Match(note_text) Against('rabbit' WITH QUERY EXPANSION); //含有rabbit可能2行,使用查询扩展可能查到大于2行,因为数据库把觉得有关系的行也查出来了
18.2.4 布尔文本搜索
布尔文本也是全文本搜索
SELECT note_text FROM productsnotes WHERE Math(note_text) Against ('heavy -rope*' IN BOOLEAN MODE); //为了匹配heavy但不包含任意以rope词的行 //使用的是IN BOOLEAN 关键字 // 布尔操作符 说 明 // + 包含,词必须存在 // - 排除,词必须不出现 // > 包含,而且增加等级值 // < 包含,且减少等级值 // () 把词组成子表达式(允许这些子表达式作为一个组被包含、排除、排列等) // ~ 取消一个词的排序值 // * 词尾的通配符(截断) // "" 定义一个短语(与单个词的列表不一样,它匹配整个短语以便包含或排除这个短语) SELECT note_text FROM productsnotes WHERE Math(note_text) Against ('+rabbit +bait' IN BOOLEAN MODE); //包含rabbit和bait的行 SELECT note_text FROM productsnotes WHERE Math(note_text) Against ('rabbit bait' IN BOOLEAN MODE); //至少包含两个中的一个 SELECT note_text FROM productsnotes WHERE Math(note_text) Against ('"rabbit bait"' IN BOOLEAN MODE); //匹配短语rabbit bait SELECT note_text FROM productsnotes WHERE Math(note_text) Against ('>rabbit <carrot' IN BOOLEAN MODE); //匹配两个词,rabbit等级增加,降低后者等级 SELECT note_text FROM productsnotes WHERE Math(note_text) Against ('+safe +(<combination)' IN BOOLEAN MODE); //匹配这两个词,降低后者的排序等级
18.2.5 全文本搜索的使用说明
(如有需要,再去查看书籍,这些要点记录了也不知道哪是重点)
第19章 插入数据
19.1 插入数据(INSERT)
19.2 插入完整的行
INSERT INTO Customers VALUES(null,'a', 'b', 'v'); //第一行是id,该列有MySQL自动增量,让MySQL写一个id,记录顺序 INSERT INTO Customers(cust_name,cust_city,cust_State) VALUES('a', 'b', 'v'); //这两个写法完成的工作一样,第二种写法给出了列名 //只要数据和列名一致,就不会出错,第一种的顺序必须和表中一致,不太好。
一种优化:INSERT比较费时,当多个客户访问时,如果数据检索是最重要的(通常是这样),则你可以通过在INSERT和INTO之间添加关键字LOW_PRIORITY,指示MySQL降低INSERT语句的优先级
19.3 插入多个行
使用多条插入语句,或者一条,一次提交
INSERT INTO Customers(cust_name,cust_city,cust_State) VALUES('a', 'b', 'v'); INSERT INTO Customers(cust_name,cust_city,cust_State) VALUES('aa', 'bb', 'vv'); //或者 INSERT INTO Customers(cust_name,cust_city,cust_State) VALUES('a', 'b', 'v'),('aa', 'bb', 'vv');//这种性能比上面快
19.4 插入检索出的数据
将一个名为custnew中的数据导入customers表中 INSERT INTO Customers(cust_name,cust_city,cust_State) SELECT cust_name,cust_city,cust_State FROM custnew;
第20章 更新和删除数据
20.1 更新数据
UPDATE customers SET cust_email = 'aa@cc.com' WHERE cust_id = 1005; //更新多个列 UPDATE customers SET cust_email = 'aa@cc.com',cust_name = 'haha' WHERE cust_id = 1005; //删除某个列的值,可以置为NULL UPDATE customers SET cust_email = NULL WHERE cust_id = 1005;
20.2 删除数据
DELETE FROM customers WHERE cust_id = 10006;//一行都没了 //DELETE删除行,而不是表本身。删除全部行,表也还在。而且这个删是逐行删 //因此建议使用 TRUNCATE TABLE来删除所有行,实际过程是删除表后,新建一个,而不是逐行删数据
20.3 更新和删除的指导原则
如果执行UPDATE而不带WHERE子句,则表中每个行都将用新值更新。类似地,如果执行DELETE语句而不带WHERE子句,表的所有数据都将被删除。由于没有undo(撤销)按钮,所以请谨慎使用UPDATE和DELETE。
第21章 创建和操纵表
21.1 创建表
21.1.1 创建表基础
CREATE TABLE customers(cust_id int NOT NULL AUTO_INCREMENT, cust_name char(50) NOT NULL, cust_city char(50) NOT NULL, cust_State char(50) NULL, PRIMARY KEY(cust_id) )ENGINE = InnoDB; //创建新表时,如果表名已经存在,就会覆盖 //最好是手工删除该表,然后重建,而不是简单的创建表覆盖 //如果仅想在表不存在时创建,应该在表名后跟一个IF NOT EXISTS
21.1.2 使用NULL值
如同21.1.1的例子,都家了关键字NOT NULL,这将会阻止插入没有值的列,返回错误,并插入失败。并且在创建表时,默认是NULL,NOT NULL需要指定。
21.1.3 主键再介绍
主键是可有由多个列组成的
PRIMARY KEY(order_num,order_item) 就表示有两个列组成这个表的主键
21.1.4 使用AUTO_INCREMENT
如同21.1.1的例子创建时使用了该关键字
AUTO_INCREMENT告诉MySQL,本列每当增加一行时自动增量。每次执行一个INSERT操作时,MySQL自动对该列增量(从而才有这个关键字AUTO_INCREMENT),给该列赋予下一个可用的值。这样给每个行分配一个唯一的cust_id,从而可以用作主键值。
并且该值从1开始增长,当你把第一条记录删除时,再插入第二条数据时,主键值是2,不是1。
21.1.5 指定默认值
//DEFAULT关键字 CREATE TABLE customers(cust_id int NOT NULL AUTO_INCREMENT, cust_name char(50) NOT NULL, cust_city char(50) NOT NULL DEFAULT 1, cust_State char(50) NULL, PRIMARY KEY(cust_id) )ENGINE = InnoDB;
21.1.6 引擎类型
MySQL具有多种引擎:
InnoDB是一个可靠的事务处理引擎(参见第26章),它不支持全文本搜索;
MEMORY在功能等同于MyISAM,但由于数据存储在内存(不是磁盘)中,速度很快(特别适合于临时表);
MyISAM是一个性能极高的引擎,它支持全文本搜索(参见第18章),但不支持事务处理。
外键不能跨引擎,也就是说,一个引擎的表不能引用使用了其他引擎的表的外键。
21.2 更新表
//添加列 ALTER TABLE vendors ADD vend_phone CHAR(20); //删除列 ALTER TABLE vendors DROP COLUMN vend_phone; //ALTER TABLE一种常见的用途是定义外键 alter table 需要建立外键的表 add constraint 外键名 foreign key (需要建立外键的字段名) references 外键表(外键字段)
21.3 删除表
DROP TABLE customer2;
21.4 重命名表
RENAME TABLE customer2 TO aaa; //对多个表重命名 RENAME TABLE customer2 TO aaa, bb TO cc, DD to ee;
第22章 使用视图
22.1 视图
视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态检索数据的查询。
//第15章的例子 SELECT cust_name,cust_contact FROM customers,orders,orderitems WHERE orders.cust_id = customers.cust_id AND orderitems.order_num = orders.order_num AND prod_id = 'TNT2'; //可以看到,需要这个数据的人,必须了解相关表的结构,并知道如何创建查询和对表进行联结。 //而视图就是为了简化这个行为
22.1.1 为什么使用视图
重用SQL语句。
简化复杂的SQL操作。在编写查询后,可以方便地重用它而不必知道它的基本查询细节。
使用表的组成部分而不是整个表。
保护数据。可以给用户授予表的特定部分的访问权限而不是整个的访问权限。
更改数据格式和表示。视图可返回与底层表的表示和格式不同的数据。
22.1.2 视图的规则和限制
与表一样,视图必须唯一命名(不能给视图取与别的视图或表相同的名字)。
对于可以创建的视图数目没有限制。
为了创建视图,必须具有足够的访问权限。这些限制通常由数据库管理人员授予。
视图可以嵌套,即可以利用从其他视图中检索数据的查询来构造一个视图。
ORDER BY可以用在视图中,但如果从该视图检索数据SELECT中也含有ORDER BY,那么该视图中的ORDER BY将被覆盖。
视图不能索引,也不能有关联的触发器或默认值。
视图可以和表一起使用。例如,编写一条联结表和视图的SELECT语句。
22.2 使用视图
视图用CREATE VIEW语句来创建。
使用SHOW CREATE VIEW viewname;来查看创建视图的语句。
用DROP删除视图,其语法为DROP VIEW viewname;。
22.2.1 利用视图简化复杂的联结
CREATE VIEW productcustomers AS SELECT cust_name,cust_contact,prod_id FROM customers,orders,orderitems WHERE customers.cust_id = order.cust_id AND orderitems.order_num = order.order_num //这创建了一个视图,联结了三个表。 //换句话说,这个视图里有三个表的部分数据,以后可以直接从这个视图查某些数据 //比如 SELECT cust_name,cust_contact FROM productcustomers WHERE prod_id = 'TNT2'; //这就是从视图中检索特定的数据(prod_id的数据在视图中)
22.2.2 用视图重新格式化检索出的数据(视图又一功能)
也就是说,如果经常使用一些联结时,可以把这些转换成视图,以后就不用每次查询,直接使用转换过的视图就可以了。
22.2.3 用视图过滤不想要的数据
22.2.4 使用视图与计算字段
22.2.5 更新视图
视图是可以进行更新的,但不是所有的都可以(并且大部分都不能更新)。应该注意的是,视图主要用于数据检索。
有如下操作,则不能更新视图:
分组(使用GROUP BY和HAVING);
联结;
子查询;
并;
聚集函数(Min()、Count()、Sum()等);
DISTINCT;
导出(计算)列。