1、数据库(database)
保存有组织的数据的容器
人们通常用户数据库这个术语来代表他们所使用的数据库软件,这是不正确的。确切来说,数据库软件应该称为DBMS(数据库管理系统)。数据库是通过DBMS创建和操纵的容器。你并不是直接访问数据库,你使用的是DBMS,它替你访问数据库。
2、表(table)
某种特定类型数据的结构化清单
不应该将顾客的清单和订单的清单存储在同一个数据表当中。这样做会使以后的检索和访问很困难。应该创建两个表,每个清单一个表。数据库中的每个表都有一个名字,用来标识自己。表名字是唯一的。
表具有一些特性,这些特性定义了数据在数据表中如何存储,比如说可以存储什么样的数据。
3、模式(schema)
关于数据库和表的布局及特性的信息
数据如何分解,各部分信息如何命名等等。描述表的这组信息就是模式。
4、列(column)
表中的一个字段
所有表都是由一个或者多个列组成。每个列有相应的数据类型。
5、行(row)
表中的一个记录
行有时也称为记录。
6、主键(primary key)
列或一组列,其值能够唯一区分表中的每个行。也可以一起使用多个列作为主键
应该总是定义主键:
1)任意两行都不具有相同的主键值
2)每个行都应该具备一个主键值(主键值不允许null值)
7、sql
sql是结构化查询语言的缩写,是专门用来与数据库通信的语言
sql优点:
1)sql不是某个特定数据库供应商专用的语言。几乎所有重要的DBMS都支持sql,但事实上任意两个DBMS实现的sql都不完全相同
2)sql简单易学。它的语句全都是由描述性很强的英语单词组成
3)sql是一种强有力的语言,可以进行非常复杂和高级的数据库操作
8、mysql
mysql、oracle和Microsoft sql server等数据库是基于客户机-服务器的数据库。
服务器部分是负责所有数据访问和处理的一个软件。关于数据添加、删除和更新的所有请求都是由服务器软件完成。客户机是与用户打交道的软件。这些请求或更改来自运行客户机软件的计算机。例如,客户机软件通过网络提交请求给服务器软件,服务器软件处理这个请求,根据需要过滤、丢弃和排序数据;然后把结果送回到你的客户机软件。
mysql优点:
1)成本 – mysql是开放源代码的,一般可以免费使用(甚至可以免费修改)
2)性能 – mysql执行很快
3)可信赖 – 某些非常重要和声望很高的公司、站点使用mysql,这些公司和站点都用mysql来处理自己的重要数据
4)简单 – mysql很容易安装和使用
9、mysql工具
mysql客户机
1)mysql命令行实用程序
应该使用mysql -u ben -p -h myserver -P 9999(指定用户名、主机、端口号),完整的命令行选项和参数列表可以用mysql –help获得
也可以通过help获得特定命令的帮助,比如help select可以查看使用select语句的帮助
2)mysql administrator
mysql administrator(mysql管理器)是一个图形交互客户机,用来简化mysql服务器的管理
10、show命令
mysql>show databases; 显示可用的数据库列表
use zabbix; 使用zabbix数据库
show tables; 返回当前数据库内可用表的列表
show columns from zabbix; 等价于describe zabbix,显示列
show status; 显示服务器状态信息
show create database; 查看创建特定数据库的mysql语句
show create table; 查看创建特定表的mysql语句
show grants; 显示用户(所有用户或特定用户)的安全权限
show errors; 显示服务器错误信息
show warnings; 显示服务器警告信息
help show; 显示允许的show语句
11、查询数据
1)查询特定列
2)查询所有列(select *)
3)去重(select distinct)
4)限制结果跳数
limit 5 指示mysql返回结果为5行数据
limit 5,5 指示mysql返回从行5开始的5行。第一个5是开始位置(从0开始计数),第二个5是要检索的行数
12、排列数据
order by
1)order by子句可以是所检索的列,也可以是非检索的列
2)可以是按照单个列排序,也可以是按照多个列排序
3)默认是升序排列(或者显式指定asc),也可以通过desc指定降序排序
13、子句顺序
1)select
2)from
3)where
4)group by
5)having
6)order by
7)limit
14、过滤数据
where
操作符:
15、组合where
and:where子句中使用的关键字,用来指示检索满足所有给定条件的行
or:where子句中使用的关键字,用来检索匹配任一给定条件的行
in:where子句中用来指定要匹配值的清单的关键字,功能与or相当
not:where子句中用来否定后跟条件的关键字
备注:
sql(像大多数sql语言一样)在处理or操作符之前,优先处理and操作符。可以使用圆括号改变默认操作顺序。
16、通配过滤
like操作符:为在搜索子句中使用通配符,必须使用like操作符
like指示mysql,后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较
搜索模式:由字面值、通配符或者两者组合构成的搜索条件
通配符:用来匹配值的一部分的特殊字符
1)百分号(%)通配符
表示任意字符出现任意次数
备注:
虽然似乎%可以匹配任何东西,但是有一个例外,就是null。
例如where prod_name like ‘%’不能匹配用值null作为产品名的行
2)下划线(_)通配符
下划线只匹配单个字符而不是多个字符
17、正则过滤
关键字like被regexp替代,其他跟使用like很像
like与regexp的区别:
1)like匹配整个列,如果被匹配的文本在列值中出现,like将不会找到它,相应的行也不会返回(除非使用通配符)
2)regexp在列值内匹配,如果被匹配的文本在列值中出现,regexp将会找到它,相应的行将被返回
例如,
3)select prod_name from products where prod_name regexp ‘1000’ order by prod_name; 返回数据’jetpack 1000’,列值内匹配
4)select prod_name from products where prod_name like ‘1000’
order by prod_name; 不返回数据,要整个匹配才会返回数据
18、regexp用法
1)匹配整个列值(使用^与$定位符,从而功能与like相同)
2)默认不区分大小写(使用binary关键字可以区分大小写,例如select prod_name regexp binary ‘JetPack .000’)
3)or匹配(使用符号’|’,表示匹配符号’|’左边或者右边的其中一个)
4)匹配几个字符之一(使用中括号’[]’,比如[123]ab可以匹配1ab或2ab或3ab)
5)匹配几个字符之一的否定写法(使用中括号,并在中括号里面的集合的开始处放置一个^,比如[^123]就是匹配除1、2、3之外的任何字符)
6)匹配范围
[1-9] 匹配1到9
[a-d] 匹配a到d
7)匹配特殊字符
必须以\为前导。比如\-表示查找-,\.表示查找.,\\表示查找\
备注:
多数正则表达式实现使用单个反斜杠转义特殊字符,以便能使用这些字符本身。但mysql要求使用两个反斜杠(mysql自己解释一个,正则表达式库解释另一个)
8)匹配字符类
[:alnum:] 匹配任意数字和字母
[:alpha:] 匹配任意字符
[:digit:] 匹配任意数字
[:lower:] 匹配小写字母
[:upper:] 匹配大写字母
[:punct:] 匹配标点符号
[:space:] 匹配空白字符
[::xdigit] 匹配十六进制数
9)重复元字符(匹配其前面的字符多少次)
* 匹配其前面的字符任意次
+ 匹配其前面的字符至少1次
? 匹配其前面的字符0次或1次
{n} 匹配其前面的字符n次
{n,} 匹配其前面的字符至少n次
{n,m} 匹配其前面的字符至少n次,至多m次
10)定位符
^ 匹配文本的开始位置
$ 匹配文本的结束位置
[[:<:]] 匹配词的开始位置
[[:>:]] 匹配词的结束位置
备注:
^有3种用法:
a、用在集合[]中表示否定该集合
b、用在字符串’’中指定串的开始位置
c、如之前所知,like匹配整个串而regexp匹配子串。利用^的定位符功能,通过用^开始每个表达式,用$结束每个表达式,可以使regexp的作用与like一样
11)可以在不使用数据库的情况下使用select来测试正则表达式。例如使用带文字字符串的regexp来测试正则表达式
select ‘hello’ regexp ‘[0-9]’ 返回0,表示不匹配
备注:
返回0表示不匹配,返回1表示匹配
19、拼接字段
concat()函数
多数的DBMS使用+或者||来实现拼接,mysql则使用concat()函数来实现。括号里面是要拼接的字符串,用逗号隔开
20、删除空格
trim()函数,支持rtrim()和ltrim()
trim() 删除左右两边的空格
rtrim() 删除右侧多余空格
ltrim() 删除左侧多余空格
21、使用别名
使用关键字as
22、使用select计算(省略from语句)
select 3*2 返回6
select trim(‘ abc ‘) 返回abc,去掉空格
select NOW() 返回当前日期和时间
23、sql函数
分文本处理函数、日期和时间处理函数、数值处理函数、聚集函数、分组函数等
24、文本处理函数
1)left() 从左边返回
left(str,length) left()函数接受两个参数,str是要提取子字符串的字符串,length是一个正整数,指定将从左边返回的字符数
例如,
select left(‘example.com’,3); 返回exa
2)right() 跟left相反,从右边返回
3)length() 返回字符串长度
4)locate()
locate(substr,str) 返回子串substr在字串str中第一次出现的位置。如果子串substr在str中不存在,将返回0
5)lower() 转换为小写
6)upper() 转换为大写
7)ltrim() 删除左侧多余的空格
8)rtrim() 删除右侧多余的空格
9)substring()
select substring(‘example.com’,4,2); 从字符串的第4个字符位置开始取,只取2个字符
10)soundex() 返回类似发音的值
where soundex(cust_contact) = soundex(‘Y Lie’) ‘cust_contact’的值中有’Y Lee’。因为’Y Lee’和’Y Lie’发音类似,所以它们的soundex值匹配,会返回’Y Lee’
25、日期和时间函数
1)curdate() 返回当前日期
2)curtime() 返回当前时间
3)date() 返回日期时间的日期部分
4)datediff 计算两个日期之差
5)date_format() 返回一个格式化的日期时间
备注:
可以使用的格式有,
a、年
%Y 年,4位
%y 年,2位
b、月
%b 缩写月名
%M 月名
%m 月,数值(00-12)
c、日
%D 带有英文前缀的月中的天
%d 月的天,数值(00-31)
d、时
%H 小时(00-23)
%h 小时(01-12)
e、分
%i 分钟(数值00-59)
f、秒
%S 秒(00-59)
%s 秒(00-59)
year() 返回一个日期的年部分
month() 返回一个日期的月部分
day() 返回一个日期的天数
dayofweek() 返回一个日期对应的星期几
time() 返回一个日期的时间部分
hour() 返回一个日期的小时部分
minute() 返回一个日期的分钟部分
second() 返回一个日期的秒部分
26、数值处理函数
1)abs() 返回一个数的绝对值
2)exp() 返回一个数的指数值
3)mod() 返回除操作的余数
4)pi() 返回圆周率
5)rand() 返回一个随机数
6)sqrt() 返回一个数的平方根
27、聚集函数
定义:运行在行组中,计算和返回单个值的函数
1)avg() 返回某列的平均值
avg()只能用于单列,要获得多列的平均值必须使用多个avg()函数
2)count() 返回某列的行数
count()函数有两种使用方式:
count(*) 对表中的数目进行计数,不管包含的是空值还是非空值
count(column) 对特定列中具有值的行进行计数,忽略空值
3)max() 返回某列中的最大值
在用于文本数据时,如果数据按照相应的列排序,则max()返回最后一行
4)min() 返回某列的最小值
在用于文本数据时,如果数据按照相应的列排序,则min()返回最前面的一行
5)sum() 返回某某列值之和
28、分组函数
group by
1)group by子句中列出的每个列必须是检索列或有效的表达式(但不能是聚集函数)
2)如果在select中使用表达式,则必须在group by子句中指定相同的表达式
3)不能使用别名
4)group by子句必须出现在order by子句之前
5)在分组函数中,不能使用where来过滤,而是用having来过滤。因为where过滤的是行而不是分组。having用在group by之后
29、with rollup
可以实现在分组统计数据的基础上再做统计(sum,avg,count…)
用法示例:
例如我们将数据表按照名字进行分组,再统计每个人登录的次数
30、子查询和相关子查询
子查询:嵌套在其他查询中的查询
相关子查询:涉及外部查询的子查询。可能会涉及到列名有多义性,这时候必须使用完全限定列名(表名和列名由一个句点分割)
备注:
子查询最常见的使用是在where子句的in操作符中
31、外键
外键是某个表中的一列,它包含另一个表的主键值,定义了两个表之间的关系。可以用来连接两个表
32、连接关系
1)内连接(等值连接):inner join
select vend_name,prod_name,prod_price from vendors,products
where vendors.vend_id = products.vend_id order by vend_name,prod_name
也可以用规范的语法:
select vend_name,prod_name,prod_price from vendors inner join products on vendors.vend_id = products.vend_id
备注:
至于使用哪种语法,sql规范首选inner join语法
2)自连接
select p1.prod_id,p1.prod_name from products as p1,products as p2 where p1.vend_id = p2.vend_id and p2.prod_id = ‘DTNTR’
等同于子查询:
select prod_id,prod_name from produtcs where vend_id = (select vend_id from products where prod_id = ‘DTNTR’)
备注:
有时候处理连接比处理子查询要快得多
3)左外连接:left join或left outer join
包含左边表的所有行(不管右边的表中是否存在与它们匹配的行),以及右表中全部匹配的行
4)右外连接:right join或right outer join
包含右边表的所有行(不管左边的表中是否存在与它们匹配的行),以及左表中全部匹配的行
5)全外连接:full join或full outer join
包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行
6)交叉连接:没有连接关系(没有where子句)
生成笛卡尔积
备注:
笛卡尔积,是指由没有联结关系的表关系返回的结果称为笛卡尔积
33、组合查询
union关键字
union规则:
1)union必须有两条或者两条以上的select语句组成,语句之间用关键字union分隔
2)union的每个查询必须包含相同的列、表达式或聚集函数(不过各个列不需要以相同的次序列出)
3)列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含的转换的类型(例如,不同的数值类型或不同的日期类型)
备注:
1)union从查询结果集中自动的去除了重复的行;如果想返回所有行,可以使用union all而不是union
2)union几乎总是完成与多个where条件相同的工作。union all为union的一种形式,它完成where子句完成不了的工作。如果确实需要每个条件的匹配行全部出现(包括重复行),则必须使用union all而不是where
34、全文本搜索功能
mysql最常用的搜索引擎是myisam和innodeDB,但是只有myisam支持全文本搜索,innodeDB不支持
为什么需要全文本搜索功能:
mysql支持使用like运算符和正则表达式进行文本搜索。但是,当文本列较大并且表中的行数增加时,使用这些方法有一些限制:
1)性能问题:mysql必须扫描整个表以根据like或正则表达式的模式查找文本
2)灵活搜索:使用like或者正则表达式搜索,很难进行灵活的搜索查询。例如,查找描述包含car但不是classic的产品
3)没有办法指定结果集中的哪一行与搜索字词更相关
由于这些限制,mysql扩展了一个非常好的功能,叫做全文搜索。从技术上讲,mysql从启用的全文搜索列的单词中创建一个索引,并对该索引进行搜索。mysql使用复杂的算法来确定与搜索查询匹配的行。
35、全文本搜索示例
1)启用全文本搜索支持:在创建表的时候通过fulltext子句启用
create table productnotes(
note_id int not null auto_increment,
prod_id char(10) not null,
note_date datetime not null,
note_text text,
primary_key(note_id),
fulltext(note_text),
)engine=myisam;
以上例子中,mysql根据子句fulltext(note_text)对它进行索引。在定义之后,mysql自动维护该索引。在增加、更新、删除行时,索引随之更新。可以在创建的时候指定fulltext,也可以在稍后指定。
2)进行全文本搜索
在索引之后,使用两个函数match()和against()执行全文本搜索,其中match()指定被搜索的列,against指定要使用的搜索表达式
select note_text from productnotes where match(note_text) against(‘rabbit’)
以上例子中,match(note_text)指示mysql针对指定的列进行搜索,against(‘rabbit’)指定词rabbit作为搜索文本
备注:
a、传递给match()的值必须与fulltext()定义中的相同。如果指定多个列,则必须列出它们(并且次序要相同)
b、搜索不区分大小写(除非使用binary方式,否则全文本搜索不区分大小写)
c、全文本搜索提供了简单like搜索不能提供的功能。而且,数据是索引的,全文本搜索还相当快
3)查询扩展
使用全文本搜索,但是没有查询扩展:
select note_text from productnotes where match(note_text) against(‘anvils’);
使用全文本搜索,并且使用查询扩展:
select note_text from productnotes where match(note_text) against(‘anvils’ with query expansion);
这行返回的行数比较多。
第一行包含词anvils,因此等级最高;
第二行与anvils无关,但因为它包含第一行中的两个词(customer和recommend),所以也被检索出来
第三行也包含这两个相同的词,但它们在文本中的位置更靠后且分开得更远,因此也包含这一行,但等级为三。
4)布尔文本搜索
布尔文本搜索与全文本搜索不同的地方在于:
1)可以排除指定的关键字
2)即使没有定义fulltext索引,也可以使用它
select note_text from productnotes where match(note_text) against(‘heavy -rope*‘ in boolean mode);
以上例子中,表示匹配词heavy,但-rope*指示mysql排除包含rope的行
select note_text from productnotes where match(note_text) against(‘rabbit bait’ in boolean mode);
以上例子中,没有指定关键字,这个搜索匹配包含rabbit和bait中的至少一个词的行
备注:
布尔操作符: