MySQL必知必会最新.pdf
http://www.100md.com
2020年11月15日
![]() |
| 第1页 |
![]() |
| 第7页 |
![]() |
| 第19页 |
![]() |
| 第29页 |
![]() |
| 第47页 |
![]() |
| 第220页 |
参见附件(7014KB,258页)。
MySQL必知必会从介绍简单的数据检索开始,逐步深入一些复杂的内容,包括联结的使用、子查询、正则表达式和基于全文本的搜索、存储过程、游标、触发器、表约束,等等。通过重点突出的章节,条理清晰、系统而扼要地讲述了读者应该掌握的知识,使他们不经意间立刻功力大增。

编辑推荐
MySQL作为开源软件的代表,已经成为世界上受欢迎的数据库管理系统之一。
《MySQL必知必会》是经典畅销书《SQL必知必会》之后,作者应众多读者的请求编写的,专门针对MySQL用户。书中继承了《MySQL必知必会》的优点,没有过多阐述数据库基础理论,而是紧贴实战需要,直接从数据检索开始,逐步深入各种复杂的内容,包括联结的使用、子查询、正则表达式和基于全文本的搜索、存储过程、游标、触发器、表约束,等等。通过本书,读者能够掌握扎实的基本功,迅速成为MySQL高手。
作者简介
Ben Forta,世界知名的技术作家,也是Adobe技术界知名的专家之一,目前担任Adobe公司的技术推广专家。他具有计算机行业20多年工作经验,多年来撰写了十几本技术图书,包括《正则表达式必知必会》、《SQL必知必会》(人民邮电出版社出版)等世界性的畅销书,已被翻译为十几种文字。
本书读者对象
读者对象
本书的读者对象是这样一些人:
他没有学过SQL
他刚开始用MySQL,并希望一举成功
他想迅速地、尽可能多地学会使用MySQL
他希望学习怎样在自己的应用程序开发中使用MySQL
他希望通过使用MySOL轻松快速地提高工作效率,而不用劳烦他人帮忙
什么是MySQL
正如所述,数据的所有存储、检索、管理和处理实际上是由数据库软件-DBMS(数据库管理系统)
完成的。MySQL是一种DBMS,即它是一种数据库软件。
MySQL已经存在很久了,它在世界范围内得到了广泛的安装和使用。为什么有那么多的公司和开发人员使用MySQL?以下列出其原因。口成本-MySQL是开放源代码的,一般可以使用(甚至可以修改)。
性能--MySQL执行很快(非常快)。
可信赖-某些非常重要和声望很高的公司、站点使用MySQL,这些公司和站点都用MySQL来处理自己的重要数据。
简单-MySQL很容易安装和使用。
事实上,MySQL受到的唯一真正的批评是它并不总是支持其他DBMS提供的功能和特性。然而,这一点也正在逐步得到改善,MySQL的各个新版本正不断增加新特性、新功能。
MySQL必知必会截图




