查询、索引和完整性
MySQL
是目前最流行的关系型DBMS
,由瑞典MySQL AB
公司开发,目前属于 Oracle
旗下产品。MySQL
具有性能高、成本低、可靠性好、开放源码等特点,广泛应用于网站开发和移动应用开发,在科学研究中的应用也极其广泛。
通过实验可以家熟悉和掌握以下内容:
- 掌握
SELECT
语句的基本语法 - 掌握子查询、连接查询的表示方法
- 掌握数据汇总的方法
- 掌握
GROUP BY和ORDER BY
子句的作用和使用方法 - 掌握视图的使用方法
- 掌握索引的使用方法
- 理解数据完整性的概念及分类
- 掌握各种数据完整性的实现方法
基本查询的学习
任务描述
本关的应用场景是企业员工数据库的查询。本关你将自己动手完成对一个真实的员工数据库YGGL
的查询:
- 查找财务部年龄不低于所有研发部雇员年龄的雇员姓名、编号和性别。
- 查找财务部收入在
5200
元以上的雇员姓名及其薪水收入支出情况。 - 上述查询功能需要你掌握
SELECT
语句的基本语法、掌握子查询、连接查询的表示方法。下面就是对这些内容的详细教程,请先仔细阅读。
相关知识
查询语句SELECT
以下是MySQL
数据库中查询数据通用的SELECT
语法:SELECT column_name1,column_name2 FROM table_name [WHERE Clause] [OFFSET M ] [LIMIT N]
- 查询语句中可以指定一个或者多个表,表之间使用逗号,分割,并使用
WHERE
语句来设定查询条件 SELECT
命令可以读取一条或者多条记录- 可以使用星号*来代替字段,返回表所有字段的数据
- 可以使用
LIMIT
属性来设定返回的记录数。
命令行的操作
下面几个表来自于我们用于实验的员工管理系统的数据库YGGL
,通过命令行新建数据库数据表并插入数据吧!CREATE DATABASE YGGL;
使用数据库:use YGGL;
员工信息表emp
表结构:
列名 | 数据类型 | 长度 | 是否允许为空值 | 说明 |
---|---|---|---|---|
eid | char | 6 | 否 | 员工编号,主键 |
ename | char | 10 | 否 | 姓名 |
birth | date | 否 | 生日 | |
sex | int | 1 | 否 | 性别 |
addr | char | 20 | 是 | 地址 |
zip | char | 6 | 是 | 邮编 |
tel | char | 12 | 是 | 电话号码 |
did | char | 3 | 否 | 部门编号,外键 |
1 |
|
数据样本:
eid | ename | birth | sex | addr | zip | tel | did |
---|---|---|---|---|---|---|---|
001 | wl | 1971-01-23 | 1 | zsl | 210003 | 12345668 | 2 |
008 | wrh | 1981-03-28 | 1 | bjdl | 210001 | 12345621 | 1 |
010 | wxr | 1987-12-09 | 1 | spl | 210006 | 12345661 | 1 |
018 | ll | 1965-07-30 | 0 | zsdl | 210002 | 12345601 | 1 |
201 | lm | 1977-10-18 | 1 | hjl | 210013 | 12345608 | 5 |
208 | zj | 1970-09-28 | 1 | plx | 210004 | 12345617 | 5 |
991 | zm | 1984-08-10 | 0 | zsl | 210003 | 12345622 | 3 |
006 | zsb | 1979-10-01 | 1 | jfl | 210010 | 12345618 | 5 |
678 | lt | 1982-04-02 | 1 | zsbl | 210008 | 12345636 | 3 |
566 | lym | 1973-09-20 | 1 | rhl | 210001 | 12345691 | 4 |
759 | yf | 1983-11-18 | 1 | bjxl | 210002 | 12345601 | 4 |
209 | cll | 1974-09-03 | 0 | hzl | 210018 | 12345658 | 4 |
1 |
|
部门信息表dept
表结构:
列名 | 数据类型 | 长度 | 是否允许为空值 | 说明 |
---|---|---|---|---|
did | char | 3 | 否 | 部门编号,主键 |
dname | char | 20 | 否 | 部门名 |
note | varchar | 100 | 是 | 备注 |
1 |
|
数据样本:
did | dname | note | 说明 |
---|---|---|---|
1 | cwb | NULL | 财务部 |
2 | rlzyb | NULL | 人力资源部 |
3 | jlbgs | NULL | 经理办公室 |
4 | yfb | NULL | 研发部 |
5 | scb | NULL | 市场部 |
1 |
|
工资表sal
表结构:
列名 | 数据类型 | 长度 | 是否允许为空值 | 说明 |
---|---|---|---|---|
eid | char | 6 | 否 | 员工编号,主键 |
income | int | 8 | 否 | 收入 |
outcome | int | 8 | 否 | 支出 |
1 |
|
数据样本:
eid | income | outcome |
---|---|---|
001 | 5100 | 1123 |
008 | 4582 | 1088 |
201 | 5569 | 1185 |
006 | 4987 | 1079 |
209 | 5066 | 1108 |
566 | 5980 | 1210 |
991 | 6259 | 1281 |
010 | 5860 | 1198 |
018 | 5347 | 1180 |
759 | 5531 | 1199 |
678 | 5240 | 1121 |
208 | 4980 | 1100 |
1 |
|
查询每个雇员的所有数据:select * from emp;
查询每个雇员的地址和电话:select ename,addr,tel from emp;
查询eid
为001
的雇员地址和电话:select ename,addr,tel from emp where eid='001';
查询emp
中所有女雇员的地址和电话,使用as
子句将结果中各列的标题分别指定为地址和电话:select ename as fname,addr as faddr,tel as ftel from emp where sex=0;
计算每个雇员的实际收入:select did,income-outcome as money from sal;
找出所有姓名是w
开头的雇员的部门号:select did from emp where name like 'w%';
%
表示任意符号
找出所有收入在5000-6000
之间的雇员号码:select eid from sal where income between 5000 and 6000;
BETWEEN
运算符用于WHERE
表达式中,选取介于两个值之间的数据范围。BETWEEN
同AND
一起搭配使用。通常value1
应该小于value2
。当BETWEEN
前面加上NOT
运算符时,表示与BETWEEN
相反的意思,即选取这个范围之外的值。
子查询的使用
所谓子查询,即在查询语句中内嵌其他查询语句。下面,我们仍继续在命令行的操作中学习。
查找在cwb
工作的雇员情况:select * from emp where did=(select did from dept where dname='cwb');
连接查询的使用
比如查询每个雇员的薪水情况,但是我们要返回雇员的姓名,而在sal
表中没有雇员姓名,这个时候就需要我们通过员工编号连接emp
和sal
两张表。select emp.ename,sal.income from emp,sal where emp.eid=sal.eid;
一些关键字
any
关键字:
假设any
内部的查询语句返回的结果个数是三个,那么:select ...from ... where a > any(...)
等价于select ...from ... where a > result1 or a > result2 or a > result3
ALL
关键字与any
关键字类似,但其含义不同,相当于上面的or
改成and
。some
关键字和any
关键字是一样的功能。
IN
运算符用于WHERE表达式中,以列表项的形式支持多个选择WHERE column IN (value1,value2,...)
WHERE column NOT IN (value1,value2,...)
当IN
前面加上NOT
运算符时,表示与IN
相反的意思,即不在这些列表项内选择。
UNION
操作符用于连接两个以上的SELECT
语句的结果组合到一个结果集合中。参数1
2
3SELECT expression_1,expression_2,...,expression_n FROM tables [WHERE conditions]
UNION [ALL | DISTINCT]
SELECT expression_1,expression_2,...,expression_n FROM tables[WHERE conditions];expression_1
,expression_2
, …expression_n
是要检索的列,tables
是要检索的数据表,WHERE conditions
是检索条件,DISTINCT
是删除结果集中重复的数据。默认情况下UNION
操作符已经删除了重复数据,所以DISTINCT
修饰符对结果没啥影响。而ALL
可以返回所有结果集,包含重复数据。
编程要求
在右侧代码窗口区域的指定位置编写查询语句,实现对数据库YGGL
(包括表emp
、dept
和sal
)的相关查询:
- 查询一:使用子查询的方法,查找财务部
cwb
年龄不低于所有研发部yfb
雇员年龄的雇员姓名ename
、编号eid
和性别sex
。 - 查询二:使用连接查询的方式,查找财务部
cwb
收入income
在5200
元以上的雇员姓名ename
及其薪水收入income
支出outcome
情况。
评测说明
平台将自动编译执行你输入的MySQL
语句,并将查询结果和正确结果进行比对。
请注意语句的格式:)
特别提醒:SQL
文件的代码不能有空行,否则会报语法错误!
我的代码
1 |
|
深入学习查询语句
任务描述
本关的应用场景是企业员工数据库的查询。上一关中简单的查询满足不了需求,比如:
- 求财务部雇员的总人数;
- 求各部门的雇员数;
- 将各雇员的姓名按收入由低到高排列。
- 上述查询功能需要你掌握数据汇总、掌握
GROUP BY
和ORDER BY
子句的作用和使用方法。下面就是对这些内容的详细教程,请先仔细阅读。
相关知识
首先我们还是使用命令行操作登录数据库系统,创建数据库YGGL
、创建数据表emp
、dept
和sal
并插入数据。
MySQL聚集函数
函数 | 说明 |
---|---|
COUNT() | 返回某列的行数 |
MAX() | 返回某列最大值 |
MIN() | 返回某列最小值 |
AVG() | 返回某列平均值 |
SUM() | 返回某列值之和 |
求财务部雇员的平均收入:
1 |
|
GROUP BY 和 ORDER BY 子句的使用
GROUP BY
语句根据一个或多个列对结果集进行分组。SELECT column_name, function(column_name) FROM table_name WHERE column_name operator value GROUP BY column_name;
如果我们需要对读取的数据进行排序,我们就可以使用MySQL
的ORDER BY
子句来设定你想按哪个字段哪种方式来进行排序,再返回搜索结果。SELECT field1, field2,...,fieldN table_name1,table_name2..., ORDER BY field1,[field2...] [ASC [DESC]]
- 你可以设定多个字段来排序。
- 你可以使用
ASC
(升序)或DESC
(降序) 关键字来设置查询结果是按升序或降序排列。 默认情况下,它是按升序排列。 - 你可以添加
WHERE...LIKE
子句来设置条件。
编程要求
在右侧代码窗口区域的指定位置编写查询语句,实现对数据库YGGL
(包括表emp
、dep
t和sal
)的相关查询:
- 查询一:求财务部雇员的总人数;
- 查询二:求各部门的雇员数;
- 查询三:将各雇员的姓名按收入由低到高排列(提示:使用连接查询)。
评测说明
请在右侧代码窗口输入MySQL
语句实现以上操作,平台将自动编译你输入的MySQL
语句。
请注意语句的格式并且不要有空行哦:)
特别提醒:SQL
文件的代码不能有空行,否则会报语法错误!
我的代码
1 |
|
视图的创建和使用
任务描述
本关的应用场景是企业员工数据库的查询。视图也是为了实现多样地查看表中的数据,比如限制财务部的经理只能看到财务部的信息。本关你创建cx_sal
视图并使用该视图查看财务部雇员薪水情况。你需要掌握视图的使用方法~
相关知识
首先我们还是使用命令行操作登录数据库系统,创建数据库YGGL
、创建数据表emp
、dept
和sal
并插入数据。
现在,你输入以下代码查看数据库中表的情况:show tables;
限制查看雇员的某些情况:
1 |
|
创建该视图后,我们可以在数据库中查看所有的表,是不是变成了下面这样?
接下来我们输入下面的命令来查看该视图:select * from cx_emp;
为了了解视图的特性,我们向视图cx_emp
中插入一条记录:
eid | ename | birth | sex | did |
---|---|---|---|---|
888 | zhj | 1983-09-25 | 1 | 3 |
现在,我们查看一下emp
表,你是不是已经成功把这条记录插入到emp
表中了呢?这就是视图,原表和视图之间是同步的。
接下来请你尝试以下操作。
将zhj
从经理办公室(部门编号3)转到市场部(部门编号为5
):
1 |
|
请你再次查看emp
表核查是否修改成功。
编程要求
请你思考,我们想限制各部门的经理只能查找本部雇员的薪水情况该怎么操作呢?比如财务部,只让财务部的经理查看本部门雇员姓名和收入、支出情况。
请你创建cx_sal
视图并使用该视图查看财务部雇员薪水情况ename
、income
和outcome
。
评测说明
请在右侧代码窗口输入MySQL
语句实现以上操作,平台将自动编译你输入的MySQL
语句。
请注意语句的格式并且不要有空行哦:)
特别提醒:SQL
文件的代码不能有空行,否则会报语法错误!
我的代码
1 |
|
索引与完整性
任务描述
经理觉得查找数据的速度偏慢、精度较低,这个时候,你需要创建索引来使查询的速度更快,使用完整性来提高查询精度。
上述查询功能需要你掌握索引的使用方法、理解数据完整性的概念及分类、掌握各种数据完整性的实现方法。下面就是对这些内容的详细教程,请先仔细阅读。
相关知识
索引
索引是根据表中一列或若干列按照一定的顺序建立的列值与记录行之间的对应关系表。在列上创建了索引之后,查找数据是可以直接根据该列上的索引找到对应行的位置,从而快速找到数据。
索引类型分成下列几个:
- 普通索引(
INDEX
):基本索引类型 - 唯一性索引(
UNIQUE
):该列的所有值没有重复 - 主键(
PRIMARY KEY
):一种唯一性索引,一个表只能有一个主键 - 全文索引(
FLLTEXT
):只能在varchar
或text
类型上创建
语法格式:
1 |
|
下面我们用命令行操作试一试。
在创建好整个数据库的基础上,对YGGL
数据库的emp
表的ename
列建立索引:
1 |
|
查看是否创建成功:
1 |
|
重命名索引:
1 |
|
删除索引:
1 |
|
数据完整性
为了防止不合规定的数据进入基表中,我们定义完整性规则。分为:域完整性、实体完整性和参照完整性。
域完整性
域完整性又叫列完整性,主要是对一列的数据进行约束。比如emp
中限定sex
的值只能为1
和2
中的一个,可以在创建表时将sex做以下定义:
1 |
|
或者在所有字段定义完成后加一句:
1 |
|
下面,我们在命令行中通过修改表的方式创建约束:
1 |
|
删除约束:
1 |
|
实体完整性
又叫行完整性,要求每一行都有一个唯一的标识符。比如emp
中的员工eid
是唯一的,才能唯一确定某一个人。通过unique
约束和primary key
约束可以实现实体完整性。
同样的,在创建表时对tel
创建约束应该将tel
定义为:
1 |
|
下面我们在命令行中通过修改表的方式创建约束:
1 |
|
参照完整性
又叫引用完整性,它保证主表和从表中的数据一致性,实现方式是定义外键与主键。例如emp
和sal
表,eid
在emp
中是外键,而在sal
中eid
定义为主键。
- 从表不能引用主表不存在的键值
- 主表中的值更改了,则从表中所有引用都也要修改
- 若要删除主表中的记录,应先删除从表中匹配的记录
如果在创建sal
表时想创建参照完整性使emp
表中所有eid
都要出现在sal
中,可以在定义emp
的eid
时这样定义:
1 |
|
下面我们在命令行中通过修改表的方式定义:
1 |
|
编程要求
同样的,你需要在我们已经创建好整个YGGL
数据库的基础上进行以下操作:
- 建立索引
pk_xs_bak
:对emp
的eid
建立索引; - 实现域完整性
ch_tel
:为emp
的tel
建立check
约束,其值只能为0-9
的数字; - 实现实体完整性
un_dept
:为dept
的dname
创建唯一性索引; - 实现参照完整性
fk_emp
:将emp
中的did
列为外键。
评测说明
请在右侧代码窗口输入MySQL
语句实现以上操作,平台将自动编译你输入的MySQL
语句。
请注意语句的格式并且不要有空行哦:)
特别提醒:SQL
文件的代码不能有空行,否则会报语法错误!
我的代码
1 |
|