《MySQL必知必会》--第16-20章

本文深入讲解了MySQL的高级操作,包括使用表别名简化SQL语句,执行自联结、自然联结和外部联结等不同类型的联结。此外,还详细介绍了全文本搜索功能,包括启用支持、进行搜索及使用查询扩展。同时,涵盖了数据插入的多种方式,如插入完整行、多行及查询结果。最后,阐述了如何更新和删除数据,并给出了相关操作的指导原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第16章--创建高级联结

16.1 使用表别名

别名除了用于列名和计算字段外,SQL还允许给表名起别名。这样做有两个主要理由:
  • 缩短SQL语句。
  • 允许在单条SELECT语句中多次使用相同的表。
应该注意,表别名只在查询执行中使用。与列别名不一样,表别名不返回到客户机。

16.2 使用不同类型的联结

迄今为止,我们使用的只是称为内部联结或等值联结(equijoin)的简单联结。现在来看3种其他联结,它们分别是自联结、自然联结和外部联结。

16.2.1 自联结

例子参考书籍
用自联结而不用子查询 自联结通常作为外部语句用来替代从相同表中检索数据时使用的子查询语句。虽然最终的结果是相同的,但有时候处理联结远比处理子查询快得多。应该试一下两种方法,以确定哪一种的性能更好。

16.2.2 自然联结

参考书籍

16.2.3 外部联结

参考书籍

第17章--组合查询

本章讲述如何利用UNION操作符将多条SELECT语句组合成一个结果
集。

第18章--全文本搜索

并非所有引擎都支持全文本搜索 正如第21章所述,MySQL支持几种基本的数据库引擎。并非所有的引擎都支持本书所描述的全文本搜索。两个最常使用的引擎为MyISAM和InnoDB,前者支持全文本搜索,而后者不支持。这就是为什么虽然本书中创建的多数样例表使用InnoDB , 而有一个样例表(productnotes表)却使用MyISAM的原因。如果你的应用中需要全文本搜索功能,应该记住这一点。
通配符和正则表达式的搜索机制非常有用,但存在几个重要的限制。
  • 性能——通配符和正则表达式匹配通常要求MySQL尝试匹配表中所有行(而且这些搜索极少使用表索引)。因此,由于被搜索行数不断增加,这些搜索可能非常耗时。
  • 明确控制——使用通配符和正则表达式匹配,很难(而且并不总是能)明确地控制匹配什么和不匹配什么。例如,指定一个词必须匹配,一个词必须不匹配,而一个词仅在第一个词确实匹配的情况下才可以匹配或者才可以不匹配。
  • 智能化的结果——虽然基于通配符和正则表达式的搜索提供了非常灵活的搜索,但它们都不能提供一种智能化的选择结果的方法。例如,一个特殊词的搜索将会返回包含该词的所有行,而不区分包含单个匹配的行和包含多个匹配的行(按照可能是更好的匹配来排列它们)。类似,一个特殊词的搜索将不会找出不包含该词但包含其他相关词的行。
所有这些限制以及更多的限制都可以用全文本搜索来解决。在使用全文本搜索时,MySQL不需要分别查看每个行,不需要分别分析和处理每个词。MySQL创建指定列中各词的一个索引,搜索可以针对这些词进行。这样,MySQL可以快速有效地决定哪些词匹配(哪些行包含它们),哪些词不匹配,它们匹配的频率,等等。

18.2 使用全文本搜索

为了进行全文本搜索,必须索引被搜索的列,而且要随着数据的改变不断地重新索引。在对表列进行适当设计后,MySQL会自动进行所有的索引和重新索引。
在索引之后,SELECT可与Match()和Against()一起使用以实际执行搜索。

18.2.1 启用全文本搜索支持

一般在创建表时启用全文本搜索。CREATE TABLE语句(第21章中介绍)接受FULLTEXT子句,它给出被索引列的一个逗号分隔的列表。下面的CREATE语句演示了FULLTEXT子句的使用:
CREATE TABLE productnots (
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;
不要在导入数据时使用FULLTEXT 更新索引要花时间,虽然不是很多,但毕竟要花时间。如果正在导入数据到一个新表,此时不应该启用FULLTEXT索引。应该首先导入所有数据,然后再修改表,定义FULLTEXT。这样有助于更快地导入数据(而且使索引数据的总时间小于在导入每行时分别进行索引所需的总时间)。

18.2.2 进行全文本搜索

在索引之后,使用两个函数Match()和Against()执行全文本搜索,其中Match()指定被搜索的列,Against()指定要使用的搜索表达式。
SELECT
*
FROM
productnots
WHERE
MATCH (note_text) AGAINST ('rabbit')
此SELECT语句检索单个列note_text。由于WHERE子句,一个全文本搜索被执行。Match(note_text)指示MySQL针对指定的列进行搜索,Against('rabbit')指定词rabbit作为搜索文本。
使用完整的Match() 说明 传递给Match() 的值必须与FULLTEXT()定义中的相同。如果指定多个列,则必须列出它们(而且次序正确)。
搜索不区分大小写 除非使用BINARY方式(本章中没有介绍),否则全文本搜索不区分大小写。
全文本搜索的一个重要部分就是对结果排序。具有较高等级的行先返回(因为这些行很可能是你真正想要的行)。

18.2.3 使用查询扩展

SELECT
*
FROM
productnots
WHERE
MATCH (note_text) AGAINST ('rabbit' with query expansion);
有点意思,参考书籍
18.2.4 布尔文本搜索

第19章--插入数据

19.1 数据插入

插入可
以用几种方式使用:
  • 插入完整的行;
  • 插入行的一部分;
  • 插入多行;
  • 插入某些查询的结果。

19.2 插入完整的行

insert语句如果不标明字段名称的话,不安全,应该尽量避免使用。这种SQL语句高度依赖于表中列的定义次序,并且还依赖于其次序容易获得的信息。即使可得到这种次序信息,也不能保证下一次表结构变动后各个列
保持完全相同的次序。因此,编写依赖于特定列次序的SQL语句是很不安全的。如果这样做,有时难免会出问题。
总是使用列的列表 一般不要使用没有明确给出列的列表的INSERT语句。使用列的列表能使SQL代码继续发挥作用,即使表结构发生了变化。
提高整体性能 数据库经常被多个客户访问,对处理什么请求以及用什么次序处理进行管理是MySQL的任务。INSERT操作可能很耗时(特别是有很多索引需要更新时),而且它可能降低等待处理的SELECT语句的性能。
如果数据检索是最重要的(通常是这样),则你可以通过在INSERT和INTO之间添加关键字LOW_PRIORITY,指示MySQL降低INSERT语句的优先级,如下所示:
INSERT LOW_PRIORITY INTO
顺便说一下,这也适用于下一章介绍的UPDATE和DELETE语句。

19.3 插入多个行

其中单条INSERT语句有多组值,每组值用一对圆括号括起来,用逗号分隔。
提高INSERT的性能 此技术可以提高数据库处理的性能,因为MySQL用单条INSERT语句处理多个插入比使用多条INSERT语句快。

19.4 插入检索出的数据

INSERT一般用来给表插入一个指定列值的行。但是,INSERT还存在另一种形式,可以利用它将一条SELECT语句的结果插入表中。这就是所谓的INSERT SELECT,顾名思义,它是由一条INSERT语句和一条SELECT语句组成的。
假如你想从另一表中合并客户列表到你的customers表。不需要每次读取一行,然后再将它用INSERT插入,可以如下进行:
INSERT INTO customers (
cust_id,
cust_contact,
cust_email,
cust_name,
cust_address,
cust_address,
cust_city,
cust_state,
cust_zip,
cust_country
) SELECT
cust_id,
cust_contact,
cust_email,
cust_name,
cust_address,
cust_address,
cust_city,
cust_state,
cust_zip,
cust_country
FROM
custnew
这个例子导入了cust_id(假设你能够确保cust_id的值不重复)。你也可以简单地省略这列(从INSERT和SELECT中),这样MySQL就会生成新值。
INSERT SELECT中的列名 为简单起见,这个例子在INSERT和SELECT语句中使用了相同的列名。但是,不一定要求列名匹配。事实上,MySQL甚至不关心SELECT返回的列名。它使用的是列的位置,因此SELECT中的第一列(不管其列名)将用来填充表列中指定的第一个列,第二列将用来填充表列中指定的第二个列,如此等等。这对于从使用不同列名的表中导入数据是非常有用的。

第20章--更新和删除数据

20.1 更新数据

不要省略WHERE子句 在使用UPDATE时一定要注意细心。因为稍不注意,就会更新表中所有行。在使用这条语句前,请完整地阅读本节。
IGNORE关键字 如果用UPDATE语句更新多行,并且在更新这些行中的一行或多行时出一个现错误,则整个UPDATE操作被取消(错误发生前更新的所有行被恢复到它们原来的值)。为即使是发生错误,也继续进行更新,可使用IGNORE关键字,如下所示:
UPDATE IGNORE customers…

20.2 删除数据

更快的删除 如果想从表中删除所有行,不要使用DELETE。可使用TRUNCATE TABLE语句,它完成相同的工作,但速度更快(TRUNCATE实际是删除原来的表并重新创建一个表,而不是逐行删除表中的数据)。

20.3 更新和删除的指导原则

下面是许多SQL程序员使用UPDATE或DELETE时所遵循的习惯。
除非确实打算更新和删除每一行,否则绝对不要使用不带WHERE子句的UPDATE或DELETE语句。
保证每个表都有主键(如果忘记这个内容,请参阅第15章),尽可能像WHERE子句那样使用它(可以指定各主键、多个值或值的范围)。
在对UPDATE或DELETE语句使用WHERE子句前,应该先用SELECT进行测试,保证它过滤的是正确的记录,以防编写的WHERE子句不正确。
使用强制实施引用完整性的数据库(关于这个内容,请参阅第15章),这样MySQL将不允许删除具有与其他表相关联的数据的行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值