图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com内 容 提 要
MySQL 是世界上最受欢迎的数据库管理系统之一。书中从介绍简单的数据
检索开始,逐步深入一些复杂的内容,包括联结的使用、子查询、正则表达式
和基于全文本的搜索、存储过程、游标、触发器、表约束,等等。通过重点突
出的章节,条理清晰、系统而扼要地讲述了读者应该掌握的知识,使他们不经
意间立刻功力大增。
本书注重实用性,操作性很强,适用于广大软件开发和数据库管理人员学
习参考。
图灵程序设计丛书
著 [ 英] Ben Forta
译 刘晓霞 钟 鸣
责任编辑 傅志红
执行编辑 刘 静
人民邮电出版社出版发行 北京市崇文区夕照寺街14号
邮编 100061 电子函件 315@ptpress.com.cn
网址 http:www.ptpress.com.cn
北京 印刷
开本:850×1168 132
印张:8
字数:246千字 2009年 1 月第 1 版
印数:1 — 4 000册 2009年 1 月北京第 1 次印刷
著作权合同登记号 图字:01-2008-4295号
MySQL必知必会
ISBN 978-7-115-19112-0TP
定价:39.00元
读者服务热线:(010)88593802 印装质量热线:(010)67129223
反盗版热线:(010)67171154
◆
◆
◆
图书在版编目(CIP)数据
MySQL必知必会 (英)福塔(Forta, B.)著;刘晓霞,钟鸣译. —北京:人民邮电出版社,2009.1
(图灵程序设计丛书)
书名原文:MySQL Crash Course
ISBN 978-7-115-19112-0
Ⅰ . M… Ⅱ.①福… ②刘… ③钟 Ⅲ. 关系数据库 — 数
据库管理系统,MySQL Ⅳ. TP311.138
中国版本图书馆CIP数据核字(2008)第159272号
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
版 权 声 明
Authorized translation from the English language edition, entitled
MySQL Crash Course, 0672327120 by Ben Forta, published by Pearson
Education, Inc., publishing as Sams. Copyright ? 2006 by Sams Publishing.
All rights reserved. No part of this book may be reproduced or
transmitted in any form or by any means, electronic or mechanical, including
photocopying, recording or by any information storage retrieval system,without permission from Pearson Education, Inc.
Simplified Chinese-language edition copyright ? 2009 by Posts
Telecom Press. All rights reserved.
本书中文简体字版由 Pearson Education Inc.授权人民邮电出版社独
家出版。未经出版者书面许可,不得以任何方式复制或抄袭本书内容。
版权所有,侵权必究。
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
致 谢
首先,我要感谢Sams出版公司的伙伴们,他们再一次给了我灵活的
自由度,让我把书写成我认为合适的样子。谢谢Mark Renfrow提供的关于
本书和前面几本书的反馈意见。特别感谢Loretta Yates不仅在中途勇敢地
介入到出版过程中,使其回归正轨,继续进行,而且还果断地签署了本
系列书中后两部书籍的出版合约。
谢谢Jochem van Dieten和Timothy Boronczyk这两位技术编辑,他们对
书稿进行了出色的技术审查。余下的那些“错误”都是我“故意”犯的,就是想看看读者们有没有注意到。:-)
最后,本书是应《SQL必知必会》读者的请求编写的。那本书收到了
很多极有价值的反馈意见和建议,在此我深表谢意。谢谢大家,我希望
自己达到了大家的期望。
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
前 言
MySQL已经成为世界上最受欢迎的数据库管理系统之一。无论是用
在小型开发项目上,还是用来构建那些声名显赫的网站,MySQL都证明
了自己是个稳定、可靠、快速、可信的系统,足以胜任任何数据存储业
务的需要。
本书基于我的一本畅销书Sams Teach Yourself SQL in 10 Minutes (中文
版《SQL必知必会》 ,人民邮电出版社出版),那本书堪称全世界用得最
多的一本SQL教程,重点讲解读者必须知道的东西,条理清晰,系统而
扼要。但是,即使是那样一本广为使用的成功的书,也还存在着以下这
些局限性。
· 由于要面向所有主要的数据库管理系统(DBMS) ,我不得不把针
对具体DBMS的内容一再压缩。
· 为了简化SQL的讲解,我必须(尽可能)只写各种主要的DBMS
通用的SQL语句。这要求我不得不舍弃一些更好的、针对具体
DBMS的解决方案。
· 虽然基本的SQL在不同的DBMS间具有较好的可移植性,但是高
级的SQL显然不是这样的。因此,那本书里无法详细讲解比较高
级的内容,如触发器、游标、存储过程、访问控制、事务等。
于是就有了这本书。本书沿用了前一本书业已成功的教程模式和组
织结构,除了MySQL以外,不在其他内容上过多纠缠。书从简单的数据
检索开始,逐步进入一些复杂的内容,包括联结的使用、子查询、正则
1
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com2 前 言
表达式和基于全文本的搜索、存储过程、游标、触发器、表约束,等等。
通过重点突出的章节,条理清晰、系统而扼要地让读者学到应该学到的
知识,使他们不经意间立刻功力大增。
请先到第1章开始学习。读者会立刻体会到MySQL提供的所有好处。
读者对象
本书的读者对象是这样一些人:
· 他没有学过SQL;
· 他刚开始用MySQL,并希望一举成功;
· 他想迅速地、尽可能多地学会使用MySQL;
· 他希望学习怎样在自己的应用程序开发中使用MySQL;
· 他希望通过使用MySQL轻松快速地提高工作效率,而不用劳烦他
人帮忙。
配套网站
本书有一个配套网站,网址是:http:forta.combooks0672327120。
读者可以通过该网站访问如下内容:
· 表格创建和表格填充的脚本,可用来创建书中使用的样例表;
· 在线支持论坛;
· 在线勘误(如果发现了勘误的话) ;
· 或许他会感兴趣的其他书。
本书约定
本书使用不同的字体区分代码和一般正文内容,对于重要的概念也
采用特殊的字体。
键入的文本和屏幕上显示出的文本用等宽代码字体表示。如:It
looks like this to mimic the way text looks on your screen.
2
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com前 言 3
一行代码最前面如果出现箭头(?)表示该行代码较长,书中一行放
不下。读者录入时需要把这一行的内容紧接着上一行输入。
说明:表示跟上下文的内容相关的一些有意思的信息。
提示:提供建议,教读者用容易的办法完成某项任务。
注意:向读者提示可能出现的问题,避免不必要的麻烦。
新术语,提供新的基本词汇的清晰定义。
表示读者自己键入的代码。通常出现在程序清单的旁边。
表示运行MySQL代码后得到的结果,通常出现在程序清单之后。
告诉读者这是作者对输入或输出的逐行分析。
输出
分析
输入
3
4
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
目 录
第1章 了解SQL............................
1
1.1 数据库基础.............................
1
1.1.1 什么是数据库.............
2
1.1.2 表.................................
2
1.1.3 列和数据类型.............
3
1.1.4 行.................................
4
1.1.5 主键.............................
4
1.2 什么是SQL .............................
5
1.3 动手实践.................................
6
1.4 小结.........................................
7
第2章 MySQL简介......................
8
2.1 什么是MySQL........................
8
2.1.1 客户机—服务器软件...
8
2.1.2 MySQL版本...............
9
2.2 MySQL工具..........................
10
2.2.1 mysql命令行实用
程序..........................
11
2.2.2 MySQL Adminis-
trator .........................
12
2.2.3 MySQL Query
Browser.....................
13
2.3 小结.......................................
14
第3章 使用MySQL....................
15
3.1 连接.......................................
15
3.2 选择数据库...........................
16
3.3 了解数据库和表...................
17
3.4 小结.......................................
19
第4章 检索数据..........................
20
4.1 SELECT语句.........................
20
4.2 检索单个列...........................
20
4.3 检索多个列...........................
22
4.4 检索所有列...........................
23
4.5 检索不同的行.......................
24
4.6 限制结果...............................
25
4.7 使用完全限定的表名...........
26
4.8 小结......................................
27
第5章 排序检索数据.................
28
5.1 排序数据...............................
28
5.2 按多个列排序.......................
30
5.3 指定排序方向.......................
31
5.4 小结......................................
33
第6章 过滤数据..........................
34
6.1 使用WHERE子句....................
34
6.2 WHERE子句操作符.................
35
6.2.1 检查单个值..............
36
6.2.2 不匹配检查..............
37
6.2.3 范围值检查..............
37
6.2.4 空值检查..................
38
6.3 小结......................................
39
第7章 数据过滤..........................
40
7.1 组合WHERE子句....................
40
7.1.1 AND操作符................
40
7.1.2 OR操作符..................
41
7.1.3 计算次序..................
42
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com2 目 录
7.2 IN操作符...............................
43
7.3 NOT操作符.............................
44
7.4 小结.......................................
45
第8章 用通配符进行过滤.........
46
8.1 LIKE操作符...........................
46
8.1.1 百分号(%)通配符...
47
8.1.2 下划线(_)通配符...
48
8.2 使用通配符的技巧................
49
8.3 小结.......................................
50
第9章 用正则表达式进行搜索...
51
9.1 正则表达式介绍...................
51
9.2 使用MySQL正则表达式.......
52
9.2.1 基本字符匹配...........
52
9.2.2 进行OR匹配..............
54
9.2.3 匹配几个字符之一...
54
9.2.4 匹配范围...................
55
9.2.5 匹配特殊字符...........
56
9.2.6 匹配字符类...............
58
9.2.7 匹配多个实例...........
58
9.2.8 定位符.......................
59
9.3 小结.......................................
61
第10章 创建计算字段...............
62
10.1 计算字段.............................
62
10.2 拼接字段.............................
63
10.3 执行算术计算.....................
66
10.4 小结.....................................
67
第11章 使用数据处理函数.......
68
11.1 函数.....................................
68
11.2 使用函数.............................
68
11.2.1 文本处理函数.......
69
11.2.2 日期和时间处理
函数.......................
71
11.2.3 数值处理函数.......
74
11.3 小结.....................................
74
第12章 汇总数据........................
75
12.1 聚集函数.............................
75
12.1.1 AVG函数............
76
12.1.2 COUNT函数........
77
12.1.3 MAX函数............
78
12.1.4 MIN函数............
79
12.1.5 SUM函数............
79
12.2 聚集不同值.........................
80
12.3 组合聚集函数.....................
81
12.4 小结.....................................
82
第13章 分组数据........................
83
13.1 数据分组.............................
83
13.2 创建分组.............................
83
13.3 过滤分组.............................
85
13.4 分组和排序.........................
87
13.5 SELECT子句顺序.................
88
13.6 小结.....................................
89
第14章 使用子查询...................
90
14.1 子查询.................................
90
14.2 利用子查询进行过滤..........
90
14.3 作为计算字段使用
子查询................................
93
14.4 小结.....................................
96
第15章 联结表............................
97
15.1 联结.....................................
97
15.1.1 关系表..................
97
15.1.2 为什么要使用
联结......................
99
15.2 创建联结.............................
99
15.2.1 WHERE子句的
重要性....................
100
15.2.2 内部联结............
103
15.2.3 联结多个表........
104
15.3 小结...................................
105
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com目 录 3
第16章 创建高级联结.............
106
16.1 使用表别名.......................
106
16.2 使用不同类型的联结.......
107
16.2.1 自联结................
107
16.2.2 自然联结............
109
16.2.3 外部联结............
109
16.3 使用带聚集函数的联结....
111
16.4 使用联结和联结条件.......
112
16.5 小结...................................
112
第17章 组合查询.....................
113
17.1 组合查询...........................
113
17.2 创建组合查询...................
113
17.2.1 使用UNION .........
114
17.2.2 UNION规则.........
115
17.2.3 包含或取消重复
的行....................
116
17.2.4 对组合查询结果
排序....................
117
17.3 小结...................................
118
第18章 全文本搜索.................
119
18.1 理解全文本搜索...............
119
18.2 使用全文本搜索...............
120
18.2.1 启用全文本搜索
支持....................
120
18.2.2 进行全文本
搜索....................
121
18.2.3 使用查询扩展....
124
18.2.4 布尔文本搜索....
126
18.2.5 全文本搜索的
使用说明............
129
18.3 小结...................................
130
第19章 插入数据.....................
131
19.1 数据插入...........................
131
19.2 插入完整的行...................
131
19.3 插入多个行.......................
134
19.4 插入检索出的数据...........
136
19.5 小结..................................
138
第20章 更新和删除数据........
139
20.1 更新数据...........................
139
20.2 删除数据...........................
141
20.3 更新和删除的指导原则.....
142
20.4 小结..................................
143
第21章 创建和操纵表.............
144
21.1 创建表...............................
144
21.1.1 表创建基础........
144
21.1.2 使用NULL值.......
146
21.1.3 主键再介绍........
147
21.1.4 使用AUTO_
INCREMENT.........
148
21.1.5 指定默认值........
149
21.1.6 引擎类型............
150
21.2 更新表...............................
151
21.3 删除表...............................
153
21.4 重命名表...........................
153
21.5 小结..................................
154
第22章 使用视图.....................
155
22.1 视图..................................
155
22.1.1 为什么使用
视图...................
156
22.1.2 视图的规则和
限制...................
157
22.2 使用视图...........................
157
22.2.1 利用视图简化
复杂的联结........
157
22.2.2 用视图重新格式化
检索出的数据....
158
22.2.3 用视图过滤不
想要的数据........
159
22.2.4 使用视图与计算
字段...................
160
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com4 目 录
22.2.5 更新视图............
161
22.3 小结...................................
162
第23章 使用存储过程.............
163
23.1 存储过程...........................
163
23.2 为什么要使用存储过程....
164
23.3 使用存储过程...................
165
23.3.1 执行存储过程......
165
23.3.2 创建存储过程......
165
23.3.3 删除存储过程......
167
23.3.4 使用参数..............
167
23.3.5 建立智能存储
过程.....................
170
23.3.6 检查存储过程......
173
23.4 小结...................................
173
第24章 使用游标......................
174
24.1 游标...................................
174
24.2 使用游标...........................
174
24.2.1 创建游标............
175
24.2.2 打开和关闭游标...
175
24.2.3 使用游标数据....
176
24.3 小结...................................
180
第25章 使用触发器.................
181
25.1 触发器...............................
181
25.2 创建触发器.......................
182
25.3 删除触发器.......................
183
25.4 使用触发器.......................
183
25.4.1 INSERT触发器....
183
25.4.2 DELETE触发器....
184
25.4.3 UPDATE触发器....
185
25.4.4 关于触发器的进
一步介绍............
186
25.5 小结...................................
186
第26章 管理事务处理.............
187
26.1 事务处理...........................
187
26.2 控制事务处理...................
189
26.2.1 使用ROLLBACK.....
189
26.2.2 使用COMMIT........
190
26.2.3 使用保留点........
191
26.2.4 更改默认的提交
行为....................
192
26.3 小结...................................
192
第27章 全球化和本地化.........
193
27.1 字符集和校对顺序............
193
27.2 使用字符集和校对顺序....
194
27.3 小结...................................
196
第28章 安全管理......................
197
28.1 访问控制...........................
197
28.2 管理用户...........................
198
28.2.1 创建用户账号....
199
28.2.2 删除用户账号....
200
28.2.3 设置访问权限....
200
28.2.4 更改口令............
203
28.3 小结...................................
204
第29章 数据库维护.................
205
29.1 备份数据...........................
205
29.2 进行数据库维护...............
206
29.3 诊断启动问题...................
207
29.4 查看日志文件...................
207
29.5 小结...................................
208
第30章 改善性能......................
209
30.1 改善性能...........................
209
30.2 小结...................................
211
附录A MySQL入门..................
212
附录B 样例表............................
214
附录C MySQL语句的语法.....
220
附录D MySQL数据类型.........
224
附录E MySQL保留字..............
228
索引 ................................................
232
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
了解SQL
本章将介绍数据库和SQL,它们是学习MySQL的先决条件。
1.1 数据库基础
你正在阅读本书,这表明你需要以某种方式与数据库打交道。在深
入学习MySQL及其SQL语言的实现之前,应该对数据库及数据库技术的
某些基本概念有所了解。
你可能还没有意识到,其实你自己一直在使用数据库。每当你从自
己的电子邮件地址簿里查找名字时,你就在使用数据库。如果你在某个
因特网搜索站点上进行搜索,也是在使用数据库。如果你在工作中登录
网络,也需要依靠数据库验证自己的名字和密码。即使是在自动取款机
上使用ATM卡,也要利用数据库进行PIN码验证和余额检查。
虽然我们一直都在使用数据库,但对究竟什么是数据库并不十分清
楚。特别是不同的人可能会使用相同的数据库术语表示不同的事物,更
加剧了这种混乱。因此,我们学习的良好切入点就是给出一张最重要的
数据库术语清单,并加以说明。
基本概念回顾 下面是某些基本数据库概念的简要介绍。如果
你已经具有一定的数据库经验,这可以用于复习巩固;如果你
是一个数据库新手,这将给你提供一些必需的基本知识。理解
数据库是掌握MySQL的一个重要部分,如果有必要的话,你
应该参阅一些有关数据库基础知识的书籍①。
① 推荐人民邮电出版社出版的由Kifer、Bernstein和Lewis合著的《数据库系统:面向应
用的方法》或Elmasri和Navathe合著的《数据库系统基础》。——编者注
第1章
5
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com2 第 1章 了解SQL
1.1.1 什么是数据库
数据库这个术语的用法很多,但就本书而言,数据库是一个以某种
有组织的方式存储的数据集合。理解数据库的一种最简单的办法是将其
想象为一个文件柜。此文件柜是一个存放数据的物理位置,不管数据是
什么以及如何组织的。
数据库(database) 保存有组织的数据的容器(通常是一个文
件或一组文件) 。
误用导致混淆 人们通常用数据库这个术语来代表他们使用
的数据库软件。这是不正确的,它是引起混淆的根源。确切
地说,数据库软件应称为DBMS(数据库管理系统)。数据库
是通过DBMS创建和操纵的容器。数据库可以是保存在硬设备
上的文件,但也可以不是。在很大程度上说,数据库究竟是
文件还是别的什么东西并不重要,因为你并不直接访问数据
库;你使用的是DBMS,它替你访问数据库。
1.1.2 表
在你将资料放入自己的文件柜时,并不是随便将它们扔进某个抽屉就完
事了,而是在文件柜中创建文件,然后将相关的资料放入特定的文件中。
在数据库领域中,这种文件称为表。表是一种结构化的文件,可用
来存储某种特定类型的数据。表可以保存顾客清单、产品目录,或者其
他信息清单。
表(table) 某种特定类型数据的结构化清单。
这里关键的一点在于,存储在表中的数据是一种类型的数据或一个
清单。决不应该将顾客的清单与订单的清单存储在同一个数据库表中。这
样做将使以后的检索和访问很困难。应该创建两个表,每个清单一个表。
数据库中的每个表都有一个名字,用来标识自己。此名字是唯一的,这表示数据库中没有其他表具有相同的名字。
6
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com1.1 数据库基础 3
表名 表名的唯一性取决于多个因素,如数据库名和表名等的
结合。 这表示,虽然在相同数据库中不能两次使用相同的表名,但在不同的数据库中却可以使用相同的表名。
表具有一些特性,这些特性定义了数据在表中如何存储,如可以存
储什么样的数据,数据如何分解,各部分信息如何命名,等等。描述表
的这组信息就是所谓的模式,模式可以用来描述数据库中特定的表以及
整个数据库(和其中表的关系) 。
模式(schema) 关于数据库和表的布局及特性的信息。
是模式还是数据库? 有时,模式用作数据库的同义词。遗憾
的是,模式的含义通常在上下文中并不是很清晰。本书中,模
式指的是上面给出的定义。
1.1.3 列和数据类型
表由列组成。列中存储着表中某部分的信息。
列(column) 表中的一个字段。所有表都是由一个或多个列组
成的。
理解列的最好办法是将数据库表想象为一个网格。网格中每一列存
储着一条特定的信息。例如,在顾客表中,一个列存储着顾客编号,另
一个列存储着顾客名,而地址、城市、州以及邮政编码全都存储在各自
的列中。
分解数据 正确地将数据分解为多个列极为重要。例如, 城市、州、邮政编码应该总是独立的列。通过把它分解开,才有可能
利用特定的列对数据进行排序和过滤(如,找出特定州或特定
城市的所有顾客) 。如果城市和州组合在一个列中,则按州进
行排序或过滤会很困难。
7
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com4 第 1章 了解SQL
数据库中每个列都有相应的数据类型。数据类型定义列可以存储的
数据种类。例如,如果列中存储的为数字(或许是订单中的物品数) ,则
相应的数据类型应该为数值类型。如果列中存储的是日期、文本、注释、金额等,则应该用恰当的数据类型规定出来。
数据类型(datatype) 所容许的数据的类型。每个表列都有相
应的数据类型,它限制(或容许)该列中存储的数据。
数据类型限制可存储在列中的数据种类(例如,防止在数值字段中
录入字符值) 。数据类型还帮助正确地排序数据,并在优化磁盘使用方面
起重要的作用。因此,在创建表时必须对数据类型给予特别的关注。
1.1.4 行
表中的数据是按行存储的,所保存的每个记录存储在自己的行内。
如果将表想象为网格,网格中垂直的列为表列,水平行为表行。
例如,顾客表可以每行存储一个顾客。表中的行数为记录的总数。
行(row) 表中的一个记录。
是记录还是行? 你可能听到用户在提到行(row)时称其为
数据库记录(record) 。在很大程度上,这两个术语是可以互相
替代的,但从技术上说,行才是正确的术语。
1.1.5 主键
表中每一行都应该有可以唯一标识自己的一列(或一组列) 。一个顾
客表可以使用顾客编号列,而订单表可以使用订单ID,雇员表可以使用
雇员ID或雇员社会保险号。
主键(primary key) ①一一列(或一组列),其值能够唯一区分表
中每个行。
① 全国科学技术名词审定委员会审定的key在数据库中的对应名词为“键码”或“码” ,本书采用了已约定俗成的“键”,请读者注意。——编者注
8
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com1.2 什么是SQL 5
唯一标识表中每行的这个列(或这组列)称为主键。主键用来表示
一个特定的行。没有主键,更新或删除表中特定行很困难,因为没有安
全的方法保证只涉及相关的行。
应该总是定义主键 虽然并不总是都需要主键,但大多数数据
库设计人员都应保证他们创建的每个表具有一个主键, 以便于
以后的数据操纵和管理。
表中的任何列都可以作为主键,只要它满足以下条件:
· 任意两行都不具有相同的主键值;
· 每个行都必须具有一个主键值(主键列不允许NULL值) 。
主键值规则 这里列出的规则是MySQL本身强制实施的。
主键通常定义在表的一列上,但这并不是必需的,也可以一起使用
多个列作为主键。在使用多列作为主键时,上述条件必须应用到构成主
键的所有列,所有列值的组合必须是唯一的(但单个列的值可以不唯一) 。
主键的最好习惯 除MySQL强制实施的规则外,应该坚持的
几个普遍认可的最好习惯为:
· 不更新主键列中的值;
· 不重用主键列的值;
· 不在主键列中使用可能会更改的值。(例如,如果使用一个
名字作为主键以标识某个供应商,当该供应商合并和更改其
名字时,必须更改这个主键。)
还有一种非常重要的键,称为外键,我们将在第15章中介绍。
1.2 什么是SQL
SQL (发音为字母S-Q-L或sequel) 是结构化查询语言 (Structured Query
Language)的缩写。SQL是一种专门用来与数据库通信的语言。
10
9
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com6 第 1章 了解SQL
与其他语言(如,英语以及Java和Visual Basic这样的程序设计语言)
不一样,SQL由很少的词构成,这是有意而为的。设计SQL的目的是很好
地完成一项任务,即提供一种从数据库中读写数据的简单有效的方法。
SQL有如下的优点。
· SQL不是某个特定数据库供应商专有的语言。几乎所有重要的
DBMS都支持SQL,所以,学习此语言使你几乎能与所有数据库
打交道。
· SQL简单易学。它的语句全都是由描述性很强的英语单词组成,而且这些单词的数目不多。
· SQL尽管看上去很简单,但它实际上是一种强有力的语言,灵活
使用其语言元素,可以进行非常复杂和高级的数据库操作。
DBMS专用的SQL SQL不是一种专利语言,而且存在一个标
准委员会,他们试图定义可供所有DBMS使用的SQL语法,但
事实上任意两个DBMS实现的SQL都不完全相同。本书讲授的
SQL是专门针对MySQL的,虽然书中所讲授的多数语法也适
用于其他DBMS,但不要认为这些SQL语法是完全可移植的。
1.3 动手实践
本书所有章节都采用可上机运行的例子来说明SQL语法,它的功能是
什么,为什么起这样的作用。作者强烈建议读者试验每个例子,以便掌
握MySQL的第一手资料。
附录B描述了本书中使用的样例表,说明如何获得和安装它们。如果
你还没有获得和安装它们,请在继续学习前先学习这个附录。
你需要MySQL 显然,你需要能访问某个MySQL副本,以便
学习本书的内容。附录A说明了在何处获得MySQL的副本,并
提供一定的入门指导。如果你已经能访问某个MySQL副本,在继续学习之前,也请阅读该附录。
11
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com1.4 小结 7
1.4 小结
这一章介绍了什么是SQL以及它为什么很有用。因为SQL是用来与数
据库打交道的,所以,我们也复习了一些基本的数据库术语。 12
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
MySQL简介
本章将介绍什么是MySQL,以及在MySQL中可以应用什么工具。
2.1 什么是MySQL
我们在前一章中介绍了数据库和SQL。正如所述,数据的所有存储、检索、管理和处理实际上是由数据库软件——DBMS(数据库管理系统)
完成的。MySQL是一种DBMS,即它是一种数据库软件。
MySQL已经存在很久了,它在世界范围内得到了广泛的安装和使用。
为什么有那么多的公司和开发人员使用MySQL?以下列出其原因。
· 成本——MySQL是开放源代码的,一般可以免费使用(甚至可以
免费修改) 。
· 性能——MySQL执行很快(非常快) 。
· 可信赖——某些非常重要和声望很高的公司、站点使用MySQL,这些公司和站点都用MySQL来处理自己的重要数据。
· 简单——MySQL很容易安装和使用。
事实上,MySQL受到的唯一真正的批评是它并不总是支持其他
DBMS提供的功能和特性。然而,这一点也正在逐步得到改善,MySQL
的各个新版本正不断增加新特性、新功能。
2.1.1 客户机—服务器软件
DBMS可分为两类:一类为基于共享文件系统的DBMS,另一类为基
于客户机—服务器的DBMS。 前者(包括诸如Microsoft Access和FileMaker)
第2章
13
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com2.1 什么是MySQL 9
用于桌面用途,通常不用于高端或更关键的应用。
MySQL、Oracle以及Microsoft SQL Server等数据库是基于客户机—服
务器的数据库。客户机—服务器应用分为两个不同的部分。服务器部分是
负责所有数据访问和处理的一个软件。这个软件运行在称为数据库服务
器的计算机上。
与数据文件打交道的只有服务器软件。关于数据、数据添加、删除
和数据更新的所有请求都由服务器软件完成。这些请求或更改来自运行
客户机软件的计算机。客户机是与用户打交道的软件。例如,如果你请
求一个按字母顺序列出的产品表,则客户机软件通过网络提交该请求给
服务器软件。服务器软件处理这个请求,根据需要过滤、丢弃和排序数
据;然后把结果送回到你的客户机软件。
有多少计算机? 客户机和服务器软件可能安装在两台计算
机或一台计算机上。不管它们在不在相同的计算机上,为进行
所有数据库交互,客户机软件都要与服务器软件进行通信。
所有这些活动对用户都是透明的。数据存储在别的地方,或者数据
库服务器为你完成这个处理这一事实是隐藏的。你不需要直接访问数据
文件。事实上,多数网络的建立使用户不具有对数据的访问权,甚至不
具有对存储数据的驱动器的访问权。
这样的意义何在?因为为了使用MySQL,你需要访问运行MySQL服
务器软件的计算机和发布命令到MySQL的客户机软件的计算机。
· 服务器软件为MySQL DBMS。你可以在本地安装的副本上运行,也可以连接到运行在你具有访问权的远程服务器上的一个副本。
· 客户机可以是MySQL提供的工具、脚本语言(如Perl)、Web应用
开发语言(如ASP、ColdFusion、JSP和PHP) 、程序设计语言(如
C、C++、Java)等。
2.1.2 MySQL版本
客户机工具稍后介绍。我们先简要介绍DBMS版本。
14
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com10 第 2章 MySQL简介
MySQL的当前版本为版本5① (虽然许多公司正在使用MySQL 3和4)。
下面是最近版本中引入的主要更改。
· 4——InnoDB引擎,增加事务处理(第26章) 、并(第17章)、改
进全文本搜索(第18章)等的支持。
· 4.1——对函数库、子查询(第14章) 、集成帮助等的重要增加。
· 5——存储过程(第23章) 、触发器(第25章) 、游标(第24章) 、视图(第22章)等。
版本4.1和版本5对MySQL增加了重要的功能,本书中涵盖了这些功
能的大多数。
使用4.1或更高版本 MySQL 4.1对MySQL函数库引入了重要
更改,本书是为使用此版本或更高版本而撰写的。多数内容实
际上也适用于MySQL 3和4,不过许多例子在这两个版本中不
工作。
版本要求说明 如果某章针对具体某个MySQL版本,则将在
该章开始处明确说明。
2.2 MySQL工具
如前所述,MySQL是一个客户机—服务器DBMS,因此,为了使用
MySQL,需要有一个客户机,即你需要用来与MySQL打交道(给MySQL
提供要执行的命令)的一个应用。
有许多客户机应用可供选择,但在学习MySQL(确切地说,在编写
和测试MySQL脚本时),最好是使用专门用途的实用程序。特别是有3个
工具需要提及。
① 目前最新的稳定版本为5.1。——编者注
15
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com2.2 MySQL 工具 11
2.2.1 mysql命令行实用程序
每个MySQL安装都有一个名为mysql的简单命令行实用程序。这
个实用程序没有下拉菜单、流行的用户界面、鼠标支持或任何类似的
东西。
在操作系统命令提示符下输入mysql将出现一个如下的简单提示:
MySQL选项和参数 如果仅输入mysql, 可能会出现一个错误
消息。因为可能需要安全证书,或者是因为MySQL没有运行
在本地或默认端口上。mysql接受你可以(和可能需要)使用
的一组命令行参数。例如,为了指定用户登录名ben,应该使
用mysql -u ben。为了给出用户名、主机名、端口和口令,应该使用mysql -u ben -p -h myserver -P 9999。
完整的命令行选项和参数列表可用mysql --help获得。
当然,具体的版本和连接信息可能不同,但都可以使用这个实用程
序。请注意:
· 命令输入在mysql>之后;
· 命令用;或\g结束,换句话说,仅按Enter不执行命令;
· 输入help或\h获得帮助,也可以输入更多的文本获得特定命令的
帮助(如,输入help select获得使用SELECT语句的帮助) ;
· 输入quit或exit退出命令行实用程序。
mysql命令行实用程序是使用最多的实用程序之一,它对于快速测试
和执行脚本(如前一章和附录B中的样例表创建和填充脚本)非常有价
值。事实上,本书中使用的所有输出例子都是从mysql命令行输出中抓取
的。
16
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com12 第 2章 MySQL简介
熟悉mysql命令行实用程序 即使你选择使用后面描述的某
个图形工具,也应该保证熟悉mysql命令行实用程序,因为它
是你可以安全地依靠的一个总是会被给出的客户机 (因为它是
核心MySQL安装的一部分) 。
2.2.2 MySQL Administrator
MySQL Administrator(MySQL管理器)是一个图形交互客户机,用
来简化MySQL服务器的管理。
获得MySQL Administrator MySQL Administrator不作为核心
MySQL 的组成部分安装。必须从 http:dev.mysql.com
downloads下载它(可得到用于Linux、Mac OS X和Windows
的版本,其源代码也可以下载)。
MySQL Administrator提示输入服务器和登录信息(并且允许你保存
服务器定义供以后选择),然后显示允许选择不同视图的图标。其中:
· Server Information(服务器信息)显示客户机和被连接的服务器的
状态和版本信息;
· Service Control(服务控制)允许停止和启动MySQL以及指定服务
器特性;
· User Administration(用户管理)用来定义MySQL用户、登录和权
限;
· Catalogs(目录)列出可用的数据库并允许创建数据库和表。
为本书创建数据源 可以使用Create New Schema选项为本书
的表和各章节创建一个数据源。书中各个例子使用一个名为
crashcourse的数据源,你可以使用这个名字,也可以使用自
己选择的名字。
17
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com2.2 MySQL 工具 13
快速访问其他工具 MySQL Administrator工具菜单包含有启
动mysql命令行实用程序 (前面描述) 和MySQL Query Browser
(MySQL查询浏览器) (下面描述)的选项。
MySQL Query Browser也包含启动mysql命令行实用程序和
MySQL Administrator的菜单选项。
2.2.3 MySQL Query Browser
MySQL Query Browser为一个图形交互客户机,用来编写和执行
MySQL命令。
获得MySQL Query Browser 与MySQL Administrator一样,MySQL Query Browser不作为核心MySQL安装的成分。也必须
从http:dev.mysql.comdownloads下载它(可得到用于Linux、Mac OS X和Windows的版本,其源代码也可以下载) 。
MySQL Query Browser要求输入服务器和登录信息(在MySQL Query
Browser和MySQL Administrator之间共享保存的定义),然后显示应用界
面。注意下面几点。
· 输入MySQL命令到屏幕顶上的窗口中。在输入语句后,单击
Execute按钮把它提交给MySQL处理。
· 结果(如果有)显示在屏幕左边的大区域网格中。
· 多条语句和结果显示在它们自己的标签中,并且允许快速切换。
· 屏幕右边是一个标签,它列出所有可能的数据源(这里称为大纲),展开任一数据源查看它的表,展开任一个表查看它的列。
· 你还可以选择表和列让MySQL Query Browser为你编写MySQL语
句。
· Schemata(大纲)标签的右边是一个History(历史)标签,它保
持MySQL语句的执行历史。在需要测试不同版本的MySQL语句
时,它非常有用。
· 关于MySQL语法、函数等的帮助可在屏幕右下角得到。
18
19
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com14 第 2章 MySQL简介
执行保存的脚本 可用MySQL Query Browser执行保存的脚
本(如用来创建和填充本书中使用的表的脚本) 。为执行保存
的脚本,请选择File, Open Script,选择相应的脚本(它将显
示在一个新标签中),然后单击Execute按钮。
2.3 小结
本章介绍了什么是MySQL,并引入了几个客户机实用程序(一个命
令行实用程序,两个可选但强烈建议使用的图形实用程序) 。
20
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
使用MySQL
本章将学习如何连接和登录到MySQL,如何执行MySQL语句,以及
如何获得数据库和表的信息。
3.1 连接
在具有可供使用的MySQL DBMS和客户机软件之后,有必要简要讨
论一下如何连接到数据库。
MySQL与所有客户机—服务器DBMS一样,要求在能执行命令之前登
录到DBMS。 登录名可以与网络登录名不相同(假定你使用网络) 。 MySQL
在内部保存自己的用户列表,并且把每个用户与各种权限关联起来。
在最初安装MySQL时,很可能会要求你输入一个管理登录(通常为
root)和一个口令。如果你使用的是自己的本地服务器,并且是简单地
试验一下MySQL,使用上述登录就可以了。但现实中,管理登录受到密
切保护(因为对它的访问授予了创建表、删除整个数据库、更改登录和
口令等完全的权限) 。
使用MySQL Administrator MySQL Administrator Users视图
提供了一个简单的界面,可用来定义新用户,包括赋予口令和
访问权限。
为了连接到MySQL,需要以下信息:
· 主机名(计算机名)——如果连接到本地MySQL服务器, 为localhost;
· 端口(如果使用默认端口3306之外的端口) ;
第3章
21
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com16 第 3章 使用MySQL
· 一个合法的用户名;
· 用户口令(如果需要) 。
如第2章所述,所有这些信息都可以传递给mysql命令行实用程序,或
输入到MySQL Administrator和MySQL Query Browser的服务器连接屏幕。
使用其他客户机 如果你使用的客户机不是这里提到的客户
机,则为了连接到MySQL,仍然需要提供上述信息。
在连接之后,你就可以访问你的登录名能够访问的任意数据库和表
了。 (登录、访问控制和安全可参阅第28章。 )
3.2 选择数据库
在你最初连接到MySQL时,没有任何数据库打开供你使用。在你能
执行任意数据库操作前,需要选择一个数据库。为此,可使用USE关键字。
关键字(key word) 作为MySQL语言组成部分的一个保留字。决
不要用关键字命名一个表或列。附录E列出了MySQL的关键字。
例如,为了使用crashcourse数据库,应该输入以下内容:
USE语句并不返回任何结果。依赖于使用的客户机,显示某种
形式的通知。例如,这里显示出的Database changed消息是
mysql命令行实用程序在数据库选择成功后显示的。
使用MySQL Query Browser 在MySQL Query Browser中, 双
击Schemata列表中列出的任一数据库以使用它。你看不到USE
命令的实际执行,但会看到被选择的数据库(黑体加亮) ,而
且应用标题栏将显示所选择的数据库名。
记住,必须先使用USE打开数据库,才能读取其中的数据。
输入
输出
分析
22
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com3.3 了解数据库和表 17
3.3 了解数据库和表
如果你不知道可以使用的数据库名时怎么办?这时,MySQL
Administrator和MySQL Query Browser怎样能显示可用的数据库列表?
数据库、表、列、用户、权限等的信息被存储在数据库和表中 (MySQL
使用MySQL来存储这些信息)。不过,内部的表一般不直接访问。可用
MySQL的SHOW命令来显示这些信息(MySQL从内部表中提取这些信息) 。
请看下面的例子:
SHOW DATABASES;返回可用数据库的一个列表。包含在这个列
表中的可能是MySQL内部使用的数据库(如例子中的mysql和
information_schema) 。当然,你自己的数据库列表可能看上去与这里的
不一样。
为了获得一个数据库内的表的列表,使用SHOW TABLES;,如下所示:
输入
输出
分析
输入
输出
23
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com18 第 3章 使用MySQL
SHOW TABLES;返回当前选择的数据库内可用表的列表。
SHOW也可以用来显示表列:
输出
SHOW COLUMNS要求给出一个表名(这个例子中的FROM
customers) ,它对每个字段返回一行,行中包含字段名、数据
类型、是否允许NULL、键信息、默认值以及其他信息(如字段cust_id
的auto_increment)。
什么是自动增量? 某些表列需要唯一值。例如,订单编号、雇员ID或(如上面例子中所示的)顾客ID。在每个行添加到表
中时,MySQL可以自动地为每个行分配下一个可用编号,不
用在添加一行时手动分配唯一值(这样做必须记住最后一次使
用的值) 。这个功能就是所谓的自动增量。如果需要它,则必
须在用CREATE语句创建表时把它作为表定义的组成部分。我们
将在第21章中介绍CREATE语句。
DESCRIBE语句 MySQL支持用DESCRIBE作为SHOW COLUMNS
FROM的一种快捷方式。换句话说,DESCRIBE customers;是
SHOW COLUMNS FROM customers;的一种快捷方式。
所支持的其他SHOW语句还有:
输入
分析
分析
24
25
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com3.4 小结 19
· SHOW STATUS,用于显示广泛的服务器状态信息;
· SHOW CREATE DATABASE和SHOW CREATE TABLE,分别用来显示创
建特定数据库或表的MySQL语句;
· SHOW GRANTS,用来显示授予用户(所有用户或特定用户)的安
全权限;
· SHOW ERRORS和SHOW WARNINGS, 用来显示服务器错误或警告消息。
值得注意的是,客户机应用程序使用与这里相同的MySQL命令。显
示数据库和表的交互式列表、允许交互式创建和编辑表、便于数据录入
和编辑或允许管理用户账号和权限等的应用全都使用你可以直接执行的
相同的MySQL命令完成它们的工作。
进一步了解SHOW 请在mysql命令行实用程序中,执行命令
HELP SHOW;显示允许的SHOW语句。
MySQL 5的新增内容 MySQL 5支持一个新的INFORMA-
TION_SCHEMA命令,可用它来获得和过滤模式信息。
3.4 小结
本章介绍了如何连接和登录MySQL,如何用USE选择数据库,如何用
SHOW查看MySQL数据库、表和内部信息。在这些知识的帮助下,我们可
以进一步深入学习所有重要的SELECT语句了。
26
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
检 索 数 据
本章将介绍如何使用SELECT语句从表中检索一个或多个数据列。
4.1 SELECT语句
正如第1章所述,SQL语句是由简单的英语单词构成的。这些单词称
为关键字,每个SQL语句都是由一个或多个关键字构成的。大概,最经常
使用的SQL语句就是SELECT语句了。它的用途是从一个或多个表中检索
信息。
为了使用SELECT检索表数据,必须至少给出两条信息——想选择什
么,以及从什么地方选择。
4.2 检索单个列
我们将从简单的SQL SELECT语句开始介绍,此语句如下所示:
上述语句利用SELECT语句从products表中检索一个名为
prod_name的列。所需的列名在SELECT关键字之后给出,FROM
关键字指出从其中检索数据的表名。此语句的输出如下所示:
第4章
输入
分析
输出
27
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com欢迎点击这里的链接进入精彩的Linux公社 网
站
Linux公社(www.Linuxidc.com)于2006年9月25日注
册并开通网站,Linux现在已经成为一种广受关注和
支持的一种操作系统,IDC是互联网数据中心,LinuxIDC就是关于Linux的数据中心。
Linux公社是专业的Linux系统门户网站,实时发布最
新Linux资讯,包括Linux、Ubuntu、Fedora、RedHat、红旗Linux、Linux教程、Linux认证、SUSE
Linux、Android、Oracle、Hadoop、CentOS、MySQL、Apache、Nginx、Tomcat、Python、Java、C语言、OpenStack、集群等技术。
Linux公社(LinuxIDC.com)设置了有一定影响力的
Linux专题栏目。
Linux公社 主站网址:www.linuxidc.com 旗下
网站:www.linuxidc.net
包括:Ubuntu 专题 Fedora专题 Android 专题
Oracle专题 Hadoop 专题 RedHat 专题 SUSE
专题 红旗 Linux 专题 CentOS专题
Linux 公社微信公众号:linuxidc_com
4.2 检索单个列 21
未排序数据 如果读者自己试验这个查询,可能会发现显示输
出的数据顺序与这里的不同。出现这种情况很正常。如果没有
明确排序查询结果(下一章介绍),则返回的数据的顺序没有
特殊意义。返回数据的顺序可能是数据被添加到表中的顺序,也可能不是。只要返回相同数目的行,就是正常的。
如上的一条简单SELECT语句将返回表中所有行。数据没有过滤 (过
滤将得出结果集的一个子集) , 也没有排序。以后几章将讨论这些内容。
结束SQL语句 多条SQL语句必须以分号(;)分隔。MySQL
如同多数DBMS一样,不需要在单条SQL语句后加分号。但特
定的DBMS可能必须在单条SQL语句后加上分号。当然,如果
愿意可以总是加上分号。事实上,即使不一定需要,但加上
分号肯定没有坏处。如果你使用的是mysql命令行,必须加上
分号来结束SQL语句。
SQL语句和大小写 请注意,SQL语句不区分大小写,因此
SELECT与select是相同的。同样,写成Select也没有关系。
许多SQL开发人员喜欢对所有SQL关键字使用大写,而对所有
列和表名使用小写,这样做使代码更易于阅读和调试。
28
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com22 第 4章 检 索 数 据
不过,一定要认识到虽然SQL是不区分大小写的,但有些标识
符(如数据库名、表名、列名)可能不同:在MySQL 4.1及之
前的版本中, 这些标识符默认是区分大小写的; 在MySQL 4.1.1
版本中,这些标识符默认是不区分大小写的。
最佳方式是按照大小写的惯例,且使用时保持一致。
使用空格 在处理SQL语句时,其中所有空格都被忽略。SQL
语句可以在一行上给出,也可以分成许多行。多数SQL开发人
员认为将SQL语句分成多行更容易阅读和调试。
4.3 检索多个列
要想从一个表中检索多个列,使用相同的SELECT语句。唯一的不同
是必须在SELECT关键字后给出多个列名,列名之间必须以逗号分隔。
当心逗号 在选择多个列时,一定要在列名之间加上逗号,但
最后一个列名后不加。如果在最后一个列名后加了逗号,将出
现错误。
下面的SELECT语句从products表中选择3列:
与前一个例子一样,这条语句使用SELECT语句从表products
中选择数据。在这个例子中,指定了3个列名,列名之间用逗
号分隔。此语句的输出如下:
输入
分析
输出
29
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com4.4 检索所有列 23
数据表示 从上述输出可以看到,SQL语句一般返回原始的、无格式的数据。数据的格式化是一个表示问题,而不是一个
检索问题。因此,表示(对齐和显示上面的价格值,用货币
符号和逗号表示其金额)一般在显示该数据的应用程序中规
定。一般很少使用实际检索出的原始数据(没有应用程序提
供的格式) 。
4.4 检索所有列
除了指定所需的列外(如上所述,一个或多个列) ,SELECT语句还可
以检索所有的列而不必逐个列出它们。这可以通过在实际列名的位置使
用星号()通配符来达到,如下所示:
如果给定一个通配符() ,则返回表中所有列。列的顺序一般
是列在表定义中出现的顺序。但有时候并不是这样的,表的模
式的变化(如添加或删除列)可能会导致顺序的变化。
使用通配符 一般,除非你确实需要表中的每个列,否则最
好别使用通配符。虽然使用通配符可能会使你自己省事,不
用明确列出所需列,但检索不需要的列通常会降低检索和应
用程序的性能。
输入
分析
30
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com24 第 4章 检 索 数 据
检索未知列 使用通配符有一个大优点。由于不明确指定列
名(因为星号检索每个列),所以能检索出名字未知的列。
4.5 检索不同的行
正如所见,SELECT返回所有匹配的行。但是,如果你不想要每个值
每次都出现,怎么办?例如,假如你想得出products表中产品的所有供
应商ID:
SELECT语句返回14行(即使表中只有4个供应商) ,因为products表
中列出了14个产品。那么,如何检索出有不同值的列表呢?
解决办法是使用DISTINCT关键字,顾名思义,此关键字指示MySQL
只返回不同的值。
SELECT DISTINCT vend_id告诉MySQL只返回不同(唯一)的
vend_id行,因此只返回4行,如下面的输出所示。如果使用
DISTINCT关键字,它必须直接放在列名的前面。
输入
输出
输入
分析
31
32
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com4.6 限制结果 25
不能部分使用DISTINCT DISTINCT关键字应用于所有列而
不仅是前置它的列。如果给出SELECT DISTINCT vend_id,prod_price,除非指定的两个列都不同,否则所有行都将被
检索出来。
4.6 限制结果
SELECT语句返回所有匹配的行,它们可能是指定表中的每个行。为
了返回第一行或前几行,可使用LIMIT子句。下面举一个例子:
此语句使用SELECT语句检索单个列。LIMIT 5指示MySQL返回
不多于5行。此语句的输出如下所示:
为得出下一个5行,可指定要检索的开始行和行数,如下所示:
LIMIT 5, 5指示MySQL返回从行5开始的5行。第一个数为开始
位置,第二个数为要检索的行数。此语句的输出如下所示:
输出
输入
输出
分析
输入
分析
33
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com26 第 4章 检 索 数 据
所以, 带一个值的LIMIT总是从第一行开始,给出的数为返回的行数。
带两个值的LIMIT可以指定从行号为第一个值的位置开始。
行0 检索出来的第一行为行0而不是行1。因此,LIMIT 1, 1
将检索出第二行而不是第一行。
在行数不够时 LIMIT中指定要检索的行数为检索的最大行
数。如果没有足够的行(例如,给出LIMIT 10, 5,但只有13
行) ,MySQL将只返回它能返回的那么多行。
MySQL 5的LIMIT语法 LIMIT 3, 4的含义是从行4开始的3
行还是从行3开始的4行?如前所述,它的意思是从行3开始的4
行,这容易把人搞糊涂。
由于这个原因, MySQL 5支持LIMIT的另一种替代语法。 LIMIT
4 OFFSET 3意为从行3开始取4行,就像LIMIT 3, 4一样。
4.7 使用完全限定的表名
迄今为止使用的SQL例子只通过列名引用列。 也可能会使用完全限定
的名字来引用列(同时使用表名和列字)。请看以下例子:
这条SQL语句在功能上等于本章最开始使用的那一条语句, 但这里指
输出
输入
34
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com4.8 小结 27
定了一个完全限定的列名。
表名也可以是完全限定的,如下所示:
这条语句在功能上也等于刚使用的那条语句(当然,假定products
表确实位于crashcourse数据库中) 。
正如以后章节所介绍的那样,有一些情形需要完全限定名。现在,需要注意这个语法,以便在遇到时知道它的作用。
4.8 小结
本章学习了如何使用SQL的SELECT语句来检索单个表列、多个表列
以及所有表列。下一章将讲授如何排序检索出来的数据。
输入
35
36
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
排序检索数据
本章将讲授如何使用SELECT语句的ORDER BY子句,根据需要排序检
索出的数据。
5.1 排序数据
正如前一章所述,下面的SQL语句返回某个数据库表的单个列。但请
看其输出,并没有特定的顺序。
其实,检索出的数据并不是以纯粹的随机顺序显示的。如果不排
序,数据一般将以它在底层表中出现的顺序显示。这可以是数据最初
第5章
输入
输出
37
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com5.1 排序数据 29
添加到表中的顺序。但是,如果数据后来进行过更新或删除,则此顺
序将会受到MySQL重用回收存储空间的影响。因此,如果不明确控
制的话,不能(也不应该)依赖该排序顺序。关系数据库设计理论认
为,如果不明确规定排序顺序,则不应该假定检索出的数据的顺序有
意义。
子句(clause) SQL语句由子句构成,有些子句是必需的,而
有的是可选的。一个子句通常由一个关键字和所提供的数据组
成。子句的例子有SELECT语句的FROM子句,我们在前一章看到过这个子
句。
为了明确地排序用SELECT语句检索出的数据,可使用ORDER BY子句。
ORDER BY子句取一个或多个列的名字,据此对输出进行排序。请看下面
的例子:
这条语句除了指示MySQL对prod_name列以字母顺序排序数据
的ORDER BY子句外,与前面的语句相同。结果如下:
输入
输出
分析
38
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com30 第 5章 排序检索数据
通过非选择列进行排序 通常,ORDER BY子句中使用的列将
是为显示所选择的列。但是,实际上并不一定要这样,用非
检索的列排序数据是完全合法的。
5.2 按多个列排序
经常需要按不止一个列进行数据排序。例如,如果要显示雇员清单,可能希望按姓和名排序(首先按姓排序,然后在每个姓中再按名排序) 。
如果多个雇员具有相同的姓,这样做很有用。
为了按多个列排序,只要指定列名,列名之间用逗号分开即可(就
像选择多个列时所做的那样) 。
下面的代码检索3个列,并按其中两个列对结果进行排序——首先按
价格,然后再按名称排序。
重要的是理解在按多个列排序时,排序完全按所规定的顺序进行。
换句话说,对于上述例子中的输出,仅在多个行具有相同的prod_price
值时才对产品按prod_name进行排序。如果prod_price列中所有的值都是
输入
输出
39
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com5.3 指定排序方向 31
唯一的,则不会按prod_name排序。
5.3 指定排序方向
数据排序不限于升序排序(从A到Z) 。这只是默认的排序顺序,还可
以使用ORDER BY子句以降序(从Z到A)顺序排序。为了进行降序排序,必须指定DESC关键字。
下面的例子按价格以降序排序产品(最贵的排在最前面) :
但是,如果打算用多个列排序怎么办?下面的例子以降序排序产品
(最贵的在最前面) ,然后再对产品名排序:
输入
输出
输入
输出
40
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com32 第 5章 排序检索数据
DESC关键字只应用到直接位于其前面的列名。在上例中,只对
prod_price列指定DESC,对prod_name列不指定。因此,prod_price列以降序排序,而prod_name列(在每个价格内)仍然按标准
的升序排序。
在多个列上降序排序 如果想在多个列上进行降序排序, 必须
对每个列指定DESC关键字。
与DESC相反的关键字是ASC (ASCENDING), 在升序排序时可以指定它。
但实际上,ASC没有多大用处,因为升序是默认的(如果既不指定ASC也
不指定DESC,则假定为ASC)。
区分大小写和排序顺序 在对文本性的数据进行排序时,A与
a相同吗?a位于B之前还是位于Z之后?这些问题不是理论问
题,其答案取决于数据库如何设置。
在字典 (dictionary) 排序顺序中, A被视为与a相同, 这是MySQL
(和大多数数据库管理系统)的默认行为。但是,许多数据库
管理员能够在需要时改变这种行为(如果你的数据库包含大量
外语字符,可能必须这样做) 。
这里,关键的问题是,如果确实需要改变这种排序顺序,用简
单的ORDER BY子句做不到。你必须请求数据库管理员的帮助。
分析
41
42
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com5.4 小结 33
使用ORDER BY和LIMIT的组合,能够找出一个列中最高或最低的值。
下面的例子演示如何找出最昂贵物品的值:
prod_price DESC保证行是按照由最昂贵到最便宜检索的,而
LIMIT 1告诉MySQL仅返回一行。
ORDER BY子句的位置 在给出ORDER BY子句时,应该保证它
位于FROM子句之后。如果使用LIMIT,它必须位于ORDER BY
之后。使用子句的次序不对将产生错误消息。
5.4 小结
本章学习了如何用SELECT语句的ORDER BY子句对检索出的数据进行
排序。这个子句必须是SELECT语句中的最后一条子句。可根据需要,利
用它在一个或多个列上对数据进行排序。
输入
输出
分析
43
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
过 滤 数 据
本章将讲授如何使用SELECT语句的WHERE子句指定搜索条件。
6.1 使用WHERE子句
数据库表一般包含大量的数据,很少需要检索表中所有行。通常只
会根据特定操作或报告的需要提取表数据的子集。只检索所需数据需要
指定搜索条件(search criteria),搜索条件也称为过滤条件(filter
condition)。
在SELECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤。
WHERE子句在表名(FROM子句)之后给出,如下所示:
这条语句从products表中检索两个列,但不返回所有行,只返
回prod_price值为2.50的行,如下所示:
这个例子采用了简单的相等测试:它检查一个列是否具有指定的值,据此进行过滤。但是SQL允许做的事情不仅仅是相等测试。
第6章
输入
分析
输出
45
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com6.2 WHERE 子句操作符 35
SQL过滤与应用过滤 数据也可以在应用层过滤。为此目
的,SQL的SELECT语句为客户机应用检索出超过实际所需的
数据,然后客户机代码对返回数据进行循环,以提取出需要
的行。
通常,这种实现并不令人满意。因此,对数据库进行了优化,以便快速有效地对数据进行过滤。让客户机应用(或开发语言)
处理数据库的工作将会极大地影响应用的性能,并且使所创建
的应用完全不具备可伸缩性。此外,如果在客户机上过滤数据,服务器不得不通过网络发送多余的数据,这将导致网络带宽的
浪费。
WHERE子句的位置 在同时使用ORDER BY和WHERE子句时,应
该让ORDER BY位于WHERE之后, 否则将会产生错误(关于ORDER
BY的使用,请参阅第5章) 。
6.2 WHERE子句操作符
我们在关于相等的测试时看到了第一个WHERE子句,它确定一个列是
否包含特定的值。MySQL支持表6-1列出的所有条件操作符。
表6-1 WHERE子句操作符
操 作 符 说 明
= 等于
<> 不等于!= 不等于
< 小于
<= 小于等于
> 大于
>= 大于等于
BETWEEN 在指定的两个值之间
46
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com36 第 6章 过 滤 数 据
6.2.1 检查单个值
我们已经看到了测试相等的例子。再来看一个类似的例子:
检查WHERE prod_name=‘fuses’语句,它返回prod_name的值
为Fuses的一行。MySQL在执行匹配时默认不区分大小写,所
以fuses与Fuses匹配。
现在来看几个使用其他操作符的例子。
第一个例子是列出价格小于10美元的所有产品:
下一条语句检索价格小于等于10美元的所有产品(输出的结果比第
一个例子输出的结果多两种产品) :
输入
输出
输入
输入
输出
输出
分析
47
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com6.2 WHERE 子句操作符 37
6.2.2 不匹配检查
以下例子列出不是由供应商1003制造的所有产品:
何时使用引号 如果仔细观察上述WHERE子句中使用的条件,会看到有的值括在单引号内(如前面使用的'fuses') ,而有
的值未括起来。单引号用来限定字符串。如果将值与串类型的
列进行比较,则需要限定引号。用来与数值列进行比较的值不
用引号。
下面是相同的例子,其中使用!=而不是<>操作符:
6.2.3 范围值检查
为了检查某个范围的值,可使用BETWEEN操作符。其语法与其他WHERE
输入
输出
输入
48
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com38 第 6章 过 滤 数 据
子句的操作符稍有不同,因为它需要两个值,即范围的开始值和结束值。
例如,BETWEEN操作符可用来检索价格在5美元和10美元之间或日期在指
定的开始日期和结束日期之间的所有产品。
下面的例子说明如何使用BETWEEN操作符,它检索价格在5美元和10
美元之间的所有产品:
从这个例子中可以看到,在使用BETWEEN时,必须指定两个值
——所需范围的低端值和高端值。这两个值必须用AND关键字
分隔。BETWEEN匹配范围中所有的值,包括指定的开始值和结束值。
6.2.4 空值检查
在创建表时,表设计人员可以指定其中的列是否可以不包含值。在
一个列不包含值时,称其为包含空值NULL。
NULL 无值(no value) ,它与字段包含0、空字符串或仅仅包含
空格不同。
SELECT语句有一个特殊的WHERE子句,可用来检查具有NULL值的列。
这个WHERE子句就是IS NULL子句。其语法如下:
这条语句返回没有价格(空prod_price字段,不是价格为0)的所有
产品,由于表中没有这样的行,所以没有返回数据。但是,customers
表确实包含有具有空值的列,如果在文件中没有某位顾客的电子邮件地
输入
输出
分析
输入
49
50
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com6.3 小结 39
址,则cust_email列将包含NULL值:
NULL与不匹配 在通过过滤选择出不具有特定值的行时,你
可能希望返回具有NULL值的行。但是,不行。因为未知具有
特殊的含义,数据库不知道它们是否匹配,所以在匹配过滤
或不匹配过滤时不返回它们。
因此,在过滤数据时,一定要验证返回数据中确实给出了被
过滤列具有NULL的行。
6.3 小结
本章介绍了如何用SELECT语句的WHERE子句过滤返回的数据。我们学
习了如何对相等、不相等、大于、小于、值的范围以及NULL值等进行测
试。
输入
输出
51
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
数 据 过 滤
本章讲授如何组合WHERE子句以建立功能更强的更高级的搜索条件。
我们还将学习如何使用NOT和IN操作符。
7.1 组合WHERE子句
第6章中介绍的所有WHERE子句在过滤数据时使用的都是单一的条
件。为了进行更强的过滤控制,MySQL允许给出多个WHERE子句。这些子
句可以两种方式使用:以AND子句的方式或OR子句的方式使用。
操作符(operator) 用来联结或改变WHERE子句中的子句的关键
字。也称为逻辑操作符(logical operator)。
7.1.1 AND操作符
为了通过不止一个列进行过滤,可使用AND操作符给WHERE子句附加
条件。下面的代码给出了一个例子:
此SQL语句检索由供应商1003制造且价格小于等于10美元的所
有产品的名称和价格。这条SELECT语句中的WHERE子句包含两
个条件,并且用AND关键字联结它们。AND指示DBMS只返回满足所有给
定条件的行。如果某个产品由供应商1003制造,但它的价格高于10美元,则不检索它。类似,如果产品价格小于10美元,但不是由指定供应商制
造的也不被检索。这条SQL语句产生的输出如下:
第7章
输入
分析
53
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com7.1 组合 WHERE 子句 41
AND 用在WHERE子句中的关键字,用来指示检索满足所有给定
条件的行。
上述例子中使用了只包含一个关键字AND的语句,把两个过滤条件组
合在一起。还可以添加多个过滤条件,每添加一条就要使用一个AND。
7.1.2 OR操作符
OR操作符与AND操作符不同,它指示MySQL检索匹配任一条件的行。
请看如下的SELECT语句:
此SQL语句检索由任一个指定供应商制造的所有产品的产品
名和价格。 OR操作符告诉DBMS匹配任一条件而不是同时匹配
两个条件。如果这里使用的是AND操作符,则没有数据返回(此时创建
的WHERE子句不会检索到匹配的产品) 。这条SQL语句产生的输出如下:
输出
输入
输出
分析
54
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com欢迎点击这里的链接进入精彩的Linux公社 网
站
Linux公社(www.Linuxidc.com)于2006年9月25日注
册并开通网站,Linux现在已经成为一种广受关注和
支持的一种操作系统,IDC是互联网数据中心,LinuxIDC就是关于Linux的数据中心。
Linux公社是专业的Linux系统门户网站,实时发布最
新Linux资讯,包括Linux、Ubuntu、Fedora、RedHat、红旗Linux、Linux教程、Linux认证、SUSE
Linux、Android、Oracle、Hadoop、CentOS、MySQL、Apache、Nginx、Tomcat、Python、Java、C语言、OpenStack、集群等技术。
Linux公社(LinuxIDC.com)设置了有一定影响力的
Linux专题栏目。
Linux公社 主站网址:www.linuxidc.com 旗下
网站:www.linuxidc.net
包括:Ubuntu 专题 Fedora专题 Android 专题
Oracle专题 Hadoop 专题 RedHat 专题 SUSE
专题 红旗 Linux 专题 CentOS专题
Linux 公社微信公众号:linuxidc_com
42 第 7章 数 据 过 滤
OR WHERE子句中使用的关键字,用来表示检索匹配任一给定
条件的行。
7.1.3 计算次序
WHERE可包含任意数目的AND和OR操作符。允许两者结合以进行复杂
和高级的过滤。
但是,组合AND和OR带来了一个有趣的问题。为了说明这个问题,来
看一个例子。假如需要列出价格为10美元(含)以上且由1002或1003制
造的所有产品。下面的SELECT语句使用AND和OR操作符的组合建立了一个
WHERE子句:
请看上面的结果。返回的行中有两行价格小于10美元,显然,返回的行未按预期的进行过滤。为什么会这样呢?原因在于计
算的次序。SQL(像多数语言一样)在处理OR操作符前,优先处理AND操
作符。当SQL看到上述WHERE子句时,它理解为由供应商1003制造的任何
价格为10美元(含)以上的产品,或者由供应商1002制造的任何产品,而不管其价格如何。换句话说,由于AND在计算次序中优先级更高,操作
符被错误地组合了。
此问题的解决方法是使用圆括号明确地分组相应的操作符。请看下
面的SELECT语句及输出:
输入
分析
输出
输入
55
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com7.2 IN操作符 43
这条SELECT语句与前一条的唯一差别是,这条语句中,前两个
条件用圆括号括了起来。因为圆括号具有较AND或OR操作符高
的计算次序,DBMS首先过滤圆括号内的OR条件。这时,SQL语句变成了
选择由供应商1002或1003制造的且价格都在10美元(含)以上的任何产
品,这正是我们所希望的。
在WHERE子句中使用圆括号 任何时候使用具有AND和OR操作
符的WHERE子句,都应该使用圆括号明确地分组操作符。不要
过分依赖默认计算次序,即使它确实是你想要的东西也是如
此。使用圆括号没有什么坏处,它能消除歧义。
7.2 IN操作符
圆括号在WHERE子句中还有另外一种用法。IN操作符用来指定条件范
围,范围中的每个条件都可以进行匹配。IN取合法值的由逗号分隔的清
单,全都括在圆括号中。下面的例子说明了这个操作符:
输出
分析
输入
输出
56
57
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com44 第 7章 数 据 过 滤
此SELECT语句检索供应商1002和1003制造的所有产品。IN操
作符后跟由逗号分隔的合法值清单,整个清单必须括在圆括号
中。
如果你认为IN操作符完成与OR相同的功能,那么你的这种猜测是对
的。下面的SQL语句完成与上面的例子相同的工作:
为什么要使用IN操作符?其优点具体如下。
· 在使用长的合法选项清单时,IN操作符的语法更清楚且更直观。
· 在使用IN时,计算的次序更容易管理(因为使用的操作符更少) 。
· IN操作符一般比OR操作符清单执行更快。
· IN的最大优点是可以包含其他SELECT语句,使得能够更动态地建
立WHERE子句。第14章将对此进行详细介绍。
IN WHERE子句中用来指定要匹配值的清单的关键字,功能与OR
相当。
7.3 NOT操作符
WHERE子句中的NOT操作符有且只有一个功能,那就是否定它之后所
跟的任何条件。
NOT WHERE子句中用来否定后跟条件的关键字。
分析
输入
输出
58
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com7.4 小结 45
下面的例子说明NOT的使用。为了列出除1002和1003之外的所有供应
商制造的产品,可编写如下的代码:
这里的NOT否定跟在它之后的条件,因此, MySQL不是匹配1002
和1003的vend_id,而是匹配1002和1003之外供应商的
vend_id。
为什么使用NOT?对于简单的WHERE子句,使用NOT确实没有什么优
势。但在更复杂的子句中,NOT是非常有用的。例如,在与IN操作符联合
使用时,NOT使找出与条件列表不匹配的行非常简单。
MySQL中的NOT MySQL支持使用NOT对IN、BETWEEN和
EXISTS子句取反,这与多数其他DBMS允许使用NOT对各种条件
取反有很大的差别。
7.4 小结
本章讲授如何用AND和OR操作符组合成WHERE子句,而且还讲授了如
何明确地管理计算的次序,如何使用IN和NOT操作符。
输入
输出
分析
59
60
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
用通配符进行过滤
本章介绍什么是通配符、如何使用通配符以及怎样使用LIKE操作符
进行通配搜索,以便对数据进行复杂过滤。
8.1 LIKE操作符
前面介绍的所有操作符都是针对已知值进行过滤的。不管是匹配一
个还是多个值,测试大于还是小于已知值,或者检查某个范围的值,共
同点是过滤中使用的值都是已知的。但是,这种过滤方法并不是任何时
候都好用。例如,怎样搜索产品名中包含文本anvil的所有产品?用简单
的比较操作符肯定不行,必须使用通配符。利用通配符可创建比较特定
数据的搜索模式。在这个例子中,如果你想找出名称包含anvil的所有产
品,可构造一个通配符搜索模式,找出产品名中任何位置出现anvil的产
品。
通配符(wildcard) 用来匹配值的一部分的特殊字符。
搜索模式(search pattern) ① 由字面值、通配符或两者组合构
成的搜索条件。
通配符本身实际是SQL的WHERE子句中有特殊含义的字符,SQL支持几
种通配符。
① 数据库中的schema(见1.1.2节)和pattern都译作“模式”,特此说明,请读者注意。
——编者注
第8章
61
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com8.1 LIKE操作符 47
为在搜索子句中使用通配符,必须使用LIKE操作符。LIKE指示MySQL,后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较。
谓词 操作符何时不是操作符?答案是在它作为谓词(predi-
cate)时。从技术上说,LIKE是谓词而不是操作符。虽然最终
的结果是相同的,但应该对此术语有所了解,以免在SQL文档
中遇到此术语时不知道。
8.1.1 百分号(%)通配符
最常使用的通配符是百分号(%) 。在搜索串中,%表示任何字符出现
任意次数。例如,为了找出所有以词jet起头的产品,可使用以下SELECT
语句:
此例子使用了搜索模式'jet%'。在执行这条子句时,将检索任
意以jet起头的词。%告诉MySQL接受jet之后的任意字符,不
管它有多少字符。
区分大小写 根据MySQL的配置方式,搜索可以是区分大小
写的。如果区分大小写,'jet%'与JetPack 1000将不匹配。
通配符可在搜索模式中任意位置使用,并且可以使用多个通配符。
下面的例子使用两个通配符,它们位于模式的两端:
输入
输出
分析
输入
62
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com48 第 8章 用通配符进行过滤
搜索模式'%anvil%'表示匹配任何位置包含文本anvil的值,而
不论它之前或之后出现什么字符。
通配符也可以出现在搜索模式的中间,虽然这样做不太有用。下面
的例子找出以s起头以e结尾的所有产品:
重要的是要注意到,除了一个或多个字符外,%还能匹配0个字符。%
代表搜索模式中给定位置的0个、1个或多个字符。
注意尾空格 尾空格可能会干扰通配符匹配。例如,在保存词
anvil时,如果它后面有一个或多个空格,则子句WHERE
prod_name LIKE '%anvil'将不会匹配它们,因为在最后的l
后有多余的字符。解决这个问题的一个简单的办法是在搜索模
式最后附加一个%。一个更好的办法是使用函数(第11章将会
介绍)去掉首尾空格。
注意NULL 虽然似乎%通配符可以匹配任何东西,但有一个例
外,即NULL。即使是WHERE prod_name LIKE '%'也不能匹配
用值NULL作为产品名的行。
8.1.2 下划线(_)通配符
另一个有用的通配符是下划线(_) 。下划线的用途与%一样,但下划
线只匹配单个字符而不是多个字符。
举一个例子:
输出
分析
输入
63
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com8.2 使用通配符的技巧 49
此WHERE子句中的搜索模式给出了后面跟有文本的两个通配
符。结果只显示匹配搜索模式的行:第一行中下划线匹配1,第二行中匹配2。.5 ton anvil产品没有匹配,因为搜索模式要求匹配两
个通配符而不是一个。对照一下,下面的SELECT语句使用%通配符,返回
三行产品:
与%能匹配0个字符不一样,_总是匹配一个字符,不能多也不能少。
8.2 使用通配符的技巧
正如所见,MySQL的通配符很有用。但这种功能是有代价的:通配
符搜索的处理一般要比前面讨论的其他搜索所花时间更长。这里给出一
些使用通配符要记住的技巧。
· 不要过度使用通配符。如果其他操作符能达到相同的目的,应该
使用其他操作符。
· 在确实需要使用通配符时,除非绝对有必要,否则不要把它们用
在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起
来是最慢的。
· 仔细注意通配符的位置。如果放错地方,可能不会返回想要的数
输入
输出
分析
输入
输出
64
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com50 第 8章 用通配符进行过滤
据。
总之,通配符是一种极重要和有用的搜索工具,以后我们经常会用
到它。
8.3 小结
本章介绍了什么是通配符以及如何在WHERE子句中使用SQL通配符,并且还说明了通配符应该细心使用,不要过度使用。
66
65
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
用正则表达式
进行搜索
本章将学习如何在MySQL WHERE子句内使用正则表达式来更好地控
制数据过滤。
9.1 正则表达式介绍
前两章中的过滤例子允许用匹配、比较和通配操作符寻找数据。对
于基本的过滤(或者甚至是某些不那么基本的过滤),这样就足够了。但
随着过滤条件的复杂性的增加,WHERE子句本身的复杂性也有必要增加。
这也就是正则表达式变得有用的地方。正则表达式是用来匹配文本
的特殊的串(字符集合)。如果你想从一个文本文件中提取电话号码,可
以使用正则表达式。如果你需要查找名字中间有数字的所有文件,可以
使用一个正则表达式。如果你想在一个文本块中找到所有重复的单词,可以使用一个正则表达式。如果你想替换一个页面中的所有URL为这些
URL的实际HTML链接, 也可以使用一个正则表达式(对于最后这个例子,或者是两个正则表达式) 。
所有种类的程序设计语言、文本编辑器、操作系统等都支持正则表
达式。有见识的程序员和网络管理员已经关注作为他们技术工具重要内
容的正则表达式很长时间了。
正则表达式用正则表达式语言来建立,正则表达式语言是用来完成
刚讨论的所有工作以及更多工作的一种特殊语言。与任意语言一样,正
则表达式具有你必须学习的特殊的语法和指令。
第9章
67
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com52 第 9章 用正则表达式进行搜索
学习更多内容 完全覆盖正则表达式的内容超出了本书的范
围。虽然基础知识都在这里做了介绍,但对正则表达式更为透
彻的介绍可能还需要参阅作者的《正则表达式必知必会》①。
9.2 使用MySQL正则表达式
那么,正则表达式与MySQL有何关系?已经说过,正则表达式的作
用是匹配文本,将一个模式(正则表达式)与一个文本串进行比较。 MySQL
用WHERE子句对正则表达式提供了初步的支持,允许你指定正则表达式,过滤SELECT检索出的数据。
仅为正则表达式语言的一个子集 如果你熟悉正则表达式, 需
要注意:MySQL仅支持多数正则表达式实现的一个很小的子
集。本章介绍MySQL支持的大多数内容。
我们举几个例子,更清晰地描述正则表达式的概念。
9.2.1 基本字符匹配
我们从一个非常简单的例子开始。下面的语句检索列prod_name包含
文本1000的所有行:
除关键字LIKE被REGEXP替代外,这条语句看上去非常像使用
LIKE的语句(第8章) 。它告诉MySQL:REGEXP后所跟的东西作
为正则表达式(与文字正文1000匹配的一个正则表达式)处理。
① 已由人民邮电出版社出版。——编者注
输入
输出
分析
68
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com9.2 使用 MySQL 正则表达式 53
为什么要费力地使用正则表达式?在刚才的例子中,正则表达式确
实没有带来太多好处(可能还会降低性能),不过,请考虑下面的例子:
这里使用了正则表达式.000。.是正则表达式语言中一个特殊
的字符。它表示匹配任意一个字符,因此,1000和2000都匹配
且返回。
当然,这个特殊的例子也可以用LIKE和通配符来完成(参阅第8章) 。
LIKE与REGEXP 在LIKE和REGEXP之间有一个重要的差别。请
看以下两条语句:
如果执行上述两条语句,会发现第一条语句不返回数据,而第
二条语句返回一行。为什么?
正如第8章所述,LIKE匹配整个列。如果被匹配的文本在列值
中出现,LIKE将不会找到它,相应的行也不被返回(除非使用
通配符)。而REGEXP在列值内进行匹配,如果被匹配的文本在
列值中出现,REGEXP将会找到它,相应的行将被返回。这是一
个非常重要的差别。
那么,REGEXP能不能用来匹配整个列值(从而起与LIKE相同
输入
输出
分析
69
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com54 第 9章 用正则表达式进行搜索
的作用)?答案是肯定的,使用^和定位符(anchor)即可,本章后面介绍。
匹配不区分大小写 MySQL中的正则表达式匹配(自版本
3.23.4后)不区分大小写(即,大写和小写都匹配)。为区分大
小写,可使用BINARY关键字,如WHERE prod_name REGEXP
BINARY 'JetPack .000'。
9.2.2 进行OR匹配
为搜索两个串之一(或者为这个串,或者为另一个串),使用|,如
下所示:
语句中使用了正则表达式1000|2000。|为正则表达式的OR操作
符。它表示匹配其中之一,因此1000和2000都匹配并返回。
使用|从功能上类似于在SELECT语句中使用OR语句, 多个OR条件可并
入单个正则表达式。
两个以上的OR条件 可以给出两个以上的OR条件。例如,'1000 | 2000 | 3000'将匹配1000或2000或3000。
9.2.3 匹配几个字符之一
匹配任何单一字符。但是,如果你只想匹配特定的字符,怎么办?
可通过指定一组用[和]括起来的字符来完成,如下所示:
输入
输出
分析
70
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com9.2 使用 MySQL 正则表达式 55
这里,使用了正则表达式[123] Ton。[123]定义一组字符,它
的意思是匹配1或2或3,因此,1 ton和2 ton都匹配且返回(没
有3 ton)。
正如所见, []是另一种形式的OR语句。 事实上,正则表达式[123]Ton
为[1|2|3]Ton的缩写,也可以使用后者。但是,需要用[]来定义OR语句
查找什么。为更好地理解这一点,请看下面的例子:
这并不是期望的输出。两个要求的行被检索出来,但还检索出
了另外3行。之所以这样是由于MySQL假定你的意思是'1'或
'2'或'3 ton'。除非把字符|括在一个集合中,否则它将应用于整个串。
字符集合也可以被否定,即,它们将匹配除指定字符外的任何东西。
为否定一个字符集,在集合的开始处放置一个^即可。因此,尽管[123]
匹配字符1、2或3,但[^123]却匹配除这些字符外的任何东西。
9.2.4 匹配范围
集合可用来定义要匹配的一个或多个字符。例如,下面的集合将匹
配数字0到9:
输入
输入
输出
输出
分析
分析
72
71
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com56 第 9章 用正则表达式进行搜索
为简化这种类型的集合,可使用-来定义一个范围。下面的式子功能
上等同于上述数字列表:
范围不限于完整的集合,[1-3]和[6-9]也是合法的范围。此外,范
围不一定只是数值的,[a-z]匹配任意字母字符。
举一个例子:
这里使用正则表达式[1-5] Ton。[1-5]定义了一个范围,这个
表达式意思是匹配1到5,因此返回3个匹配行。由于5 ton匹配,所以返回.5 ton。
9.2.5 匹配特殊字符
正则表达式语言由具有特定含义的特殊字符构成。我们已经看到.、 []、|和-等,还有其他一些字符。请问,如果你需要匹配这些字符,应该怎么
办呢?例如,如果要找出包含.字符的值,怎样搜索?请看下面的例子:
输入
输入
输出
输出
分析
73
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com9.2 使用 MySQL 正则表达式 57
这并不是期望的输出,.匹配任意字符,因此每个行都被检索出
来。
为了匹配特殊字符,必须用\\为前导。 \\-表示查找-, \\.表示查找.。
这才是期望的输出。\\.匹配.,所以只检索出一行。这种处理
就是所谓的转义(escaping) ,正则表达式内具有特殊意义的所
有字符都必须以这种方式转义。这包括.、|、[]以及迄今为止使用过的
其他特殊字符。
\\也用来引用元字符(具有特殊含义的字符) ,如表9-1所列。
表9-1 空白元字符
元 字 符 说 明
\\f 换页
\\n 换行
\\r 回车
\\t 制表
\\v 纵向制表
匹配\ 为了匹配反斜杠(\)字符本身,需要使用\\\。
\或\\? 多数正则表达式实现使用单个反斜杠转义特殊字符,以便能使用这些字符本身。 但MySQL要求两个反斜杠 (MySQL
自己解释一个,正则表达式库解释另一个) 。
输入
输出
分析
分析
74
75
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com58 第 9章 用正则表达式进行搜索
9.2.6 匹配字符类
存在找出你自己经常使用的数字、所有字母字符或所有数字字母字
符等的匹配。为更方便工作,可以使用预定义的字符集,称为字符类
(character class) 。表9-2列出字符类以及它们的含义。
表9-2 字符类
类 说 明
[:alnum:] 任意字母和数字(同[a-zA-Z0-9])
[:alpha:] 任意字符(同[a-zA-Z])
[:blank:] 空格和制表(同[\\t])
[:cntrl:] ASCII控制字符(ASCII 0到31和127)
[:digit:] 任意数字(同[0-9])
[:graph:] 与[:print:]相同,但不包括空格
[:lower:] 任意小写字母(同[a-z])
[:print:] 任意可打印字符
[:punct:] 既不在[:alnum:]又不在[:cntrl:]中的任意字符
[:space:] 包括空格在内的任意空白字符(同[\\f\\n\\r\\t\\v])
[:upper:] 任意大写字母(同[A-Z])
[:xdigit:] 任意十六进制数字(同[a-fA-F0-9])
9.2.7 匹配多个实例
目前为止使用的所有正则表达式都试图匹配单次出现。如果存在一
个匹配,该行被检索出来,如果不存在,检索不出任何行。但有时需要
对匹配的数目进行更强的控制。例如,你可能需要寻找所有的数,不管
数中包含多少数字,或者你可能想寻找一个单词并且还能够适应一个尾
随的s(如果存在),等等。
这可以用表9-3列出的正则表达式重复元字符来完成。
表9-3 重复元字符
元 字 符 说 明
0个或多个匹配
+ 1个或多个匹配(等于{1,})
· 0个或1个匹配(等于{0,1})
{n} 指定数目的匹配
{n,} 不少于指定数目的匹配
{n,m} 匹配数目的范围(m不超过255)
76
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com9.2 使用 MySQL 正则表达式 59
下面举几个例子。
正则表达式\\([0-9] sticks?\\)需要解说一下。\\(匹配),[0-9]匹配任意数字(这个例子中为1和5),sticks?匹配stick
和sticks(s后的?使s可选,因为?匹配它前面的任何字符的0次或1次出
现) ,\\)匹配)。没有?,匹配stick和sticks会非常困难。
以下是另一个例子。这次我们打算匹配连在一起的4位数字:
如前所述,[:digit:]匹配任意数字,因而它为数字的一个集
合。{4}确切地要求它前面的字符(任意数字)出现4次,所以
[[:digit:]]{4}匹配连在一起的任意4位数字。
需要注意的是,在使用正则表达式时,编写某个特殊的表达式几乎
总是有不止一种方法。上面的例子也可以如下编写:
9.2.8 定位符
目前为止的所有例子都是匹配一个串中任意位置的文本。为了匹配
输入
输入
输入
输出
输出
分析
分析
77
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com60 第 9章 用正则表达式进行搜索
特定位置的文本,需要使用表9-4列出的定位符。
表9-4 定位元字符
元 字 符 说 明
^ 文本的开始
文本的结尾
[[:<:]] 词的开始
[[:>:]] 词的结尾
例如,如果你想找出以一个数(包括以小数点开始的数)开始的所
有产品,怎么办?简单搜索[0-9\\.](或[[:digit:]\\.])不行,因为
它将在文本内任意位置查找匹配。解决办法是使用^定位符,如下所示:
^匹配串的开始。因此,^[0-9\\.]只在.或任意数字为串中第
一个字符时才匹配它们。没有^, 则还要多检索出4个别的行 (那
些中间有数字的行) 。
^的双重用途 ^有两种用法。在集合中(用[和]定义),用它
来否定该集合,否则,用来指串的开始处。
使REGEXP起类似LIKE的作用 本章前面说过,LIKE和REGEXP
的不同在于,LIKE匹配整个串而REGEXP匹配子串。利用定位
符,通过用^开始每个表达式,用结束每个表达式,可以使
REGEXP的作用与LIKE一样。
输入
输出
分析
78
79
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com9.3 小结 61
简单的正则表达式测试 可以在不使用数据库表的情况下用
SELECT来测试正则表达式。 REGEXP检查总是返回0 (没有匹配)
或1(匹配)。可以用带文字串的REGEXP来测试表达式,并试
验它们。相应的语法如下:
这个例子显然将返回0(因为文本hello中没有数字) 。
9.3 小结
本章介绍了正则表达式的基础知识,学习了如何在MySQL的SELECT
语句中通过REGEXP关键字使用它们。
80
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
创建计算字段
本章介绍什么是计算字段,如何创建计算字段以及怎样从应用程序
中使用别名引用它们。
10.1 计算字段
存储在数据库表中的数据一般不是应用程序所需要的格式。下面举
几个例子。
· 如果想在一个字段中既显示公司名,又显示公司的地址,但这两
个信息一般包含在不同的表列中。
· 城市、州和邮政编码存储在不同的列中(应该这样),但邮件标签
打印程序却需要把它们作为一个恰当格式的字段检索出来。
· 列数据是大小写混合的,但报表程序需要把所有数据按大写表示
出来。
· 物品订单表存储物品的价格和数量,但不需要存储每个物品的总
价格(用价格乘以数量即可)。为打印发票,需要物品的总价格。
· 需要根据表数据进行总数、平均数计算或其他计算。
在上述每个例子中,存储在表中的数据都不是应用程序所需要的。
我们需要直接从数据库中检索出转换、计算或格式化过的数据;而不是
检索出数据,然后再在客户机应用程序或报告程序中重新格式化。
这就是计算字段发挥作用的所在了。与前面各章介绍过的列不同,计算字段并不实际存在于数据库表中。计算字段是运行时在SELECT语句
内创建的。
第10章
81
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com欢迎点击这里的链接进入精彩的Linux公社 网
站
Linux公社(www.Linuxidc.com)于2006年9月25日注
册并开通网站,Linux现在已经成为一种广受关注和
支持的一种操作系统,IDC是互联网数据中心,LinuxIDC就是关于Linux的数据中心。
Linux公社是专业的Linux系统门户网站,实时发布最
新Linux资讯,包括Linux、Ubuntu、Fedora、RedHat、红旗Linux、Linux教程、Linux认证、SUSE
Linux、Android、Oracle、Hadoop、CentOS、MySQL、Apache、Nginx、Tomcat、Python、Java、C语言、OpenStack、集群等技术。
Linux公社(LinuxIDC.com)设置了有一定影响力的
Linux专题栏目。
Linux公社 主站网址:www.linuxidc.com 旗下
网站:www.linuxidc.net
包括:Ubuntu 专题 Fedora专题 Android 专题
Oracle专题 Hadoop 专题 RedHat 专题 SUSE
专题 红旗 Linux 专题 CentOS专题
Linux 公社微信公众号:linuxidc_com
10.2 拼接字段 63
字段(field) 基本上与列(column)的意思相同,经常互换使
用,不过数据库列一般称为列,而术语字段通常用在计算字段的
连接上。
重要的是要注意到,只有数据库知道SELECT语句中哪些列是实际的
表列,哪些列是计算字段。从客户机(如应用程序)的角度来看,计算
字段的数据是以与其他列的数据相同的方式返回的。
客户机与服务器的格式 可在SQL语句内完成的许多转换
和格式化工作都可以直接在客户机应用程序内完成。但一
般来说,在数据库服务器上完成这些操作比在客户机中完
成要快得多,因为DBMS是设计来快速有效地完成这种处
理的。
10.2 拼接字段
为了说明如何使用计算字段,举一个创建由两列组成的标题的简单
例子。
vendors表包含供应商名和位置信息。假如要生成一个供应商报表,需要在供应商的名字中按照name(location)这样的格式列出供应商的位
置。
此报表需要单个值,而表中数据存储在两个列vend_name和vend_
country中。此外,需要用括号将vend_country括起来,这些东西都没有
明确存储在数据库表中。我们来看看怎样编写返回供应商名和位置的
SELECT语句。
拼接(concatenate) 将值联结到一起构成单个值。
解决办法是把两个列拼接起来。在MySQL的SELECT语句中,可使用
Concat函数来拼接两个列。
82
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com64 第 10章 创建计算字段
MySQL的不同之处 多数DBMS使用+或||来实现拼接,MySQL则使用Concat函数来实现。当把SQL语句转换成
MySQL语句时一定要把这个区别铭记在心。
Concat拼接串,即把多个串连接起来形成一个较长的串。
Concat需要一个或多个指定的串,各个串之间用逗号分隔。
上面的SELECT语句连接以下4个元素:
· 存储在vend_name列中的名字;
· 包含一个空格和一个左圆括号的串;
· 存储在vend_country列中的国家;
· 包含一个右圆括号的串。
从上述输出中可以看到,SELECT语句返回包含上述4个元素的单个列
(计算字段) 。
在第8章中曾提到通过删除数据右侧多余的空格来整理数据,这可以
使用MySQL的RTrim函数来完成,如下所示:
RTrim函数去掉值右边的所有空格。通过使用RTrim,各个
列都进行了整理。
输入
分析
输入
输出
分析
83
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com10.2 拼接字段 65
Trim函数 MySQL除了支持RTrim(正如刚才所见,它去掉
串右边的空格),还支持LTrim(去掉串左边的空格)以及
Trim(去掉串左右两边的空格) 。
使用别名
从前面的输出中可以看到,SELECT语句拼接地址字段工作得很好。
但此新计算列的名字是什么呢?实际上它没有名字,它只是一个值。如
果仅在SQL查询工具中查看一下结果,这样没有什么不好。但是,一个未
命名的列不能用于客户机应用中,因为客户机没有办法引用它。
为了解决这个问题,SQL支持列别名。别名(alias)是一个字段或值
的替换名。别名用AS关键字赋予。请看下面的SELECT语句:
SELECT语句本身与以前使用的相同,只不过这里的语句中计算
字段之后跟了文本AS vend_title。它指示SQL创建一个包含
指定计算的名为vend_title的计算字段。从输出中可以看到,结果与以
前的相同,但现在列名为vend_title,任何客户机应用都可以按名引用
这个列,就像它是一个实际的表列一样。
别名的其他用途 别名还有其他用途。常见的用途包括在实际
的表列名包含不符合规定的字符(如空格)时重新命名它,在
原来的名字含混或容易误解时扩充它,等等。
输入
输出
分析
84
85
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com66 第 10章 创建计算字段
导出列 别名有时也称为导出列(derived column) ,不管称为
什么,它们所代表的都是相同的东西。
10.3 执行算术计算
计算字段的另一常见用途是对检索出的数据进行算术计算。举一个
例子,orders表包含收到的所有订单,orderitems表包含每个订单中的
各项物品。下面的SQL语句检索订单号20005中的所有物品:
item_price列包含订单中每项物品的单价。如下汇总物品的价格(单
价乘以订购数量) :
输出中显示的expanded_price列为一个计算字段,此计算为
quantityitem_price。客户机应用现在可以使用这个新计算
列,就像使用其他列一样。
输入
输出
输入
输出
分析
86
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com10.4 小结 67
MySQL支持表10-1中列出的基本算术操作符。此外,圆括号可用来
区分优先顺序。关于优先顺序的介绍,请参阅第7章。
表10-1 MySQL算术操作符
操 作 符 说 明
+ 加
- 减
乘
除
如何测试计算 SELECT提供了测试和试验函数与计算的一个
很好的办法。虽然SELECT通常用来从表中检索数据,但可以
省略FROM子句以便简单地访问和处理表达式。例如,SELECT
32;将返回6,SELECT Trim('abc');将返回abc,而SELECT
Now利用Now函数返回当前日期和时间。通过这些例子,可以明白如何根据需要使用SELECT进行试验。
10.4 小结
本章介绍了计算字段以及如何创建计算字段。我们用例子说明了计
算字段在串拼接和算术计算的用途。此外,还学习了如何创建和使用别
名,以便应用程序能引用计算字段。
87
88
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
使用数据处理函数
本章介绍什么是函数, MySQL支持何种函数,以及如何使用这些函数。
11.1 函数
与其他大多数计算机语言一样,SQL支持利用函数来处理数据。函数
一般是在数据上执行的,它给数据的转换和处理提供了方便。
在前一章中用来去掉串尾空格的RTrim就是一个函数的例子。
函数没有SQL的可移植性强 能运行在多个系统上的代码称
为可移植的(portable) 。相对来说,多数SQL语句是可移植的,在SQL实现之间有差异时,这些差异通常不那么难处理。而函
数的可移植性却不强。几乎每种主要的DBMS的实现都支持其
他实现不支持的函数,而且有时差异还很大。
为了代码的可移植,许多SQL程序员不赞成使用特殊实现的功
能。虽然这样做很有好处,但不总是利于应用程序的性能。如
果不使用这些函数,编写某些应用程序代码会很艰难。必须利
用其他方法来实现DBMS非常有效地完成的工作。
如果你决定使用函数,应该保证做好代码注释,以便以后你(或
其他人)能确切地知道所编写SQL代码的含义。
11.2 使用函数
大多数SQL实现支持以下类型的函数。
· 用于处理文本串(如删除或填充值,转换值为大写或小写)的文
第11章
89
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com11.2 使用函数 69
本函数。
· 用于在数值数据上进行算术操作(如返回绝对值,进行代数运算)
的数值函数。
· 用于处理日期和时间值并从这些值中提取特定成分(例如,返回
两个日期之差,检查日期有效性等)的日期和时间函数。
· 返回DBMS正使用的特殊信息(如返回用户登录信息,检查版本
细节)的系统函数。
11.2.1 文本处理函数
上一章中我们已经看过一个文本处理函数的例子,其中使用RTrim
函数来去除列值右边的空格。下面是另一个例子,这次使用Upper函数:
正如所见,Upper将文本转换为大写,因此本例子中每个供
应商都列出两次,第一次为vendors表中存储的值,第二次作
为列vend_name_upcase转换为大写。
表11-1列出了某些常用的文本处理函数。
表11-1 常用的文本处理函数
函 数 说 明
Left 返回串左边的字符
Length 返回串的长度
Locate 找出串的一个子串
Lower 将串转换为小写
LTrim 去掉串左边的空格
Right 返回串右边的字符
输入
输出
分析
90
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com70 第 11章 使用数据处理函数
(续)
函 数 说 明
RTrim 去掉串右边的空格
Soundex 返回串的SOUNDEX值
SubString 返回子串的字符
Upper 将串转换为大写
表11-1中的SOUNDEX需要做进一步的解释。SOUNDEX是一个将任何文
本串转换为描述其语音表示的字母数字模式的算法。SOUNDEX考虑了类似
的发音字符和音节,使得能对串进行发音比较而不是字母比较。虽然
SOUNDEX不是SQL概念,但MySQL(就像多数DBMS一样)都提供对
SOUNDEX的支持。
下面给出一个使用Soundex函数的例子。customers表中有一个顾
客Coyote Inc.,其联系名为Y.Lee。但如果这是输入错误,此联系名实
际应该是Y.Lie,怎么办?显然,按正确的联系名搜索不会返回数据,如
下所示:
现在试一下使用Soundex函数进行搜索,它匹配所有发音类似于
Y.Lie的联系名:
在这个例子中,WHERE子句使用Soundex函数来转换cust_
contact列值和搜索串为它们的SOUNDEX值。因为Y.Lee和
Y.Lie发音相似,所以它们的SOUNDEX值匹配,因此WHERE子句正确地过滤
出了所需的数据。
输入
输出
输入
分析
输出
91
92
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com11.2 使用函数 71
11.2.2 日期和时间处理函数
日期和时间采用相应的数据类型和特殊的格式存储,以便能快速和
有效地排序或过滤,并且节省物理存储空间。
一般,应用程序不使用用来存储日期和时间的格式,因此日期和时
间函数总是被用来读取、统计和处理这些值。由于这个原因,日期和时
间函数在MySQL语言中具有重要的作用。
表11-2列出了某些常用的日期和时间处理函数。
表11-2 常用日期和时间处理函数
函 数 说 明
AddDate 增加一个日期(天、周等)
AddTime 增加一个时间(时、分等)
CurDate 返回当前日期
CurTime 返回当前时间
Date 返回日期时间的日期部分
DateDiff 计算两个日期之差
Date_Add 高度灵活的日期运算函数
Date_Format 返回一个格式化的日期或时间串
Day 返回一个日期的天数部分
DayOfWeek 对于一个日期,返回对应的星期几
Hour 返回一个时间的小时部分
Minute 返回一个时间的分钟部分
Month 返回一个日期的月份部分
Now 返回当前日期和时间
Second 返回一个时间的秒部分
Time 返回一个日期时间的时间部分
Year 返回一个日期的年份部分
这是重新复习用WHERE进行数据过滤的一个好时机。迄今为止,我
们都是用比较数值和文本的WHERE子句过滤数据,但数据经常需要用日
期进行过滤。用日期进行过滤需要注意一些别的问题和使用特殊的
MySQL函数。
首先需要注意的是MySQL使用的日期格式。无论你什么时候指定一
93
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com72 第 11章 使用数据处理函数
个日期,不管是插入或更新表值还是用WHERE子句进行过滤,日期必须为
格式yyyy-mm-dd。因此,2005年9月1日,给出为2005-09-01。虽然其他的
日期格式可能也行,但这是首选的日期格式,因为它排除了多义性(如,040506是2006年5月4日或2006年4月5日或2004年5月6日或……) 。
应该总是使用4位数字的年份 支持2位数字的年份,MySQL
处理00-69为2000-2069,处理70-99为1970-1999。虽然它们可
能是打算要的年份,但使用完整的4位数字年份更可靠,因为
MySQL不必做出任何假定。
因此,基本的日期比较应该很简单:
此SELECT语句正常运行。它检索出一个订单记录,该订单记录
的order_date为2005-09-01。
但是,使用WHERE order_date = '2005-09-01'可靠吗?order_
date的数据类型为datetime。这种类型存储日期及时间值。样例表中
的值全都具有时间值00:00:00,但实际中很可能并不总是这样。如果
用当前日期和时间存储订单日期(因此你不仅知道订单日期,还知道
下订单当天的时间),怎么办?比如,存储的order_date值为
2005-09-01 11:30:05,则WHERE order_date = '2005-09-01'失败。
即使给出具有该日期的一行,也不会把它检索出来,因为WHERE匹配失
败。
解决办法是指示MySQL仅将给出的日期与列中的日期部分进行比
较,而不是将给出的日期与整个列值进行比较。为此,必须使用Date
函数。Date(order_date)指示MySQL仅提取列的日期部分,更可靠的
SELECT语句为:
输入
输出
分析
94
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com11.2 使用函数 73
如果要的是日期,请使用Date 如果你想要的仅是日期,则使用Date是一个良好的习惯,即使你知道相应的列只包
含日期也是如此。这样,如果由于某种原因表中以后有日期和
时间值,你的SQL代码也不用改变。当然,也存在一个Time
函数,在你只想要时间时应该使用它。
Date和Time都是在MySQL 4.1.1中第一次引入的。
在你知道了如何用日期进行相等测试后,其他操作符(在第6章中介
绍)的使用也就很清楚了。
不过,还有一种日期比较需要说明。如果你想检索出2005年9月下的
所有订单,怎么办?简单的相等测试不行,因为它也要匹配月份中的天
数。有几种解决办法,其中之一如下所示:
其中,BETWEEN操作符用来把2005-09-01和2005-09-30定义为
一个要匹配的日期范围。
还有另外一种办法(一种不需要记住每个月中有多少天或不需要操
心闰年2月的办法) :
Year是一个从日期(或日期时间)中返回年份的函数。类似,Month从日期中返回月份。因此,WHERE Year(order_date)
输入
输入
输出
分析
输入
分析
95
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 ww ......
Linux公社 www.linuxidc.com内 容 提 要
MySQL 是世界上最受欢迎的数据库管理系统之一。书中从介绍简单的数据
检索开始,逐步深入一些复杂的内容,包括联结的使用、子查询、正则表达式
和基于全文本的搜索、存储过程、游标、触发器、表约束,等等。通过重点突
出的章节,条理清晰、系统而扼要地讲述了读者应该掌握的知识,使他们不经
意间立刻功力大增。
本书注重实用性,操作性很强,适用于广大软件开发和数据库管理人员学
习参考。
图灵程序设计丛书
著 [ 英] Ben Forta
译 刘晓霞 钟 鸣
责任编辑 傅志红
执行编辑 刘 静
人民邮电出版社出版发行 北京市崇文区夕照寺街14号
邮编 100061 电子函件 315@ptpress.com.cn
网址 http:www.ptpress.com.cn
北京 印刷
开本:850×1168 132
印张:8
字数:246千字 2009年 1 月第 1 版
印数:1 — 4 000册 2009年 1 月北京第 1 次印刷
著作权合同登记号 图字:01-2008-4295号
MySQL必知必会
ISBN 978-7-115-19112-0TP
定价:39.00元
读者服务热线:(010)88593802 印装质量热线:(010)67129223
反盗版热线:(010)67171154
◆
◆
◆
图书在版编目(CIP)数据
MySQL必知必会 (英)福塔(Forta, B.)著;刘晓霞,钟鸣译. —北京:人民邮电出版社,2009.1
(图灵程序设计丛书)
书名原文:MySQL Crash Course
ISBN 978-7-115-19112-0
Ⅰ . M… Ⅱ.①福… ②刘… ③钟 Ⅲ. 关系数据库 — 数
据库管理系统,MySQL Ⅳ. TP311.138
中国版本图书馆CIP数据核字(2008)第159272号
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
版 权 声 明
Authorized translation from the English language edition, entitled
MySQL Crash Course, 0672327120 by Ben Forta, published by Pearson
Education, Inc., publishing as Sams. Copyright ? 2006 by Sams Publishing.
All rights reserved. No part of this book may be reproduced or
transmitted in any form or by any means, electronic or mechanical, including
photocopying, recording or by any information storage retrieval system,without permission from Pearson Education, Inc.
Simplified Chinese-language edition copyright ? 2009 by Posts
Telecom Press. All rights reserved.
本书中文简体字版由 Pearson Education Inc.授权人民邮电出版社独
家出版。未经出版者书面许可,不得以任何方式复制或抄袭本书内容。
版权所有,侵权必究。
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
致 谢
首先,我要感谢Sams出版公司的伙伴们,他们再一次给了我灵活的
自由度,让我把书写成我认为合适的样子。谢谢Mark Renfrow提供的关于
本书和前面几本书的反馈意见。特别感谢Loretta Yates不仅在中途勇敢地
介入到出版过程中,使其回归正轨,继续进行,而且还果断地签署了本
系列书中后两部书籍的出版合约。
谢谢Jochem van Dieten和Timothy Boronczyk这两位技术编辑,他们对
书稿进行了出色的技术审查。余下的那些“错误”都是我“故意”犯的,就是想看看读者们有没有注意到。:-)
最后,本书是应《SQL必知必会》读者的请求编写的。那本书收到了
很多极有价值的反馈意见和建议,在此我深表谢意。谢谢大家,我希望
自己达到了大家的期望。
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
前 言
MySQL已经成为世界上最受欢迎的数据库管理系统之一。无论是用
在小型开发项目上,还是用来构建那些声名显赫的网站,MySQL都证明
了自己是个稳定、可靠、快速、可信的系统,足以胜任任何数据存储业
务的需要。
本书基于我的一本畅销书Sams Teach Yourself SQL in 10 Minutes (中文
版《SQL必知必会》 ,人民邮电出版社出版),那本书堪称全世界用得最
多的一本SQL教程,重点讲解读者必须知道的东西,条理清晰,系统而
扼要。但是,即使是那样一本广为使用的成功的书,也还存在着以下这
些局限性。
· 由于要面向所有主要的数据库管理系统(DBMS) ,我不得不把针
对具体DBMS的内容一再压缩。
· 为了简化SQL的讲解,我必须(尽可能)只写各种主要的DBMS
通用的SQL语句。这要求我不得不舍弃一些更好的、针对具体
DBMS的解决方案。
· 虽然基本的SQL在不同的DBMS间具有较好的可移植性,但是高
级的SQL显然不是这样的。因此,那本书里无法详细讲解比较高
级的内容,如触发器、游标、存储过程、访问控制、事务等。
于是就有了这本书。本书沿用了前一本书业已成功的教程模式和组
织结构,除了MySQL以外,不在其他内容上过多纠缠。书从简单的数据
检索开始,逐步进入一些复杂的内容,包括联结的使用、子查询、正则
1
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com2 前 言
表达式和基于全文本的搜索、存储过程、游标、触发器、表约束,等等。
通过重点突出的章节,条理清晰、系统而扼要地让读者学到应该学到的
知识,使他们不经意间立刻功力大增。
请先到第1章开始学习。读者会立刻体会到MySQL提供的所有好处。
读者对象
本书的读者对象是这样一些人:
· 他没有学过SQL;
· 他刚开始用MySQL,并希望一举成功;
· 他想迅速地、尽可能多地学会使用MySQL;
· 他希望学习怎样在自己的应用程序开发中使用MySQL;
· 他希望通过使用MySQL轻松快速地提高工作效率,而不用劳烦他
人帮忙。
配套网站
本书有一个配套网站,网址是:http:forta.combooks0672327120。
读者可以通过该网站访问如下内容:
· 表格创建和表格填充的脚本,可用来创建书中使用的样例表;
· 在线支持论坛;
· 在线勘误(如果发现了勘误的话) ;
· 或许他会感兴趣的其他书。
本书约定
本书使用不同的字体区分代码和一般正文内容,对于重要的概念也
采用特殊的字体。
键入的文本和屏幕上显示出的文本用等宽代码字体表示。如:It
looks like this to mimic the way text looks on your screen.
2
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com前 言 3
一行代码最前面如果出现箭头(?)表示该行代码较长,书中一行放
不下。读者录入时需要把这一行的内容紧接着上一行输入。
说明:表示跟上下文的内容相关的一些有意思的信息。
提示:提供建议,教读者用容易的办法完成某项任务。
注意:向读者提示可能出现的问题,避免不必要的麻烦。
新术语,提供新的基本词汇的清晰定义。
表示读者自己键入的代码。通常出现在程序清单的旁边。
表示运行MySQL代码后得到的结果,通常出现在程序清单之后。
告诉读者这是作者对输入或输出的逐行分析。
输出
分析
输入
3
4
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
目 录
第1章 了解SQL............................
1
1.1 数据库基础.............................
1
1.1.1 什么是数据库.............
2
1.1.2 表.................................
2
1.1.3 列和数据类型.............
3
1.1.4 行.................................
4
1.1.5 主键.............................
4
1.2 什么是SQL .............................
5
1.3 动手实践.................................
6
1.4 小结.........................................
7
第2章 MySQL简介......................
8
2.1 什么是MySQL........................
8
2.1.1 客户机—服务器软件...
8
2.1.2 MySQL版本...............
9
2.2 MySQL工具..........................
10
2.2.1 mysql命令行实用
程序..........................
11
2.2.2 MySQL Adminis-
trator .........................
12
2.2.3 MySQL Query
Browser.....................
13
2.3 小结.......................................
14
第3章 使用MySQL....................
15
3.1 连接.......................................
15
3.2 选择数据库...........................
16
3.3 了解数据库和表...................
17
3.4 小结.......................................
19
第4章 检索数据..........................
20
4.1 SELECT语句.........................
20
4.2 检索单个列...........................
20
4.3 检索多个列...........................
22
4.4 检索所有列...........................
23
4.5 检索不同的行.......................
24
4.6 限制结果...............................
25
4.7 使用完全限定的表名...........
26
4.8 小结......................................
27
第5章 排序检索数据.................
28
5.1 排序数据...............................
28
5.2 按多个列排序.......................
30
5.3 指定排序方向.......................
31
5.4 小结......................................
33
第6章 过滤数据..........................
34
6.1 使用WHERE子句....................
34
6.2 WHERE子句操作符.................
35
6.2.1 检查单个值..............
36
6.2.2 不匹配检查..............
37
6.2.3 范围值检查..............
37
6.2.4 空值检查..................
38
6.3 小结......................................
39
第7章 数据过滤..........................
40
7.1 组合WHERE子句....................
40
7.1.1 AND操作符................
40
7.1.2 OR操作符..................
41
7.1.3 计算次序..................
42
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com2 目 录
7.2 IN操作符...............................
43
7.3 NOT操作符.............................
44
7.4 小结.......................................
45
第8章 用通配符进行过滤.........
46
8.1 LIKE操作符...........................
46
8.1.1 百分号(%)通配符...
47
8.1.2 下划线(_)通配符...
48
8.2 使用通配符的技巧................
49
8.3 小结.......................................
50
第9章 用正则表达式进行搜索...
51
9.1 正则表达式介绍...................
51
9.2 使用MySQL正则表达式.......
52
9.2.1 基本字符匹配...........
52
9.2.2 进行OR匹配..............
54
9.2.3 匹配几个字符之一...
54
9.2.4 匹配范围...................
55
9.2.5 匹配特殊字符...........
56
9.2.6 匹配字符类...............
58
9.2.7 匹配多个实例...........
58
9.2.8 定位符.......................
59
9.3 小结.......................................
61
第10章 创建计算字段...............
62
10.1 计算字段.............................
62
10.2 拼接字段.............................
63
10.3 执行算术计算.....................
66
10.4 小结.....................................
67
第11章 使用数据处理函数.......
68
11.1 函数.....................................
68
11.2 使用函数.............................
68
11.2.1 文本处理函数.......
69
11.2.2 日期和时间处理
函数.......................
71
11.2.3 数值处理函数.......
74
11.3 小结.....................................
74
第12章 汇总数据........................
75
12.1 聚集函数.............................
75
12.1.1 AVG函数............
76
12.1.2 COUNT函数........
77
12.1.3 MAX函数............
78
12.1.4 MIN函数............
79
12.1.5 SUM函数............
79
12.2 聚集不同值.........................
80
12.3 组合聚集函数.....................
81
12.4 小结.....................................
82
第13章 分组数据........................
83
13.1 数据分组.............................
83
13.2 创建分组.............................
83
13.3 过滤分组.............................
85
13.4 分组和排序.........................
87
13.5 SELECT子句顺序.................
88
13.6 小结.....................................
89
第14章 使用子查询...................
90
14.1 子查询.................................
90
14.2 利用子查询进行过滤..........
90
14.3 作为计算字段使用
子查询................................
93
14.4 小结.....................................
96
第15章 联结表............................
97
15.1 联结.....................................
97
15.1.1 关系表..................
97
15.1.2 为什么要使用
联结......................
99
15.2 创建联结.............................
99
15.2.1 WHERE子句的
重要性....................
100
15.2.2 内部联结............
103
15.2.3 联结多个表........
104
15.3 小结...................................
105
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com目 录 3
第16章 创建高级联结.............
106
16.1 使用表别名.......................
106
16.2 使用不同类型的联结.......
107
16.2.1 自联结................
107
16.2.2 自然联结............
109
16.2.3 外部联结............
109
16.3 使用带聚集函数的联结....
111
16.4 使用联结和联结条件.......
112
16.5 小结...................................
112
第17章 组合查询.....................
113
17.1 组合查询...........................
113
17.2 创建组合查询...................
113
17.2.1 使用UNION .........
114
17.2.2 UNION规则.........
115
17.2.3 包含或取消重复
的行....................
116
17.2.4 对组合查询结果
排序....................
117
17.3 小结...................................
118
第18章 全文本搜索.................
119
18.1 理解全文本搜索...............
119
18.2 使用全文本搜索...............
120
18.2.1 启用全文本搜索
支持....................
120
18.2.2 进行全文本
搜索....................
121
18.2.3 使用查询扩展....
124
18.2.4 布尔文本搜索....
126
18.2.5 全文本搜索的
使用说明............
129
18.3 小结...................................
130
第19章 插入数据.....................
131
19.1 数据插入...........................
131
19.2 插入完整的行...................
131
19.3 插入多个行.......................
134
19.4 插入检索出的数据...........
136
19.5 小结..................................
138
第20章 更新和删除数据........
139
20.1 更新数据...........................
139
20.2 删除数据...........................
141
20.3 更新和删除的指导原则.....
142
20.4 小结..................................
143
第21章 创建和操纵表.............
144
21.1 创建表...............................
144
21.1.1 表创建基础........
144
21.1.2 使用NULL值.......
146
21.1.3 主键再介绍........
147
21.1.4 使用AUTO_
INCREMENT.........
148
21.1.5 指定默认值........
149
21.1.6 引擎类型............
150
21.2 更新表...............................
151
21.3 删除表...............................
153
21.4 重命名表...........................
153
21.5 小结..................................
154
第22章 使用视图.....................
155
22.1 视图..................................
155
22.1.1 为什么使用
视图...................
156
22.1.2 视图的规则和
限制...................
157
22.2 使用视图...........................
157
22.2.1 利用视图简化
复杂的联结........
157
22.2.2 用视图重新格式化
检索出的数据....
158
22.2.3 用视图过滤不
想要的数据........
159
22.2.4 使用视图与计算
字段...................
160
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com4 目 录
22.2.5 更新视图............
161
22.3 小结...................................
162
第23章 使用存储过程.............
163
23.1 存储过程...........................
163
23.2 为什么要使用存储过程....
164
23.3 使用存储过程...................
165
23.3.1 执行存储过程......
165
23.3.2 创建存储过程......
165
23.3.3 删除存储过程......
167
23.3.4 使用参数..............
167
23.3.5 建立智能存储
过程.....................
170
23.3.6 检查存储过程......
173
23.4 小结...................................
173
第24章 使用游标......................
174
24.1 游标...................................
174
24.2 使用游标...........................
174
24.2.1 创建游标............
175
24.2.2 打开和关闭游标...
175
24.2.3 使用游标数据....
176
24.3 小结...................................
180
第25章 使用触发器.................
181
25.1 触发器...............................
181
25.2 创建触发器.......................
182
25.3 删除触发器.......................
183
25.4 使用触发器.......................
183
25.4.1 INSERT触发器....
183
25.4.2 DELETE触发器....
184
25.4.3 UPDATE触发器....
185
25.4.4 关于触发器的进
一步介绍............
186
25.5 小结...................................
186
第26章 管理事务处理.............
187
26.1 事务处理...........................
187
26.2 控制事务处理...................
189
26.2.1 使用ROLLBACK.....
189
26.2.2 使用COMMIT........
190
26.2.3 使用保留点........
191
26.2.4 更改默认的提交
行为....................
192
26.3 小结...................................
192
第27章 全球化和本地化.........
193
27.1 字符集和校对顺序............
193
27.2 使用字符集和校对顺序....
194
27.3 小结...................................
196
第28章 安全管理......................
197
28.1 访问控制...........................
197
28.2 管理用户...........................
198
28.2.1 创建用户账号....
199
28.2.2 删除用户账号....
200
28.2.3 设置访问权限....
200
28.2.4 更改口令............
203
28.3 小结...................................
204
第29章 数据库维护.................
205
29.1 备份数据...........................
205
29.2 进行数据库维护...............
206
29.3 诊断启动问题...................
207
29.4 查看日志文件...................
207
29.5 小结...................................
208
第30章 改善性能......................
209
30.1 改善性能...........................
209
30.2 小结...................................
211
附录A MySQL入门..................
212
附录B 样例表............................
214
附录C MySQL语句的语法.....
220
附录D MySQL数据类型.........
224
附录E MySQL保留字..............
228
索引 ................................................
232
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
了解SQL
本章将介绍数据库和SQL,它们是学习MySQL的先决条件。
1.1 数据库基础
你正在阅读本书,这表明你需要以某种方式与数据库打交道。在深
入学习MySQL及其SQL语言的实现之前,应该对数据库及数据库技术的
某些基本概念有所了解。
你可能还没有意识到,其实你自己一直在使用数据库。每当你从自
己的电子邮件地址簿里查找名字时,你就在使用数据库。如果你在某个
因特网搜索站点上进行搜索,也是在使用数据库。如果你在工作中登录
网络,也需要依靠数据库验证自己的名字和密码。即使是在自动取款机
上使用ATM卡,也要利用数据库进行PIN码验证和余额检查。
虽然我们一直都在使用数据库,但对究竟什么是数据库并不十分清
楚。特别是不同的人可能会使用相同的数据库术语表示不同的事物,更
加剧了这种混乱。因此,我们学习的良好切入点就是给出一张最重要的
数据库术语清单,并加以说明。
基本概念回顾 下面是某些基本数据库概念的简要介绍。如果
你已经具有一定的数据库经验,这可以用于复习巩固;如果你
是一个数据库新手,这将给你提供一些必需的基本知识。理解
数据库是掌握MySQL的一个重要部分,如果有必要的话,你
应该参阅一些有关数据库基础知识的书籍①。
① 推荐人民邮电出版社出版的由Kifer、Bernstein和Lewis合著的《数据库系统:面向应
用的方法》或Elmasri和Navathe合著的《数据库系统基础》。——编者注
第1章
5
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com2 第 1章 了解SQL
1.1.1 什么是数据库
数据库这个术语的用法很多,但就本书而言,数据库是一个以某种
有组织的方式存储的数据集合。理解数据库的一种最简单的办法是将其
想象为一个文件柜。此文件柜是一个存放数据的物理位置,不管数据是
什么以及如何组织的。
数据库(database) 保存有组织的数据的容器(通常是一个文
件或一组文件) 。
误用导致混淆 人们通常用数据库这个术语来代表他们使用
的数据库软件。这是不正确的,它是引起混淆的根源。确切
地说,数据库软件应称为DBMS(数据库管理系统)。数据库
是通过DBMS创建和操纵的容器。数据库可以是保存在硬设备
上的文件,但也可以不是。在很大程度上说,数据库究竟是
文件还是别的什么东西并不重要,因为你并不直接访问数据
库;你使用的是DBMS,它替你访问数据库。
1.1.2 表
在你将资料放入自己的文件柜时,并不是随便将它们扔进某个抽屉就完
事了,而是在文件柜中创建文件,然后将相关的资料放入特定的文件中。
在数据库领域中,这种文件称为表。表是一种结构化的文件,可用
来存储某种特定类型的数据。表可以保存顾客清单、产品目录,或者其
他信息清单。
表(table) 某种特定类型数据的结构化清单。
这里关键的一点在于,存储在表中的数据是一种类型的数据或一个
清单。决不应该将顾客的清单与订单的清单存储在同一个数据库表中。这
样做将使以后的检索和访问很困难。应该创建两个表,每个清单一个表。
数据库中的每个表都有一个名字,用来标识自己。此名字是唯一的,这表示数据库中没有其他表具有相同的名字。
6
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com1.1 数据库基础 3
表名 表名的唯一性取决于多个因素,如数据库名和表名等的
结合。 这表示,虽然在相同数据库中不能两次使用相同的表名,但在不同的数据库中却可以使用相同的表名。
表具有一些特性,这些特性定义了数据在表中如何存储,如可以存
储什么样的数据,数据如何分解,各部分信息如何命名,等等。描述表
的这组信息就是所谓的模式,模式可以用来描述数据库中特定的表以及
整个数据库(和其中表的关系) 。
模式(schema) 关于数据库和表的布局及特性的信息。
是模式还是数据库? 有时,模式用作数据库的同义词。遗憾
的是,模式的含义通常在上下文中并不是很清晰。本书中,模
式指的是上面给出的定义。
1.1.3 列和数据类型
表由列组成。列中存储着表中某部分的信息。
列(column) 表中的一个字段。所有表都是由一个或多个列组
成的。
理解列的最好办法是将数据库表想象为一个网格。网格中每一列存
储着一条特定的信息。例如,在顾客表中,一个列存储着顾客编号,另
一个列存储着顾客名,而地址、城市、州以及邮政编码全都存储在各自
的列中。
分解数据 正确地将数据分解为多个列极为重要。例如, 城市、州、邮政编码应该总是独立的列。通过把它分解开,才有可能
利用特定的列对数据进行排序和过滤(如,找出特定州或特定
城市的所有顾客) 。如果城市和州组合在一个列中,则按州进
行排序或过滤会很困难。
7
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com4 第 1章 了解SQL
数据库中每个列都有相应的数据类型。数据类型定义列可以存储的
数据种类。例如,如果列中存储的为数字(或许是订单中的物品数) ,则
相应的数据类型应该为数值类型。如果列中存储的是日期、文本、注释、金额等,则应该用恰当的数据类型规定出来。
数据类型(datatype) 所容许的数据的类型。每个表列都有相
应的数据类型,它限制(或容许)该列中存储的数据。
数据类型限制可存储在列中的数据种类(例如,防止在数值字段中
录入字符值) 。数据类型还帮助正确地排序数据,并在优化磁盘使用方面
起重要的作用。因此,在创建表时必须对数据类型给予特别的关注。
1.1.4 行
表中的数据是按行存储的,所保存的每个记录存储在自己的行内。
如果将表想象为网格,网格中垂直的列为表列,水平行为表行。
例如,顾客表可以每行存储一个顾客。表中的行数为记录的总数。
行(row) 表中的一个记录。
是记录还是行? 你可能听到用户在提到行(row)时称其为
数据库记录(record) 。在很大程度上,这两个术语是可以互相
替代的,但从技术上说,行才是正确的术语。
1.1.5 主键
表中每一行都应该有可以唯一标识自己的一列(或一组列) 。一个顾
客表可以使用顾客编号列,而订单表可以使用订单ID,雇员表可以使用
雇员ID或雇员社会保险号。
主键(primary key) ①一一列(或一组列),其值能够唯一区分表
中每个行。
① 全国科学技术名词审定委员会审定的key在数据库中的对应名词为“键码”或“码” ,本书采用了已约定俗成的“键”,请读者注意。——编者注
8
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com1.2 什么是SQL 5
唯一标识表中每行的这个列(或这组列)称为主键。主键用来表示
一个特定的行。没有主键,更新或删除表中特定行很困难,因为没有安
全的方法保证只涉及相关的行。
应该总是定义主键 虽然并不总是都需要主键,但大多数数据
库设计人员都应保证他们创建的每个表具有一个主键, 以便于
以后的数据操纵和管理。
表中的任何列都可以作为主键,只要它满足以下条件:
· 任意两行都不具有相同的主键值;
· 每个行都必须具有一个主键值(主键列不允许NULL值) 。
主键值规则 这里列出的规则是MySQL本身强制实施的。
主键通常定义在表的一列上,但这并不是必需的,也可以一起使用
多个列作为主键。在使用多列作为主键时,上述条件必须应用到构成主
键的所有列,所有列值的组合必须是唯一的(但单个列的值可以不唯一) 。
主键的最好习惯 除MySQL强制实施的规则外,应该坚持的
几个普遍认可的最好习惯为:
· 不更新主键列中的值;
· 不重用主键列的值;
· 不在主键列中使用可能会更改的值。(例如,如果使用一个
名字作为主键以标识某个供应商,当该供应商合并和更改其
名字时,必须更改这个主键。)
还有一种非常重要的键,称为外键,我们将在第15章中介绍。
1.2 什么是SQL
SQL (发音为字母S-Q-L或sequel) 是结构化查询语言 (Structured Query
Language)的缩写。SQL是一种专门用来与数据库通信的语言。
10
9
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com6 第 1章 了解SQL
与其他语言(如,英语以及Java和Visual Basic这样的程序设计语言)
不一样,SQL由很少的词构成,这是有意而为的。设计SQL的目的是很好
地完成一项任务,即提供一种从数据库中读写数据的简单有效的方法。
SQL有如下的优点。
· SQL不是某个特定数据库供应商专有的语言。几乎所有重要的
DBMS都支持SQL,所以,学习此语言使你几乎能与所有数据库
打交道。
· SQL简单易学。它的语句全都是由描述性很强的英语单词组成,而且这些单词的数目不多。
· SQL尽管看上去很简单,但它实际上是一种强有力的语言,灵活
使用其语言元素,可以进行非常复杂和高级的数据库操作。
DBMS专用的SQL SQL不是一种专利语言,而且存在一个标
准委员会,他们试图定义可供所有DBMS使用的SQL语法,但
事实上任意两个DBMS实现的SQL都不完全相同。本书讲授的
SQL是专门针对MySQL的,虽然书中所讲授的多数语法也适
用于其他DBMS,但不要认为这些SQL语法是完全可移植的。
1.3 动手实践
本书所有章节都采用可上机运行的例子来说明SQL语法,它的功能是
什么,为什么起这样的作用。作者强烈建议读者试验每个例子,以便掌
握MySQL的第一手资料。
附录B描述了本书中使用的样例表,说明如何获得和安装它们。如果
你还没有获得和安装它们,请在继续学习前先学习这个附录。
你需要MySQL 显然,你需要能访问某个MySQL副本,以便
学习本书的内容。附录A说明了在何处获得MySQL的副本,并
提供一定的入门指导。如果你已经能访问某个MySQL副本,在继续学习之前,也请阅读该附录。
11
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com1.4 小结 7
1.4 小结
这一章介绍了什么是SQL以及它为什么很有用。因为SQL是用来与数
据库打交道的,所以,我们也复习了一些基本的数据库术语。 12
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
MySQL简介
本章将介绍什么是MySQL,以及在MySQL中可以应用什么工具。
2.1 什么是MySQL
我们在前一章中介绍了数据库和SQL。正如所述,数据的所有存储、检索、管理和处理实际上是由数据库软件——DBMS(数据库管理系统)
完成的。MySQL是一种DBMS,即它是一种数据库软件。
MySQL已经存在很久了,它在世界范围内得到了广泛的安装和使用。
为什么有那么多的公司和开发人员使用MySQL?以下列出其原因。
· 成本——MySQL是开放源代码的,一般可以免费使用(甚至可以
免费修改) 。
· 性能——MySQL执行很快(非常快) 。
· 可信赖——某些非常重要和声望很高的公司、站点使用MySQL,这些公司和站点都用MySQL来处理自己的重要数据。
· 简单——MySQL很容易安装和使用。
事实上,MySQL受到的唯一真正的批评是它并不总是支持其他
DBMS提供的功能和特性。然而,这一点也正在逐步得到改善,MySQL
的各个新版本正不断增加新特性、新功能。
2.1.1 客户机—服务器软件
DBMS可分为两类:一类为基于共享文件系统的DBMS,另一类为基
于客户机—服务器的DBMS。 前者(包括诸如Microsoft Access和FileMaker)
第2章
13
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com2.1 什么是MySQL 9
用于桌面用途,通常不用于高端或更关键的应用。
MySQL、Oracle以及Microsoft SQL Server等数据库是基于客户机—服
务器的数据库。客户机—服务器应用分为两个不同的部分。服务器部分是
负责所有数据访问和处理的一个软件。这个软件运行在称为数据库服务
器的计算机上。
与数据文件打交道的只有服务器软件。关于数据、数据添加、删除
和数据更新的所有请求都由服务器软件完成。这些请求或更改来自运行
客户机软件的计算机。客户机是与用户打交道的软件。例如,如果你请
求一个按字母顺序列出的产品表,则客户机软件通过网络提交该请求给
服务器软件。服务器软件处理这个请求,根据需要过滤、丢弃和排序数
据;然后把结果送回到你的客户机软件。
有多少计算机? 客户机和服务器软件可能安装在两台计算
机或一台计算机上。不管它们在不在相同的计算机上,为进行
所有数据库交互,客户机软件都要与服务器软件进行通信。
所有这些活动对用户都是透明的。数据存储在别的地方,或者数据
库服务器为你完成这个处理这一事实是隐藏的。你不需要直接访问数据
文件。事实上,多数网络的建立使用户不具有对数据的访问权,甚至不
具有对存储数据的驱动器的访问权。
这样的意义何在?因为为了使用MySQL,你需要访问运行MySQL服
务器软件的计算机和发布命令到MySQL的客户机软件的计算机。
· 服务器软件为MySQL DBMS。你可以在本地安装的副本上运行,也可以连接到运行在你具有访问权的远程服务器上的一个副本。
· 客户机可以是MySQL提供的工具、脚本语言(如Perl)、Web应用
开发语言(如ASP、ColdFusion、JSP和PHP) 、程序设计语言(如
C、C++、Java)等。
2.1.2 MySQL版本
客户机工具稍后介绍。我们先简要介绍DBMS版本。
14
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com10 第 2章 MySQL简介
MySQL的当前版本为版本5① (虽然许多公司正在使用MySQL 3和4)。
下面是最近版本中引入的主要更改。
· 4——InnoDB引擎,增加事务处理(第26章) 、并(第17章)、改
进全文本搜索(第18章)等的支持。
· 4.1——对函数库、子查询(第14章) 、集成帮助等的重要增加。
· 5——存储过程(第23章) 、触发器(第25章) 、游标(第24章) 、视图(第22章)等。
版本4.1和版本5对MySQL增加了重要的功能,本书中涵盖了这些功
能的大多数。
使用4.1或更高版本 MySQL 4.1对MySQL函数库引入了重要
更改,本书是为使用此版本或更高版本而撰写的。多数内容实
际上也适用于MySQL 3和4,不过许多例子在这两个版本中不
工作。
版本要求说明 如果某章针对具体某个MySQL版本,则将在
该章开始处明确说明。
2.2 MySQL工具
如前所述,MySQL是一个客户机—服务器DBMS,因此,为了使用
MySQL,需要有一个客户机,即你需要用来与MySQL打交道(给MySQL
提供要执行的命令)的一个应用。
有许多客户机应用可供选择,但在学习MySQL(确切地说,在编写
和测试MySQL脚本时),最好是使用专门用途的实用程序。特别是有3个
工具需要提及。
① 目前最新的稳定版本为5.1。——编者注
15
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com2.2 MySQL 工具 11
2.2.1 mysql命令行实用程序
每个MySQL安装都有一个名为mysql的简单命令行实用程序。这
个实用程序没有下拉菜单、流行的用户界面、鼠标支持或任何类似的
东西。
在操作系统命令提示符下输入mysql将出现一个如下的简单提示:
MySQL选项和参数 如果仅输入mysql, 可能会出现一个错误
消息。因为可能需要安全证书,或者是因为MySQL没有运行
在本地或默认端口上。mysql接受你可以(和可能需要)使用
的一组命令行参数。例如,为了指定用户登录名ben,应该使
用mysql -u ben。为了给出用户名、主机名、端口和口令,应该使用mysql -u ben -p -h myserver -P 9999。
完整的命令行选项和参数列表可用mysql --help获得。
当然,具体的版本和连接信息可能不同,但都可以使用这个实用程
序。请注意:
· 命令输入在mysql>之后;
· 命令用;或\g结束,换句话说,仅按Enter不执行命令;
· 输入help或\h获得帮助,也可以输入更多的文本获得特定命令的
帮助(如,输入help select获得使用SELECT语句的帮助) ;
· 输入quit或exit退出命令行实用程序。
mysql命令行实用程序是使用最多的实用程序之一,它对于快速测试
和执行脚本(如前一章和附录B中的样例表创建和填充脚本)非常有价
值。事实上,本书中使用的所有输出例子都是从mysql命令行输出中抓取
的。
16
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com12 第 2章 MySQL简介
熟悉mysql命令行实用程序 即使你选择使用后面描述的某
个图形工具,也应该保证熟悉mysql命令行实用程序,因为它
是你可以安全地依靠的一个总是会被给出的客户机 (因为它是
核心MySQL安装的一部分) 。
2.2.2 MySQL Administrator
MySQL Administrator(MySQL管理器)是一个图形交互客户机,用
来简化MySQL服务器的管理。
获得MySQL Administrator MySQL Administrator不作为核心
MySQL 的组成部分安装。必须从 http:dev.mysql.com
downloads下载它(可得到用于Linux、Mac OS X和Windows
的版本,其源代码也可以下载)。
MySQL Administrator提示输入服务器和登录信息(并且允许你保存
服务器定义供以后选择),然后显示允许选择不同视图的图标。其中:
· Server Information(服务器信息)显示客户机和被连接的服务器的
状态和版本信息;
· Service Control(服务控制)允许停止和启动MySQL以及指定服务
器特性;
· User Administration(用户管理)用来定义MySQL用户、登录和权
限;
· Catalogs(目录)列出可用的数据库并允许创建数据库和表。
为本书创建数据源 可以使用Create New Schema选项为本书
的表和各章节创建一个数据源。书中各个例子使用一个名为
crashcourse的数据源,你可以使用这个名字,也可以使用自
己选择的名字。
17
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com2.2 MySQL 工具 13
快速访问其他工具 MySQL Administrator工具菜单包含有启
动mysql命令行实用程序 (前面描述) 和MySQL Query Browser
(MySQL查询浏览器) (下面描述)的选项。
MySQL Query Browser也包含启动mysql命令行实用程序和
MySQL Administrator的菜单选项。
2.2.3 MySQL Query Browser
MySQL Query Browser为一个图形交互客户机,用来编写和执行
MySQL命令。
获得MySQL Query Browser 与MySQL Administrator一样,MySQL Query Browser不作为核心MySQL安装的成分。也必须
从http:dev.mysql.comdownloads下载它(可得到用于Linux、Mac OS X和Windows的版本,其源代码也可以下载) 。
MySQL Query Browser要求输入服务器和登录信息(在MySQL Query
Browser和MySQL Administrator之间共享保存的定义),然后显示应用界
面。注意下面几点。
· 输入MySQL命令到屏幕顶上的窗口中。在输入语句后,单击
Execute按钮把它提交给MySQL处理。
· 结果(如果有)显示在屏幕左边的大区域网格中。
· 多条语句和结果显示在它们自己的标签中,并且允许快速切换。
· 屏幕右边是一个标签,它列出所有可能的数据源(这里称为大纲),展开任一数据源查看它的表,展开任一个表查看它的列。
· 你还可以选择表和列让MySQL Query Browser为你编写MySQL语
句。
· Schemata(大纲)标签的右边是一个History(历史)标签,它保
持MySQL语句的执行历史。在需要测试不同版本的MySQL语句
时,它非常有用。
· 关于MySQL语法、函数等的帮助可在屏幕右下角得到。
18
19
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com14 第 2章 MySQL简介
执行保存的脚本 可用MySQL Query Browser执行保存的脚
本(如用来创建和填充本书中使用的表的脚本) 。为执行保存
的脚本,请选择File, Open Script,选择相应的脚本(它将显
示在一个新标签中),然后单击Execute按钮。
2.3 小结
本章介绍了什么是MySQL,并引入了几个客户机实用程序(一个命
令行实用程序,两个可选但强烈建议使用的图形实用程序) 。
20
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
使用MySQL
本章将学习如何连接和登录到MySQL,如何执行MySQL语句,以及
如何获得数据库和表的信息。
3.1 连接
在具有可供使用的MySQL DBMS和客户机软件之后,有必要简要讨
论一下如何连接到数据库。
MySQL与所有客户机—服务器DBMS一样,要求在能执行命令之前登
录到DBMS。 登录名可以与网络登录名不相同(假定你使用网络) 。 MySQL
在内部保存自己的用户列表,并且把每个用户与各种权限关联起来。
在最初安装MySQL时,很可能会要求你输入一个管理登录(通常为
root)和一个口令。如果你使用的是自己的本地服务器,并且是简单地
试验一下MySQL,使用上述登录就可以了。但现实中,管理登录受到密
切保护(因为对它的访问授予了创建表、删除整个数据库、更改登录和
口令等完全的权限) 。
使用MySQL Administrator MySQL Administrator Users视图
提供了一个简单的界面,可用来定义新用户,包括赋予口令和
访问权限。
为了连接到MySQL,需要以下信息:
· 主机名(计算机名)——如果连接到本地MySQL服务器, 为localhost;
· 端口(如果使用默认端口3306之外的端口) ;
第3章
21
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com16 第 3章 使用MySQL
· 一个合法的用户名;
· 用户口令(如果需要) 。
如第2章所述,所有这些信息都可以传递给mysql命令行实用程序,或
输入到MySQL Administrator和MySQL Query Browser的服务器连接屏幕。
使用其他客户机 如果你使用的客户机不是这里提到的客户
机,则为了连接到MySQL,仍然需要提供上述信息。
在连接之后,你就可以访问你的登录名能够访问的任意数据库和表
了。 (登录、访问控制和安全可参阅第28章。 )
3.2 选择数据库
在你最初连接到MySQL时,没有任何数据库打开供你使用。在你能
执行任意数据库操作前,需要选择一个数据库。为此,可使用USE关键字。
关键字(key word) 作为MySQL语言组成部分的一个保留字。决
不要用关键字命名一个表或列。附录E列出了MySQL的关键字。
例如,为了使用crashcourse数据库,应该输入以下内容:
USE语句并不返回任何结果。依赖于使用的客户机,显示某种
形式的通知。例如,这里显示出的Database changed消息是
mysql命令行实用程序在数据库选择成功后显示的。
使用MySQL Query Browser 在MySQL Query Browser中, 双
击Schemata列表中列出的任一数据库以使用它。你看不到USE
命令的实际执行,但会看到被选择的数据库(黑体加亮) ,而
且应用标题栏将显示所选择的数据库名。
记住,必须先使用USE打开数据库,才能读取其中的数据。
输入
输出
分析
22
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com3.3 了解数据库和表 17
3.3 了解数据库和表
如果你不知道可以使用的数据库名时怎么办?这时,MySQL
Administrator和MySQL Query Browser怎样能显示可用的数据库列表?
数据库、表、列、用户、权限等的信息被存储在数据库和表中 (MySQL
使用MySQL来存储这些信息)。不过,内部的表一般不直接访问。可用
MySQL的SHOW命令来显示这些信息(MySQL从内部表中提取这些信息) 。
请看下面的例子:
SHOW DATABASES;返回可用数据库的一个列表。包含在这个列
表中的可能是MySQL内部使用的数据库(如例子中的mysql和
information_schema) 。当然,你自己的数据库列表可能看上去与这里的
不一样。
为了获得一个数据库内的表的列表,使用SHOW TABLES;,如下所示:
输入
输出
分析
输入
输出
23
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com18 第 3章 使用MySQL
SHOW TABLES;返回当前选择的数据库内可用表的列表。
SHOW也可以用来显示表列:
输出
SHOW COLUMNS要求给出一个表名(这个例子中的FROM
customers) ,它对每个字段返回一行,行中包含字段名、数据
类型、是否允许NULL、键信息、默认值以及其他信息(如字段cust_id
的auto_increment)。
什么是自动增量? 某些表列需要唯一值。例如,订单编号、雇员ID或(如上面例子中所示的)顾客ID。在每个行添加到表
中时,MySQL可以自动地为每个行分配下一个可用编号,不
用在添加一行时手动分配唯一值(这样做必须记住最后一次使
用的值) 。这个功能就是所谓的自动增量。如果需要它,则必
须在用CREATE语句创建表时把它作为表定义的组成部分。我们
将在第21章中介绍CREATE语句。
DESCRIBE语句 MySQL支持用DESCRIBE作为SHOW COLUMNS
FROM的一种快捷方式。换句话说,DESCRIBE customers;是
SHOW COLUMNS FROM customers;的一种快捷方式。
所支持的其他SHOW语句还有:
输入
分析
分析
24
25
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com3.4 小结 19
· SHOW STATUS,用于显示广泛的服务器状态信息;
· SHOW CREATE DATABASE和SHOW CREATE TABLE,分别用来显示创
建特定数据库或表的MySQL语句;
· SHOW GRANTS,用来显示授予用户(所有用户或特定用户)的安
全权限;
· SHOW ERRORS和SHOW WARNINGS, 用来显示服务器错误或警告消息。
值得注意的是,客户机应用程序使用与这里相同的MySQL命令。显
示数据库和表的交互式列表、允许交互式创建和编辑表、便于数据录入
和编辑或允许管理用户账号和权限等的应用全都使用你可以直接执行的
相同的MySQL命令完成它们的工作。
进一步了解SHOW 请在mysql命令行实用程序中,执行命令
HELP SHOW;显示允许的SHOW语句。
MySQL 5的新增内容 MySQL 5支持一个新的INFORMA-
TION_SCHEMA命令,可用它来获得和过滤模式信息。
3.4 小结
本章介绍了如何连接和登录MySQL,如何用USE选择数据库,如何用
SHOW查看MySQL数据库、表和内部信息。在这些知识的帮助下,我们可
以进一步深入学习所有重要的SELECT语句了。
26
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
检 索 数 据
本章将介绍如何使用SELECT语句从表中检索一个或多个数据列。
4.1 SELECT语句
正如第1章所述,SQL语句是由简单的英语单词构成的。这些单词称
为关键字,每个SQL语句都是由一个或多个关键字构成的。大概,最经常
使用的SQL语句就是SELECT语句了。它的用途是从一个或多个表中检索
信息。
为了使用SELECT检索表数据,必须至少给出两条信息——想选择什
么,以及从什么地方选择。
4.2 检索单个列
我们将从简单的SQL SELECT语句开始介绍,此语句如下所示:
上述语句利用SELECT语句从products表中检索一个名为
prod_name的列。所需的列名在SELECT关键字之后给出,FROM
关键字指出从其中检索数据的表名。此语句的输出如下所示:
第4章
输入
分析
输出
27
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com欢迎点击这里的链接进入精彩的Linux公社 网
站
Linux公社(www.Linuxidc.com)于2006年9月25日注
册并开通网站,Linux现在已经成为一种广受关注和
支持的一种操作系统,IDC是互联网数据中心,LinuxIDC就是关于Linux的数据中心。
Linux公社是专业的Linux系统门户网站,实时发布最
新Linux资讯,包括Linux、Ubuntu、Fedora、RedHat、红旗Linux、Linux教程、Linux认证、SUSE
Linux、Android、Oracle、Hadoop、CentOS、MySQL、Apache、Nginx、Tomcat、Python、Java、C语言、OpenStack、集群等技术。
Linux公社(LinuxIDC.com)设置了有一定影响力的
Linux专题栏目。
Linux公社 主站网址:www.linuxidc.com 旗下
网站:www.linuxidc.net
包括:Ubuntu 专题 Fedora专题 Android 专题
Oracle专题 Hadoop 专题 RedHat 专题 SUSE
专题 红旗 Linux 专题 CentOS专题
Linux 公社微信公众号:linuxidc_com
4.2 检索单个列 21
未排序数据 如果读者自己试验这个查询,可能会发现显示输
出的数据顺序与这里的不同。出现这种情况很正常。如果没有
明确排序查询结果(下一章介绍),则返回的数据的顺序没有
特殊意义。返回数据的顺序可能是数据被添加到表中的顺序,也可能不是。只要返回相同数目的行,就是正常的。
如上的一条简单SELECT语句将返回表中所有行。数据没有过滤 (过
滤将得出结果集的一个子集) , 也没有排序。以后几章将讨论这些内容。
结束SQL语句 多条SQL语句必须以分号(;)分隔。MySQL
如同多数DBMS一样,不需要在单条SQL语句后加分号。但特
定的DBMS可能必须在单条SQL语句后加上分号。当然,如果
愿意可以总是加上分号。事实上,即使不一定需要,但加上
分号肯定没有坏处。如果你使用的是mysql命令行,必须加上
分号来结束SQL语句。
SQL语句和大小写 请注意,SQL语句不区分大小写,因此
SELECT与select是相同的。同样,写成Select也没有关系。
许多SQL开发人员喜欢对所有SQL关键字使用大写,而对所有
列和表名使用小写,这样做使代码更易于阅读和调试。
28
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com22 第 4章 检 索 数 据
不过,一定要认识到虽然SQL是不区分大小写的,但有些标识
符(如数据库名、表名、列名)可能不同:在MySQL 4.1及之
前的版本中, 这些标识符默认是区分大小写的; 在MySQL 4.1.1
版本中,这些标识符默认是不区分大小写的。
最佳方式是按照大小写的惯例,且使用时保持一致。
使用空格 在处理SQL语句时,其中所有空格都被忽略。SQL
语句可以在一行上给出,也可以分成许多行。多数SQL开发人
员认为将SQL语句分成多行更容易阅读和调试。
4.3 检索多个列
要想从一个表中检索多个列,使用相同的SELECT语句。唯一的不同
是必须在SELECT关键字后给出多个列名,列名之间必须以逗号分隔。
当心逗号 在选择多个列时,一定要在列名之间加上逗号,但
最后一个列名后不加。如果在最后一个列名后加了逗号,将出
现错误。
下面的SELECT语句从products表中选择3列:
与前一个例子一样,这条语句使用SELECT语句从表products
中选择数据。在这个例子中,指定了3个列名,列名之间用逗
号分隔。此语句的输出如下:
输入
分析
输出
29
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com4.4 检索所有列 23
数据表示 从上述输出可以看到,SQL语句一般返回原始的、无格式的数据。数据的格式化是一个表示问题,而不是一个
检索问题。因此,表示(对齐和显示上面的价格值,用货币
符号和逗号表示其金额)一般在显示该数据的应用程序中规
定。一般很少使用实际检索出的原始数据(没有应用程序提
供的格式) 。
4.4 检索所有列
除了指定所需的列外(如上所述,一个或多个列) ,SELECT语句还可
以检索所有的列而不必逐个列出它们。这可以通过在实际列名的位置使
用星号()通配符来达到,如下所示:
如果给定一个通配符() ,则返回表中所有列。列的顺序一般
是列在表定义中出现的顺序。但有时候并不是这样的,表的模
式的变化(如添加或删除列)可能会导致顺序的变化。
使用通配符 一般,除非你确实需要表中的每个列,否则最
好别使用通配符。虽然使用通配符可能会使你自己省事,不
用明确列出所需列,但检索不需要的列通常会降低检索和应
用程序的性能。
输入
分析
30
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com24 第 4章 检 索 数 据
检索未知列 使用通配符有一个大优点。由于不明确指定列
名(因为星号检索每个列),所以能检索出名字未知的列。
4.5 检索不同的行
正如所见,SELECT返回所有匹配的行。但是,如果你不想要每个值
每次都出现,怎么办?例如,假如你想得出products表中产品的所有供
应商ID:
SELECT语句返回14行(即使表中只有4个供应商) ,因为products表
中列出了14个产品。那么,如何检索出有不同值的列表呢?
解决办法是使用DISTINCT关键字,顾名思义,此关键字指示MySQL
只返回不同的值。
SELECT DISTINCT vend_id告诉MySQL只返回不同(唯一)的
vend_id行,因此只返回4行,如下面的输出所示。如果使用
DISTINCT关键字,它必须直接放在列名的前面。
输入
输出
输入
分析
31
32
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com4.6 限制结果 25
不能部分使用DISTINCT DISTINCT关键字应用于所有列而
不仅是前置它的列。如果给出SELECT DISTINCT vend_id,prod_price,除非指定的两个列都不同,否则所有行都将被
检索出来。
4.6 限制结果
SELECT语句返回所有匹配的行,它们可能是指定表中的每个行。为
了返回第一行或前几行,可使用LIMIT子句。下面举一个例子:
此语句使用SELECT语句检索单个列。LIMIT 5指示MySQL返回
不多于5行。此语句的输出如下所示:
为得出下一个5行,可指定要检索的开始行和行数,如下所示:
LIMIT 5, 5指示MySQL返回从行5开始的5行。第一个数为开始
位置,第二个数为要检索的行数。此语句的输出如下所示:
输出
输入
输出
分析
输入
分析
33
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com26 第 4章 检 索 数 据
所以, 带一个值的LIMIT总是从第一行开始,给出的数为返回的行数。
带两个值的LIMIT可以指定从行号为第一个值的位置开始。
行0 检索出来的第一行为行0而不是行1。因此,LIMIT 1, 1
将检索出第二行而不是第一行。
在行数不够时 LIMIT中指定要检索的行数为检索的最大行
数。如果没有足够的行(例如,给出LIMIT 10, 5,但只有13
行) ,MySQL将只返回它能返回的那么多行。
MySQL 5的LIMIT语法 LIMIT 3, 4的含义是从行4开始的3
行还是从行3开始的4行?如前所述,它的意思是从行3开始的4
行,这容易把人搞糊涂。
由于这个原因, MySQL 5支持LIMIT的另一种替代语法。 LIMIT
4 OFFSET 3意为从行3开始取4行,就像LIMIT 3, 4一样。
4.7 使用完全限定的表名
迄今为止使用的SQL例子只通过列名引用列。 也可能会使用完全限定
的名字来引用列(同时使用表名和列字)。请看以下例子:
这条SQL语句在功能上等于本章最开始使用的那一条语句, 但这里指
输出
输入
34
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com4.8 小结 27
定了一个完全限定的列名。
表名也可以是完全限定的,如下所示:
这条语句在功能上也等于刚使用的那条语句(当然,假定products
表确实位于crashcourse数据库中) 。
正如以后章节所介绍的那样,有一些情形需要完全限定名。现在,需要注意这个语法,以便在遇到时知道它的作用。
4.8 小结
本章学习了如何使用SQL的SELECT语句来检索单个表列、多个表列
以及所有表列。下一章将讲授如何排序检索出来的数据。
输入
35
36
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
排序检索数据
本章将讲授如何使用SELECT语句的ORDER BY子句,根据需要排序检
索出的数据。
5.1 排序数据
正如前一章所述,下面的SQL语句返回某个数据库表的单个列。但请
看其输出,并没有特定的顺序。
其实,检索出的数据并不是以纯粹的随机顺序显示的。如果不排
序,数据一般将以它在底层表中出现的顺序显示。这可以是数据最初
第5章
输入
输出
37
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com5.1 排序数据 29
添加到表中的顺序。但是,如果数据后来进行过更新或删除,则此顺
序将会受到MySQL重用回收存储空间的影响。因此,如果不明确控
制的话,不能(也不应该)依赖该排序顺序。关系数据库设计理论认
为,如果不明确规定排序顺序,则不应该假定检索出的数据的顺序有
意义。
子句(clause) SQL语句由子句构成,有些子句是必需的,而
有的是可选的。一个子句通常由一个关键字和所提供的数据组
成。子句的例子有SELECT语句的FROM子句,我们在前一章看到过这个子
句。
为了明确地排序用SELECT语句检索出的数据,可使用ORDER BY子句。
ORDER BY子句取一个或多个列的名字,据此对输出进行排序。请看下面
的例子:
这条语句除了指示MySQL对prod_name列以字母顺序排序数据
的ORDER BY子句外,与前面的语句相同。结果如下:
输入
输出
分析
38
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com30 第 5章 排序检索数据
通过非选择列进行排序 通常,ORDER BY子句中使用的列将
是为显示所选择的列。但是,实际上并不一定要这样,用非
检索的列排序数据是完全合法的。
5.2 按多个列排序
经常需要按不止一个列进行数据排序。例如,如果要显示雇员清单,可能希望按姓和名排序(首先按姓排序,然后在每个姓中再按名排序) 。
如果多个雇员具有相同的姓,这样做很有用。
为了按多个列排序,只要指定列名,列名之间用逗号分开即可(就
像选择多个列时所做的那样) 。
下面的代码检索3个列,并按其中两个列对结果进行排序——首先按
价格,然后再按名称排序。
重要的是理解在按多个列排序时,排序完全按所规定的顺序进行。
换句话说,对于上述例子中的输出,仅在多个行具有相同的prod_price
值时才对产品按prod_name进行排序。如果prod_price列中所有的值都是
输入
输出
39
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com5.3 指定排序方向 31
唯一的,则不会按prod_name排序。
5.3 指定排序方向
数据排序不限于升序排序(从A到Z) 。这只是默认的排序顺序,还可
以使用ORDER BY子句以降序(从Z到A)顺序排序。为了进行降序排序,必须指定DESC关键字。
下面的例子按价格以降序排序产品(最贵的排在最前面) :
但是,如果打算用多个列排序怎么办?下面的例子以降序排序产品
(最贵的在最前面) ,然后再对产品名排序:
输入
输出
输入
输出
40
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com32 第 5章 排序检索数据
DESC关键字只应用到直接位于其前面的列名。在上例中,只对
prod_price列指定DESC,对prod_name列不指定。因此,prod_price列以降序排序,而prod_name列(在每个价格内)仍然按标准
的升序排序。
在多个列上降序排序 如果想在多个列上进行降序排序, 必须
对每个列指定DESC关键字。
与DESC相反的关键字是ASC (ASCENDING), 在升序排序时可以指定它。
但实际上,ASC没有多大用处,因为升序是默认的(如果既不指定ASC也
不指定DESC,则假定为ASC)。
区分大小写和排序顺序 在对文本性的数据进行排序时,A与
a相同吗?a位于B之前还是位于Z之后?这些问题不是理论问
题,其答案取决于数据库如何设置。
在字典 (dictionary) 排序顺序中, A被视为与a相同, 这是MySQL
(和大多数数据库管理系统)的默认行为。但是,许多数据库
管理员能够在需要时改变这种行为(如果你的数据库包含大量
外语字符,可能必须这样做) 。
这里,关键的问题是,如果确实需要改变这种排序顺序,用简
单的ORDER BY子句做不到。你必须请求数据库管理员的帮助。
分析
41
42
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com5.4 小结 33
使用ORDER BY和LIMIT的组合,能够找出一个列中最高或最低的值。
下面的例子演示如何找出最昂贵物品的值:
prod_price DESC保证行是按照由最昂贵到最便宜检索的,而
LIMIT 1告诉MySQL仅返回一行。
ORDER BY子句的位置 在给出ORDER BY子句时,应该保证它
位于FROM子句之后。如果使用LIMIT,它必须位于ORDER BY
之后。使用子句的次序不对将产生错误消息。
5.4 小结
本章学习了如何用SELECT语句的ORDER BY子句对检索出的数据进行
排序。这个子句必须是SELECT语句中的最后一条子句。可根据需要,利
用它在一个或多个列上对数据进行排序。
输入
输出
分析
43
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
过 滤 数 据
本章将讲授如何使用SELECT语句的WHERE子句指定搜索条件。
6.1 使用WHERE子句
数据库表一般包含大量的数据,很少需要检索表中所有行。通常只
会根据特定操作或报告的需要提取表数据的子集。只检索所需数据需要
指定搜索条件(search criteria),搜索条件也称为过滤条件(filter
condition)。
在SELECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤。
WHERE子句在表名(FROM子句)之后给出,如下所示:
这条语句从products表中检索两个列,但不返回所有行,只返
回prod_price值为2.50的行,如下所示:
这个例子采用了简单的相等测试:它检查一个列是否具有指定的值,据此进行过滤。但是SQL允许做的事情不仅仅是相等测试。
第6章
输入
分析
输出
45
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com6.2 WHERE 子句操作符 35
SQL过滤与应用过滤 数据也可以在应用层过滤。为此目
的,SQL的SELECT语句为客户机应用检索出超过实际所需的
数据,然后客户机代码对返回数据进行循环,以提取出需要
的行。
通常,这种实现并不令人满意。因此,对数据库进行了优化,以便快速有效地对数据进行过滤。让客户机应用(或开发语言)
处理数据库的工作将会极大地影响应用的性能,并且使所创建
的应用完全不具备可伸缩性。此外,如果在客户机上过滤数据,服务器不得不通过网络发送多余的数据,这将导致网络带宽的
浪费。
WHERE子句的位置 在同时使用ORDER BY和WHERE子句时,应
该让ORDER BY位于WHERE之后, 否则将会产生错误(关于ORDER
BY的使用,请参阅第5章) 。
6.2 WHERE子句操作符
我们在关于相等的测试时看到了第一个WHERE子句,它确定一个列是
否包含特定的值。MySQL支持表6-1列出的所有条件操作符。
表6-1 WHERE子句操作符
操 作 符 说 明
= 等于
<> 不等于!= 不等于
< 小于
<= 小于等于
> 大于
>= 大于等于
BETWEEN 在指定的两个值之间
46
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com36 第 6章 过 滤 数 据
6.2.1 检查单个值
我们已经看到了测试相等的例子。再来看一个类似的例子:
检查WHERE prod_name=‘fuses’语句,它返回prod_name的值
为Fuses的一行。MySQL在执行匹配时默认不区分大小写,所
以fuses与Fuses匹配。
现在来看几个使用其他操作符的例子。
第一个例子是列出价格小于10美元的所有产品:
下一条语句检索价格小于等于10美元的所有产品(输出的结果比第
一个例子输出的结果多两种产品) :
输入
输出
输入
输入
输出
输出
分析
47
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com6.2 WHERE 子句操作符 37
6.2.2 不匹配检查
以下例子列出不是由供应商1003制造的所有产品:
何时使用引号 如果仔细观察上述WHERE子句中使用的条件,会看到有的值括在单引号内(如前面使用的'fuses') ,而有
的值未括起来。单引号用来限定字符串。如果将值与串类型的
列进行比较,则需要限定引号。用来与数值列进行比较的值不
用引号。
下面是相同的例子,其中使用!=而不是<>操作符:
6.2.3 范围值检查
为了检查某个范围的值,可使用BETWEEN操作符。其语法与其他WHERE
输入
输出
输入
48
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com38 第 6章 过 滤 数 据
子句的操作符稍有不同,因为它需要两个值,即范围的开始值和结束值。
例如,BETWEEN操作符可用来检索价格在5美元和10美元之间或日期在指
定的开始日期和结束日期之间的所有产品。
下面的例子说明如何使用BETWEEN操作符,它检索价格在5美元和10
美元之间的所有产品:
从这个例子中可以看到,在使用BETWEEN时,必须指定两个值
——所需范围的低端值和高端值。这两个值必须用AND关键字
分隔。BETWEEN匹配范围中所有的值,包括指定的开始值和结束值。
6.2.4 空值检查
在创建表时,表设计人员可以指定其中的列是否可以不包含值。在
一个列不包含值时,称其为包含空值NULL。
NULL 无值(no value) ,它与字段包含0、空字符串或仅仅包含
空格不同。
SELECT语句有一个特殊的WHERE子句,可用来检查具有NULL值的列。
这个WHERE子句就是IS NULL子句。其语法如下:
这条语句返回没有价格(空prod_price字段,不是价格为0)的所有
产品,由于表中没有这样的行,所以没有返回数据。但是,customers
表确实包含有具有空值的列,如果在文件中没有某位顾客的电子邮件地
输入
输出
分析
输入
49
50
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com6.3 小结 39
址,则cust_email列将包含NULL值:
NULL与不匹配 在通过过滤选择出不具有特定值的行时,你
可能希望返回具有NULL值的行。但是,不行。因为未知具有
特殊的含义,数据库不知道它们是否匹配,所以在匹配过滤
或不匹配过滤时不返回它们。
因此,在过滤数据时,一定要验证返回数据中确实给出了被
过滤列具有NULL的行。
6.3 小结
本章介绍了如何用SELECT语句的WHERE子句过滤返回的数据。我们学
习了如何对相等、不相等、大于、小于、值的范围以及NULL值等进行测
试。
输入
输出
51
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
数 据 过 滤
本章讲授如何组合WHERE子句以建立功能更强的更高级的搜索条件。
我们还将学习如何使用NOT和IN操作符。
7.1 组合WHERE子句
第6章中介绍的所有WHERE子句在过滤数据时使用的都是单一的条
件。为了进行更强的过滤控制,MySQL允许给出多个WHERE子句。这些子
句可以两种方式使用:以AND子句的方式或OR子句的方式使用。
操作符(operator) 用来联结或改变WHERE子句中的子句的关键
字。也称为逻辑操作符(logical operator)。
7.1.1 AND操作符
为了通过不止一个列进行过滤,可使用AND操作符给WHERE子句附加
条件。下面的代码给出了一个例子:
此SQL语句检索由供应商1003制造且价格小于等于10美元的所
有产品的名称和价格。这条SELECT语句中的WHERE子句包含两
个条件,并且用AND关键字联结它们。AND指示DBMS只返回满足所有给
定条件的行。如果某个产品由供应商1003制造,但它的价格高于10美元,则不检索它。类似,如果产品价格小于10美元,但不是由指定供应商制
造的也不被检索。这条SQL语句产生的输出如下:
第7章
输入
分析
53
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com7.1 组合 WHERE 子句 41
AND 用在WHERE子句中的关键字,用来指示检索满足所有给定
条件的行。
上述例子中使用了只包含一个关键字AND的语句,把两个过滤条件组
合在一起。还可以添加多个过滤条件,每添加一条就要使用一个AND。
7.1.2 OR操作符
OR操作符与AND操作符不同,它指示MySQL检索匹配任一条件的行。
请看如下的SELECT语句:
此SQL语句检索由任一个指定供应商制造的所有产品的产品
名和价格。 OR操作符告诉DBMS匹配任一条件而不是同时匹配
两个条件。如果这里使用的是AND操作符,则没有数据返回(此时创建
的WHERE子句不会检索到匹配的产品) 。这条SQL语句产生的输出如下:
输出
输入
输出
分析
54
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com欢迎点击这里的链接进入精彩的Linux公社 网
站
Linux公社(www.Linuxidc.com)于2006年9月25日注
册并开通网站,Linux现在已经成为一种广受关注和
支持的一种操作系统,IDC是互联网数据中心,LinuxIDC就是关于Linux的数据中心。
Linux公社是专业的Linux系统门户网站,实时发布最
新Linux资讯,包括Linux、Ubuntu、Fedora、RedHat、红旗Linux、Linux教程、Linux认证、SUSE
Linux、Android、Oracle、Hadoop、CentOS、MySQL、Apache、Nginx、Tomcat、Python、Java、C语言、OpenStack、集群等技术。
Linux公社(LinuxIDC.com)设置了有一定影响力的
Linux专题栏目。
Linux公社 主站网址:www.linuxidc.com 旗下
网站:www.linuxidc.net
包括:Ubuntu 专题 Fedora专题 Android 专题
Oracle专题 Hadoop 专题 RedHat 专题 SUSE
专题 红旗 Linux 专题 CentOS专题
Linux 公社微信公众号:linuxidc_com
42 第 7章 数 据 过 滤
OR WHERE子句中使用的关键字,用来表示检索匹配任一给定
条件的行。
7.1.3 计算次序
WHERE可包含任意数目的AND和OR操作符。允许两者结合以进行复杂
和高级的过滤。
但是,组合AND和OR带来了一个有趣的问题。为了说明这个问题,来
看一个例子。假如需要列出价格为10美元(含)以上且由1002或1003制
造的所有产品。下面的SELECT语句使用AND和OR操作符的组合建立了一个
WHERE子句:
请看上面的结果。返回的行中有两行价格小于10美元,显然,返回的行未按预期的进行过滤。为什么会这样呢?原因在于计
算的次序。SQL(像多数语言一样)在处理OR操作符前,优先处理AND操
作符。当SQL看到上述WHERE子句时,它理解为由供应商1003制造的任何
价格为10美元(含)以上的产品,或者由供应商1002制造的任何产品,而不管其价格如何。换句话说,由于AND在计算次序中优先级更高,操作
符被错误地组合了。
此问题的解决方法是使用圆括号明确地分组相应的操作符。请看下
面的SELECT语句及输出:
输入
分析
输出
输入
55
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com7.2 IN操作符 43
这条SELECT语句与前一条的唯一差别是,这条语句中,前两个
条件用圆括号括了起来。因为圆括号具有较AND或OR操作符高
的计算次序,DBMS首先过滤圆括号内的OR条件。这时,SQL语句变成了
选择由供应商1002或1003制造的且价格都在10美元(含)以上的任何产
品,这正是我们所希望的。
在WHERE子句中使用圆括号 任何时候使用具有AND和OR操作
符的WHERE子句,都应该使用圆括号明确地分组操作符。不要
过分依赖默认计算次序,即使它确实是你想要的东西也是如
此。使用圆括号没有什么坏处,它能消除歧义。
7.2 IN操作符
圆括号在WHERE子句中还有另外一种用法。IN操作符用来指定条件范
围,范围中的每个条件都可以进行匹配。IN取合法值的由逗号分隔的清
单,全都括在圆括号中。下面的例子说明了这个操作符:
输出
分析
输入
输出
56
57
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com44 第 7章 数 据 过 滤
此SELECT语句检索供应商1002和1003制造的所有产品。IN操
作符后跟由逗号分隔的合法值清单,整个清单必须括在圆括号
中。
如果你认为IN操作符完成与OR相同的功能,那么你的这种猜测是对
的。下面的SQL语句完成与上面的例子相同的工作:
为什么要使用IN操作符?其优点具体如下。
· 在使用长的合法选项清单时,IN操作符的语法更清楚且更直观。
· 在使用IN时,计算的次序更容易管理(因为使用的操作符更少) 。
· IN操作符一般比OR操作符清单执行更快。
· IN的最大优点是可以包含其他SELECT语句,使得能够更动态地建
立WHERE子句。第14章将对此进行详细介绍。
IN WHERE子句中用来指定要匹配值的清单的关键字,功能与OR
相当。
7.3 NOT操作符
WHERE子句中的NOT操作符有且只有一个功能,那就是否定它之后所
跟的任何条件。
NOT WHERE子句中用来否定后跟条件的关键字。
分析
输入
输出
58
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com7.4 小结 45
下面的例子说明NOT的使用。为了列出除1002和1003之外的所有供应
商制造的产品,可编写如下的代码:
这里的NOT否定跟在它之后的条件,因此, MySQL不是匹配1002
和1003的vend_id,而是匹配1002和1003之外供应商的
vend_id。
为什么使用NOT?对于简单的WHERE子句,使用NOT确实没有什么优
势。但在更复杂的子句中,NOT是非常有用的。例如,在与IN操作符联合
使用时,NOT使找出与条件列表不匹配的行非常简单。
MySQL中的NOT MySQL支持使用NOT对IN、BETWEEN和
EXISTS子句取反,这与多数其他DBMS允许使用NOT对各种条件
取反有很大的差别。
7.4 小结
本章讲授如何用AND和OR操作符组合成WHERE子句,而且还讲授了如
何明确地管理计算的次序,如何使用IN和NOT操作符。
输入
输出
分析
59
60
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
用通配符进行过滤
本章介绍什么是通配符、如何使用通配符以及怎样使用LIKE操作符
进行通配搜索,以便对数据进行复杂过滤。
8.1 LIKE操作符
前面介绍的所有操作符都是针对已知值进行过滤的。不管是匹配一
个还是多个值,测试大于还是小于已知值,或者检查某个范围的值,共
同点是过滤中使用的值都是已知的。但是,这种过滤方法并不是任何时
候都好用。例如,怎样搜索产品名中包含文本anvil的所有产品?用简单
的比较操作符肯定不行,必须使用通配符。利用通配符可创建比较特定
数据的搜索模式。在这个例子中,如果你想找出名称包含anvil的所有产
品,可构造一个通配符搜索模式,找出产品名中任何位置出现anvil的产
品。
通配符(wildcard) 用来匹配值的一部分的特殊字符。
搜索模式(search pattern) ① 由字面值、通配符或两者组合构
成的搜索条件。
通配符本身实际是SQL的WHERE子句中有特殊含义的字符,SQL支持几
种通配符。
① 数据库中的schema(见1.1.2节)和pattern都译作“模式”,特此说明,请读者注意。
——编者注
第8章
61
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com8.1 LIKE操作符 47
为在搜索子句中使用通配符,必须使用LIKE操作符。LIKE指示MySQL,后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较。
谓词 操作符何时不是操作符?答案是在它作为谓词(predi-
cate)时。从技术上说,LIKE是谓词而不是操作符。虽然最终
的结果是相同的,但应该对此术语有所了解,以免在SQL文档
中遇到此术语时不知道。
8.1.1 百分号(%)通配符
最常使用的通配符是百分号(%) 。在搜索串中,%表示任何字符出现
任意次数。例如,为了找出所有以词jet起头的产品,可使用以下SELECT
语句:
此例子使用了搜索模式'jet%'。在执行这条子句时,将检索任
意以jet起头的词。%告诉MySQL接受jet之后的任意字符,不
管它有多少字符。
区分大小写 根据MySQL的配置方式,搜索可以是区分大小
写的。如果区分大小写,'jet%'与JetPack 1000将不匹配。
通配符可在搜索模式中任意位置使用,并且可以使用多个通配符。
下面的例子使用两个通配符,它们位于模式的两端:
输入
输出
分析
输入
62
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com48 第 8章 用通配符进行过滤
搜索模式'%anvil%'表示匹配任何位置包含文本anvil的值,而
不论它之前或之后出现什么字符。
通配符也可以出现在搜索模式的中间,虽然这样做不太有用。下面
的例子找出以s起头以e结尾的所有产品:
重要的是要注意到,除了一个或多个字符外,%还能匹配0个字符。%
代表搜索模式中给定位置的0个、1个或多个字符。
注意尾空格 尾空格可能会干扰通配符匹配。例如,在保存词
anvil时,如果它后面有一个或多个空格,则子句WHERE
prod_name LIKE '%anvil'将不会匹配它们,因为在最后的l
后有多余的字符。解决这个问题的一个简单的办法是在搜索模
式最后附加一个%。一个更好的办法是使用函数(第11章将会
介绍)去掉首尾空格。
注意NULL 虽然似乎%通配符可以匹配任何东西,但有一个例
外,即NULL。即使是WHERE prod_name LIKE '%'也不能匹配
用值NULL作为产品名的行。
8.1.2 下划线(_)通配符
另一个有用的通配符是下划线(_) 。下划线的用途与%一样,但下划
线只匹配单个字符而不是多个字符。
举一个例子:
输出
分析
输入
63
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com8.2 使用通配符的技巧 49
此WHERE子句中的搜索模式给出了后面跟有文本的两个通配
符。结果只显示匹配搜索模式的行:第一行中下划线匹配1,第二行中匹配2。.5 ton anvil产品没有匹配,因为搜索模式要求匹配两
个通配符而不是一个。对照一下,下面的SELECT语句使用%通配符,返回
三行产品:
与%能匹配0个字符不一样,_总是匹配一个字符,不能多也不能少。
8.2 使用通配符的技巧
正如所见,MySQL的通配符很有用。但这种功能是有代价的:通配
符搜索的处理一般要比前面讨论的其他搜索所花时间更长。这里给出一
些使用通配符要记住的技巧。
· 不要过度使用通配符。如果其他操作符能达到相同的目的,应该
使用其他操作符。
· 在确实需要使用通配符时,除非绝对有必要,否则不要把它们用
在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起
来是最慢的。
· 仔细注意通配符的位置。如果放错地方,可能不会返回想要的数
输入
输出
分析
输入
输出
64
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com50 第 8章 用通配符进行过滤
据。
总之,通配符是一种极重要和有用的搜索工具,以后我们经常会用
到它。
8.3 小结
本章介绍了什么是通配符以及如何在WHERE子句中使用SQL通配符,并且还说明了通配符应该细心使用,不要过度使用。
66
65
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
用正则表达式
进行搜索
本章将学习如何在MySQL WHERE子句内使用正则表达式来更好地控
制数据过滤。
9.1 正则表达式介绍
前两章中的过滤例子允许用匹配、比较和通配操作符寻找数据。对
于基本的过滤(或者甚至是某些不那么基本的过滤),这样就足够了。但
随着过滤条件的复杂性的增加,WHERE子句本身的复杂性也有必要增加。
这也就是正则表达式变得有用的地方。正则表达式是用来匹配文本
的特殊的串(字符集合)。如果你想从一个文本文件中提取电话号码,可
以使用正则表达式。如果你需要查找名字中间有数字的所有文件,可以
使用一个正则表达式。如果你想在一个文本块中找到所有重复的单词,可以使用一个正则表达式。如果你想替换一个页面中的所有URL为这些
URL的实际HTML链接, 也可以使用一个正则表达式(对于最后这个例子,或者是两个正则表达式) 。
所有种类的程序设计语言、文本编辑器、操作系统等都支持正则表
达式。有见识的程序员和网络管理员已经关注作为他们技术工具重要内
容的正则表达式很长时间了。
正则表达式用正则表达式语言来建立,正则表达式语言是用来完成
刚讨论的所有工作以及更多工作的一种特殊语言。与任意语言一样,正
则表达式具有你必须学习的特殊的语法和指令。
第9章
67
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com52 第 9章 用正则表达式进行搜索
学习更多内容 完全覆盖正则表达式的内容超出了本书的范
围。虽然基础知识都在这里做了介绍,但对正则表达式更为透
彻的介绍可能还需要参阅作者的《正则表达式必知必会》①。
9.2 使用MySQL正则表达式
那么,正则表达式与MySQL有何关系?已经说过,正则表达式的作
用是匹配文本,将一个模式(正则表达式)与一个文本串进行比较。 MySQL
用WHERE子句对正则表达式提供了初步的支持,允许你指定正则表达式,过滤SELECT检索出的数据。
仅为正则表达式语言的一个子集 如果你熟悉正则表达式, 需
要注意:MySQL仅支持多数正则表达式实现的一个很小的子
集。本章介绍MySQL支持的大多数内容。
我们举几个例子,更清晰地描述正则表达式的概念。
9.2.1 基本字符匹配
我们从一个非常简单的例子开始。下面的语句检索列prod_name包含
文本1000的所有行:
除关键字LIKE被REGEXP替代外,这条语句看上去非常像使用
LIKE的语句(第8章) 。它告诉MySQL:REGEXP后所跟的东西作
为正则表达式(与文字正文1000匹配的一个正则表达式)处理。
① 已由人民邮电出版社出版。——编者注
输入
输出
分析
68
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com9.2 使用 MySQL 正则表达式 53
为什么要费力地使用正则表达式?在刚才的例子中,正则表达式确
实没有带来太多好处(可能还会降低性能),不过,请考虑下面的例子:
这里使用了正则表达式.000。.是正则表达式语言中一个特殊
的字符。它表示匹配任意一个字符,因此,1000和2000都匹配
且返回。
当然,这个特殊的例子也可以用LIKE和通配符来完成(参阅第8章) 。
LIKE与REGEXP 在LIKE和REGEXP之间有一个重要的差别。请
看以下两条语句:
如果执行上述两条语句,会发现第一条语句不返回数据,而第
二条语句返回一行。为什么?
正如第8章所述,LIKE匹配整个列。如果被匹配的文本在列值
中出现,LIKE将不会找到它,相应的行也不被返回(除非使用
通配符)。而REGEXP在列值内进行匹配,如果被匹配的文本在
列值中出现,REGEXP将会找到它,相应的行将被返回。这是一
个非常重要的差别。
那么,REGEXP能不能用来匹配整个列值(从而起与LIKE相同
输入
输出
分析
69
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com54 第 9章 用正则表达式进行搜索
的作用)?答案是肯定的,使用^和定位符(anchor)即可,本章后面介绍。
匹配不区分大小写 MySQL中的正则表达式匹配(自版本
3.23.4后)不区分大小写(即,大写和小写都匹配)。为区分大
小写,可使用BINARY关键字,如WHERE prod_name REGEXP
BINARY 'JetPack .000'。
9.2.2 进行OR匹配
为搜索两个串之一(或者为这个串,或者为另一个串),使用|,如
下所示:
语句中使用了正则表达式1000|2000。|为正则表达式的OR操作
符。它表示匹配其中之一,因此1000和2000都匹配并返回。
使用|从功能上类似于在SELECT语句中使用OR语句, 多个OR条件可并
入单个正则表达式。
两个以上的OR条件 可以给出两个以上的OR条件。例如,'1000 | 2000 | 3000'将匹配1000或2000或3000。
9.2.3 匹配几个字符之一
匹配任何单一字符。但是,如果你只想匹配特定的字符,怎么办?
可通过指定一组用[和]括起来的字符来完成,如下所示:
输入
输出
分析
70
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com9.2 使用 MySQL 正则表达式 55
这里,使用了正则表达式[123] Ton。[123]定义一组字符,它
的意思是匹配1或2或3,因此,1 ton和2 ton都匹配且返回(没
有3 ton)。
正如所见, []是另一种形式的OR语句。 事实上,正则表达式[123]Ton
为[1|2|3]Ton的缩写,也可以使用后者。但是,需要用[]来定义OR语句
查找什么。为更好地理解这一点,请看下面的例子:
这并不是期望的输出。两个要求的行被检索出来,但还检索出
了另外3行。之所以这样是由于MySQL假定你的意思是'1'或
'2'或'3 ton'。除非把字符|括在一个集合中,否则它将应用于整个串。
字符集合也可以被否定,即,它们将匹配除指定字符外的任何东西。
为否定一个字符集,在集合的开始处放置一个^即可。因此,尽管[123]
匹配字符1、2或3,但[^123]却匹配除这些字符外的任何东西。
9.2.4 匹配范围
集合可用来定义要匹配的一个或多个字符。例如,下面的集合将匹
配数字0到9:
输入
输入
输出
输出
分析
分析
72
71
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com56 第 9章 用正则表达式进行搜索
为简化这种类型的集合,可使用-来定义一个范围。下面的式子功能
上等同于上述数字列表:
范围不限于完整的集合,[1-3]和[6-9]也是合法的范围。此外,范
围不一定只是数值的,[a-z]匹配任意字母字符。
举一个例子:
这里使用正则表达式[1-5] Ton。[1-5]定义了一个范围,这个
表达式意思是匹配1到5,因此返回3个匹配行。由于5 ton匹配,所以返回.5 ton。
9.2.5 匹配特殊字符
正则表达式语言由具有特定含义的特殊字符构成。我们已经看到.、 []、|和-等,还有其他一些字符。请问,如果你需要匹配这些字符,应该怎么
办呢?例如,如果要找出包含.字符的值,怎样搜索?请看下面的例子:
输入
输入
输出
输出
分析
73
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com9.2 使用 MySQL 正则表达式 57
这并不是期望的输出,.匹配任意字符,因此每个行都被检索出
来。
为了匹配特殊字符,必须用\\为前导。 \\-表示查找-, \\.表示查找.。
这才是期望的输出。\\.匹配.,所以只检索出一行。这种处理
就是所谓的转义(escaping) ,正则表达式内具有特殊意义的所
有字符都必须以这种方式转义。这包括.、|、[]以及迄今为止使用过的
其他特殊字符。
\\也用来引用元字符(具有特殊含义的字符) ,如表9-1所列。
表9-1 空白元字符
元 字 符 说 明
\\f 换页
\\n 换行
\\r 回车
\\t 制表
\\v 纵向制表
匹配\ 为了匹配反斜杠(\)字符本身,需要使用\\\。
\或\\? 多数正则表达式实现使用单个反斜杠转义特殊字符,以便能使用这些字符本身。 但MySQL要求两个反斜杠 (MySQL
自己解释一个,正则表达式库解释另一个) 。
输入
输出
分析
分析
74
75
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com58 第 9章 用正则表达式进行搜索
9.2.6 匹配字符类
存在找出你自己经常使用的数字、所有字母字符或所有数字字母字
符等的匹配。为更方便工作,可以使用预定义的字符集,称为字符类
(character class) 。表9-2列出字符类以及它们的含义。
表9-2 字符类
类 说 明
[:alnum:] 任意字母和数字(同[a-zA-Z0-9])
[:alpha:] 任意字符(同[a-zA-Z])
[:blank:] 空格和制表(同[\\t])
[:cntrl:] ASCII控制字符(ASCII 0到31和127)
[:digit:] 任意数字(同[0-9])
[:graph:] 与[:print:]相同,但不包括空格
[:lower:] 任意小写字母(同[a-z])
[:print:] 任意可打印字符
[:punct:] 既不在[:alnum:]又不在[:cntrl:]中的任意字符
[:space:] 包括空格在内的任意空白字符(同[\\f\\n\\r\\t\\v])
[:upper:] 任意大写字母(同[A-Z])
[:xdigit:] 任意十六进制数字(同[a-fA-F0-9])
9.2.7 匹配多个实例
目前为止使用的所有正则表达式都试图匹配单次出现。如果存在一
个匹配,该行被检索出来,如果不存在,检索不出任何行。但有时需要
对匹配的数目进行更强的控制。例如,你可能需要寻找所有的数,不管
数中包含多少数字,或者你可能想寻找一个单词并且还能够适应一个尾
随的s(如果存在),等等。
这可以用表9-3列出的正则表达式重复元字符来完成。
表9-3 重复元字符
元 字 符 说 明
0个或多个匹配
+ 1个或多个匹配(等于{1,})
· 0个或1个匹配(等于{0,1})
{n} 指定数目的匹配
{n,} 不少于指定数目的匹配
{n,m} 匹配数目的范围(m不超过255)
76
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com9.2 使用 MySQL 正则表达式 59
下面举几个例子。
正则表达式\\([0-9] sticks?\\)需要解说一下。\\(匹配),[0-9]匹配任意数字(这个例子中为1和5),sticks?匹配stick
和sticks(s后的?使s可选,因为?匹配它前面的任何字符的0次或1次出
现) ,\\)匹配)。没有?,匹配stick和sticks会非常困难。
以下是另一个例子。这次我们打算匹配连在一起的4位数字:
如前所述,[:digit:]匹配任意数字,因而它为数字的一个集
合。{4}确切地要求它前面的字符(任意数字)出现4次,所以
[[:digit:]]{4}匹配连在一起的任意4位数字。
需要注意的是,在使用正则表达式时,编写某个特殊的表达式几乎
总是有不止一种方法。上面的例子也可以如下编写:
9.2.8 定位符
目前为止的所有例子都是匹配一个串中任意位置的文本。为了匹配
输入
输入
输入
输出
输出
分析
分析
77
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com60 第 9章 用正则表达式进行搜索
特定位置的文本,需要使用表9-4列出的定位符。
表9-4 定位元字符
元 字 符 说 明
^ 文本的开始
文本的结尾
[[:<:]] 词的开始
[[:>:]] 词的结尾
例如,如果你想找出以一个数(包括以小数点开始的数)开始的所
有产品,怎么办?简单搜索[0-9\\.](或[[:digit:]\\.])不行,因为
它将在文本内任意位置查找匹配。解决办法是使用^定位符,如下所示:
^匹配串的开始。因此,^[0-9\\.]只在.或任意数字为串中第
一个字符时才匹配它们。没有^, 则还要多检索出4个别的行 (那
些中间有数字的行) 。
^的双重用途 ^有两种用法。在集合中(用[和]定义),用它
来否定该集合,否则,用来指串的开始处。
使REGEXP起类似LIKE的作用 本章前面说过,LIKE和REGEXP
的不同在于,LIKE匹配整个串而REGEXP匹配子串。利用定位
符,通过用^开始每个表达式,用结束每个表达式,可以使
REGEXP的作用与LIKE一样。
输入
输出
分析
78
79
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com9.3 小结 61
简单的正则表达式测试 可以在不使用数据库表的情况下用
SELECT来测试正则表达式。 REGEXP检查总是返回0 (没有匹配)
或1(匹配)。可以用带文字串的REGEXP来测试表达式,并试
验它们。相应的语法如下:
这个例子显然将返回0(因为文本hello中没有数字) 。
9.3 小结
本章介绍了正则表达式的基础知识,学习了如何在MySQL的SELECT
语句中通过REGEXP关键字使用它们。
80
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
创建计算字段
本章介绍什么是计算字段,如何创建计算字段以及怎样从应用程序
中使用别名引用它们。
10.1 计算字段
存储在数据库表中的数据一般不是应用程序所需要的格式。下面举
几个例子。
· 如果想在一个字段中既显示公司名,又显示公司的地址,但这两
个信息一般包含在不同的表列中。
· 城市、州和邮政编码存储在不同的列中(应该这样),但邮件标签
打印程序却需要把它们作为一个恰当格式的字段检索出来。
· 列数据是大小写混合的,但报表程序需要把所有数据按大写表示
出来。
· 物品订单表存储物品的价格和数量,但不需要存储每个物品的总
价格(用价格乘以数量即可)。为打印发票,需要物品的总价格。
· 需要根据表数据进行总数、平均数计算或其他计算。
在上述每个例子中,存储在表中的数据都不是应用程序所需要的。
我们需要直接从数据库中检索出转换、计算或格式化过的数据;而不是
检索出数据,然后再在客户机应用程序或报告程序中重新格式化。
这就是计算字段发挥作用的所在了。与前面各章介绍过的列不同,计算字段并不实际存在于数据库表中。计算字段是运行时在SELECT语句
内创建的。
第10章
81
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com欢迎点击这里的链接进入精彩的Linux公社 网
站
Linux公社(www.Linuxidc.com)于2006年9月25日注
册并开通网站,Linux现在已经成为一种广受关注和
支持的一种操作系统,IDC是互联网数据中心,LinuxIDC就是关于Linux的数据中心。
Linux公社是专业的Linux系统门户网站,实时发布最
新Linux资讯,包括Linux、Ubuntu、Fedora、RedHat、红旗Linux、Linux教程、Linux认证、SUSE
Linux、Android、Oracle、Hadoop、CentOS、MySQL、Apache、Nginx、Tomcat、Python、Java、C语言、OpenStack、集群等技术。
Linux公社(LinuxIDC.com)设置了有一定影响力的
Linux专题栏目。
Linux公社 主站网址:www.linuxidc.com 旗下
网站:www.linuxidc.net
包括:Ubuntu 专题 Fedora专题 Android 专题
Oracle专题 Hadoop 专题 RedHat 专题 SUSE
专题 红旗 Linux 专题 CentOS专题
Linux 公社微信公众号:linuxidc_com
10.2 拼接字段 63
字段(field) 基本上与列(column)的意思相同,经常互换使
用,不过数据库列一般称为列,而术语字段通常用在计算字段的
连接上。
重要的是要注意到,只有数据库知道SELECT语句中哪些列是实际的
表列,哪些列是计算字段。从客户机(如应用程序)的角度来看,计算
字段的数据是以与其他列的数据相同的方式返回的。
客户机与服务器的格式 可在SQL语句内完成的许多转换
和格式化工作都可以直接在客户机应用程序内完成。但一
般来说,在数据库服务器上完成这些操作比在客户机中完
成要快得多,因为DBMS是设计来快速有效地完成这种处
理的。
10.2 拼接字段
为了说明如何使用计算字段,举一个创建由两列组成的标题的简单
例子。
vendors表包含供应商名和位置信息。假如要生成一个供应商报表,需要在供应商的名字中按照name(location)这样的格式列出供应商的位
置。
此报表需要单个值,而表中数据存储在两个列vend_name和vend_
country中。此外,需要用括号将vend_country括起来,这些东西都没有
明确存储在数据库表中。我们来看看怎样编写返回供应商名和位置的
SELECT语句。
拼接(concatenate) 将值联结到一起构成单个值。
解决办法是把两个列拼接起来。在MySQL的SELECT语句中,可使用
Concat函数来拼接两个列。
82
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com64 第 10章 创建计算字段
MySQL的不同之处 多数DBMS使用+或||来实现拼接,MySQL则使用Concat函数来实现。当把SQL语句转换成
MySQL语句时一定要把这个区别铭记在心。
Concat拼接串,即把多个串连接起来形成一个较长的串。
Concat需要一个或多个指定的串,各个串之间用逗号分隔。
上面的SELECT语句连接以下4个元素:
· 存储在vend_name列中的名字;
· 包含一个空格和一个左圆括号的串;
· 存储在vend_country列中的国家;
· 包含一个右圆括号的串。
从上述输出中可以看到,SELECT语句返回包含上述4个元素的单个列
(计算字段) 。
在第8章中曾提到通过删除数据右侧多余的空格来整理数据,这可以
使用MySQL的RTrim函数来完成,如下所示:
RTrim函数去掉值右边的所有空格。通过使用RTrim,各个
列都进行了整理。
输入
分析
输入
输出
分析
83
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com10.2 拼接字段 65
Trim函数 MySQL除了支持RTrim(正如刚才所见,它去掉
串右边的空格),还支持LTrim(去掉串左边的空格)以及
Trim(去掉串左右两边的空格) 。
使用别名
从前面的输出中可以看到,SELECT语句拼接地址字段工作得很好。
但此新计算列的名字是什么呢?实际上它没有名字,它只是一个值。如
果仅在SQL查询工具中查看一下结果,这样没有什么不好。但是,一个未
命名的列不能用于客户机应用中,因为客户机没有办法引用它。
为了解决这个问题,SQL支持列别名。别名(alias)是一个字段或值
的替换名。别名用AS关键字赋予。请看下面的SELECT语句:
SELECT语句本身与以前使用的相同,只不过这里的语句中计算
字段之后跟了文本AS vend_title。它指示SQL创建一个包含
指定计算的名为vend_title的计算字段。从输出中可以看到,结果与以
前的相同,但现在列名为vend_title,任何客户机应用都可以按名引用
这个列,就像它是一个实际的表列一样。
别名的其他用途 别名还有其他用途。常见的用途包括在实际
的表列名包含不符合规定的字符(如空格)时重新命名它,在
原来的名字含混或容易误解时扩充它,等等。
输入
输出
分析
84
85
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com66 第 10章 创建计算字段
导出列 别名有时也称为导出列(derived column) ,不管称为
什么,它们所代表的都是相同的东西。
10.3 执行算术计算
计算字段的另一常见用途是对检索出的数据进行算术计算。举一个
例子,orders表包含收到的所有订单,orderitems表包含每个订单中的
各项物品。下面的SQL语句检索订单号20005中的所有物品:
item_price列包含订单中每项物品的单价。如下汇总物品的价格(单
价乘以订购数量) :
输出中显示的expanded_price列为一个计算字段,此计算为
quantityitem_price。客户机应用现在可以使用这个新计算
列,就像使用其他列一样。
输入
输出
输入
输出
分析
86
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com10.4 小结 67
MySQL支持表10-1中列出的基本算术操作符。此外,圆括号可用来
区分优先顺序。关于优先顺序的介绍,请参阅第7章。
表10-1 MySQL算术操作符
操 作 符 说 明
+ 加
- 减
乘
除
如何测试计算 SELECT提供了测试和试验函数与计算的一个
很好的办法。虽然SELECT通常用来从表中检索数据,但可以
省略FROM子句以便简单地访问和处理表达式。例如,SELECT
32;将返回6,SELECT Trim('abc');将返回abc,而SELECT
Now利用Now函数返回当前日期和时间。通过这些例子,可以明白如何根据需要使用SELECT进行试验。
10.4 小结
本章介绍了计算字段以及如何创建计算字段。我们用例子说明了计
算字段在串拼接和算术计算的用途。此外,还学习了如何创建和使用别
名,以便应用程序能引用计算字段。
87
88
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com
使用数据处理函数
本章介绍什么是函数, MySQL支持何种函数,以及如何使用这些函数。
11.1 函数
与其他大多数计算机语言一样,SQL支持利用函数来处理数据。函数
一般是在数据上执行的,它给数据的转换和处理提供了方便。
在前一章中用来去掉串尾空格的RTrim就是一个函数的例子。
函数没有SQL的可移植性强 能运行在多个系统上的代码称
为可移植的(portable) 。相对来说,多数SQL语句是可移植的,在SQL实现之间有差异时,这些差异通常不那么难处理。而函
数的可移植性却不强。几乎每种主要的DBMS的实现都支持其
他实现不支持的函数,而且有时差异还很大。
为了代码的可移植,许多SQL程序员不赞成使用特殊实现的功
能。虽然这样做很有好处,但不总是利于应用程序的性能。如
果不使用这些函数,编写某些应用程序代码会很艰难。必须利
用其他方法来实现DBMS非常有效地完成的工作。
如果你决定使用函数,应该保证做好代码注释,以便以后你(或
其他人)能确切地知道所编写SQL代码的含义。
11.2 使用函数
大多数SQL实现支持以下类型的函数。
· 用于处理文本串(如删除或填充值,转换值为大写或小写)的文
第11章
89
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com11.2 使用函数 69
本函数。
· 用于在数值数据上进行算术操作(如返回绝对值,进行代数运算)
的数值函数。
· 用于处理日期和时间值并从这些值中提取特定成分(例如,返回
两个日期之差,检查日期有效性等)的日期和时间函数。
· 返回DBMS正使用的特殊信息(如返回用户登录信息,检查版本
细节)的系统函数。
11.2.1 文本处理函数
上一章中我们已经看过一个文本处理函数的例子,其中使用RTrim
函数来去除列值右边的空格。下面是另一个例子,这次使用Upper函数:
正如所见,Upper将文本转换为大写,因此本例子中每个供
应商都列出两次,第一次为vendors表中存储的值,第二次作
为列vend_name_upcase转换为大写。
表11-1列出了某些常用的文本处理函数。
表11-1 常用的文本处理函数
函 数 说 明
Left 返回串左边的字符
Length 返回串的长度
Locate 找出串的一个子串
Lower 将串转换为小写
LTrim 去掉串左边的空格
Right 返回串右边的字符
输入
输出
分析
90
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com70 第 11章 使用数据处理函数
(续)
函 数 说 明
RTrim 去掉串右边的空格
Soundex 返回串的SOUNDEX值
SubString 返回子串的字符
Upper 将串转换为大写
表11-1中的SOUNDEX需要做进一步的解释。SOUNDEX是一个将任何文
本串转换为描述其语音表示的字母数字模式的算法。SOUNDEX考虑了类似
的发音字符和音节,使得能对串进行发音比较而不是字母比较。虽然
SOUNDEX不是SQL概念,但MySQL(就像多数DBMS一样)都提供对
SOUNDEX的支持。
下面给出一个使用Soundex函数的例子。customers表中有一个顾
客Coyote Inc.,其联系名为Y.Lee。但如果这是输入错误,此联系名实
际应该是Y.Lie,怎么办?显然,按正确的联系名搜索不会返回数据,如
下所示:
现在试一下使用Soundex函数进行搜索,它匹配所有发音类似于
Y.Lie的联系名:
在这个例子中,WHERE子句使用Soundex函数来转换cust_
contact列值和搜索串为它们的SOUNDEX值。因为Y.Lee和
Y.Lie发音相似,所以它们的SOUNDEX值匹配,因此WHERE子句正确地过滤
出了所需的数据。
输入
输出
输入
分析
输出
91
92
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com11.2 使用函数 71
11.2.2 日期和时间处理函数
日期和时间采用相应的数据类型和特殊的格式存储,以便能快速和
有效地排序或过滤,并且节省物理存储空间。
一般,应用程序不使用用来存储日期和时间的格式,因此日期和时
间函数总是被用来读取、统计和处理这些值。由于这个原因,日期和时
间函数在MySQL语言中具有重要的作用。
表11-2列出了某些常用的日期和时间处理函数。
表11-2 常用日期和时间处理函数
函 数 说 明
AddDate 增加一个日期(天、周等)
AddTime 增加一个时间(时、分等)
CurDate 返回当前日期
CurTime 返回当前时间
Date 返回日期时间的日期部分
DateDiff 计算两个日期之差
Date_Add 高度灵活的日期运算函数
Date_Format 返回一个格式化的日期或时间串
Day 返回一个日期的天数部分
DayOfWeek 对于一个日期,返回对应的星期几
Hour 返回一个时间的小时部分
Minute 返回一个时间的分钟部分
Month 返回一个日期的月份部分
Now 返回当前日期和时间
Second 返回一个时间的秒部分
Time 返回一个日期时间的时间部分
Year 返回一个日期的年份部分
这是重新复习用WHERE进行数据过滤的一个好时机。迄今为止,我
们都是用比较数值和文本的WHERE子句过滤数据,但数据经常需要用日
期进行过滤。用日期进行过滤需要注意一些别的问题和使用特殊的
MySQL函数。
首先需要注意的是MySQL使用的日期格式。无论你什么时候指定一
93
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com72 第 11章 使用数据处理函数
个日期,不管是插入或更新表值还是用WHERE子句进行过滤,日期必须为
格式yyyy-mm-dd。因此,2005年9月1日,给出为2005-09-01。虽然其他的
日期格式可能也行,但这是首选的日期格式,因为它排除了多义性(如,040506是2006年5月4日或2006年4月5日或2004年5月6日或……) 。
应该总是使用4位数字的年份 支持2位数字的年份,MySQL
处理00-69为2000-2069,处理70-99为1970-1999。虽然它们可
能是打算要的年份,但使用完整的4位数字年份更可靠,因为
MySQL不必做出任何假定。
因此,基本的日期比较应该很简单:
此SELECT语句正常运行。它检索出一个订单记录,该订单记录
的order_date为2005-09-01。
但是,使用WHERE order_date = '2005-09-01'可靠吗?order_
date的数据类型为datetime。这种类型存储日期及时间值。样例表中
的值全都具有时间值00:00:00,但实际中很可能并不总是这样。如果
用当前日期和时间存储订单日期(因此你不仅知道订单日期,还知道
下订单当天的时间),怎么办?比如,存储的order_date值为
2005-09-01 11:30:05,则WHERE order_date = '2005-09-01'失败。
即使给出具有该日期的一行,也不会把它检索出来,因为WHERE匹配失
败。
解决办法是指示MySQL仅将给出的日期与列中的日期部分进行比
较,而不是将给出的日期与整个列值进行比较。为此,必须使用Date
函数。Date(order_date)指示MySQL仅提取列的日期部分,更可靠的
SELECT语句为:
输入
输出
分析
94
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 www.linuxidc.com11.2 使用函数 73
如果要的是日期,请使用Date 如果你想要的仅是日期,则使用Date是一个良好的习惯,即使你知道相应的列只包
含日期也是如此。这样,如果由于某种原因表中以后有日期和
时间值,你的SQL代码也不用改变。当然,也存在一个Time
函数,在你只想要时间时应该使用它。
Date和Time都是在MySQL 4.1.1中第一次引入的。
在你知道了如何用日期进行相等测试后,其他操作符(在第6章中介
绍)的使用也就很清楚了。
不过,还有一种日期比较需要说明。如果你想检索出2005年9月下的
所有订单,怎么办?简单的相等测试不行,因为它也要匹配月份中的天
数。有几种解决办法,其中之一如下所示:
其中,BETWEEN操作符用来把2005-09-01和2005-09-30定义为
一个要匹配的日期范围。
还有另外一种办法(一种不需要记住每个月中有多少天或不需要操
心闰年2月的办法) :
Year是一个从日期(或日期时间)中返回年份的函数。类似,Month从日期中返回月份。因此,WHERE Year(order_date)
输入
输入
输出
分析
输入
分析
95
图灵社区会员 臭豆腐(StinkBC@gmail.com) 专享 尊重版权
Linux公社 ww ......
您现在查看是摘要介绍页, 详见PDF附件(7014KB,258页)。





