前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于 MySQL 的数据库实践(基本查询)

基于 MySQL 的数据库实践(基本查询)

作者头像
星哥玩云
发布2022-08-16 14:39:32
1.1K0
发布2022-08-16 14:39:32
举报
文章被收录于专栏:开源部署

首先根据准备工作中的操作导入大学模式,打开数据库连接后进入到 MySQL 的交互界面,再使用命令 use db-book; 切换到 db-book 数据库

单关系查询

SQL 查询的基本结构由三个子句构成,select,from 和 where,查询的输入是 from 子句中列出的关系,在这些关系上进行 where 和 select 子句指定的运算,然后产生一个关系作为结果,即 SQL 查询的结果是一个关系,这点很重要。  先考虑一个简单的查询,找出所有教师的名字,教师的名字可以在 instructor 关系中找到,这样我们 from instructor 来查询;教师的名字出现在 name 属性中,这样我们使用 select name 子句,综合起来就是下面的查询。

mysql> select name     -> from instructor; +------------+ | name      | +------------+ | Srinivasan | | Wu        | | Mozart    | | Einstein  | | El Said    | | Gold      | | Katz      | | Califieri  | | Singh      | | Crick      | | Brandt    | | Kim        | +------------+ 12 rows in set (0.01 sec)

现在考虑另一个查询,找出所有教师所在的系名。

mysql> select dept_name     -> from instructor; +------------+ | dept_name  | +------------+ | Biology    | | Comp. Sci. | | Comp. Sci. | | Comp. Sci. | | Elec. Eng. | | Finance    | | Finance    | | History    | | History    | | Music      | | Physics    | | Physics    | +------------+ 12 rows in set (0.00 sec)

注意到 Comp. Sci. 等行出现了不止一次,这是因为一个系可能有多个教师。  在关系模型的形式化数学定义中,关系是一个集合,因此关系中不包含重复的元素。但在实践中,有时我们希望保留重复,更关键的事,去掉重复是消耗较大的,因此 SQL 默认在关系以及 SQL 表达式结果中允许出现重复。  如果我们想要去掉重复,可以在 select 后加入关键字 distinct,也就是像下面这样。

mysql> select distinct dept_name     -> from instructor; +------------+ | dept_name  | +------------+ | Biology    | | Comp. Sci. | | Elec. Eng. | | Finance    | | History    | | Music      | | Physics    | +------------+ 7 rows in set (0.01 sec)

完整地说,SQL 支持使用关键字 all 来显式指明不去掉重复,但因为标准默认的行为即保留重复元组,因此不使用 all 才是更符合习惯的写法。 select 子句还可带含有四则运算运算符的表达式,运算对象可以是常数或元组的属性,这一点对应关系代数运算中的广义投影,看下面的查询。

mysql> select ID, name, dept_name, salary * 1.1     -> from instructor; +-------+------------+------------+--------------+ | ID    | name      | dept_name  | salary * 1.1 | +-------+------------+------------+--------------+ | 10101 | Srinivasan | Comp. Sci. |    71500.000 | | 12121 | Wu        | Finance    |    99000.000 | | 15151 | Mozart    | Music      |    44000.000 | | 22222 | Einstein  | Physics    |  104500.000 | | 32343 | El Said    | History    |    66000.000 | | 33456 | Gold      | Physics    |    95700.000 | | 45565 | Katz      | Comp. Sci. |    82500.000 | | 58583 | Califieri  | History    |    68200.000 | | 76543 | Singh      | Finance    |    88000.000 | | 76766 | Crick      | Biology    |    79200.000 | | 83821 | Brandt    | Comp. Sci. |  101200.000 | | 98345 | Kim        | Elec. Eng. |    88000.000 | +-------+------------+------------+--------------+ 12 rows in set (0.00 sec)

这个查询,如上所示,返回一个与 instructor 一样的关系,除了属性 salary 的值是原来的 1.1 倍,查询的语义是为每位教师增长 10% 的工资的结果,注意这并不修改 instructor 关系,而是返回了一个新的关系。 where 子句允许我们只选出那些在 from 子句的结果关系中满足特定谓词的元组。  考虑查询,找出所有在 Computer Science 系并且工资超过 70000 美元的教师的姓名。我们可以使用 where 子句写出下面的查询。

mysql> select name     -> from instructor     -> where dept_name = 'Comp. Sci.' and salary > 70000; +--------+ | name  | +--------+ | Katz  | | Brandt | +--------+ 2 rows in set (0.01 sec)

SQL 允许在 where 子句中使用逻辑连词 and,or 和 not,逻辑连词的运算对象可以是包含比较运算符的表达式。注意相等用 = 表示,不相等用 <> 表示。

多关系查询

上面的查询都是基于单个关系的,但是通常我们的查询需要从多个关系中获取信息。  考虑查询,找出所有教师的姓名,以及他们所在的系的名称和系所在的建筑物的名称。考虑 instructor 关系的模式,我们可以从 dept_name 属性得到系名,但是系所在的建筑物的名称记录在 department 关系的 building 属性中,为了回答查询,instructor 关系中的每个元组必须与 department 关系中的元组匹配,后者在 dept_name 上的取值等于 instructor 元组在 dept_name 上的取值。有了这样的思路,我们可以尝试写对应的 SQL 查询。

mysql> select name, instructor.dept_name, building     -> from instructor, department     -> where instructor.dept_name = department.dept_name; +------------+------------+----------+ | name      | dept_name  | building | +------------+------------+----------+ | Crick      | Biology    | Watson  | | Srinivasan | Comp. Sci. | Taylor  | | Katz      | Comp. Sci. | Taylor  | | Brandt    | Comp. Sci. | Taylor  | | Kim        | Elec. Eng. | Taylor  | | Wu        | Finance    | Painter  | | Singh      | Finance    | Painter  | | El Said    | History    | Painter  | | Califieri  | History    | Painter  | | Mozart    | Music      | Packard  | | Einstein  | Physics    | Watson  | | Gold      | Physics    | Watson  | +------------+------------+----------+ 12 rows in set (0.00 sec)

注意 dept_name 属性既出现在 instructor 关系中,也出现在 department 关系中,关系名作为前缀可以说明我们指的是哪一个属性,与之相反,name 属性和 building 属性只出现在一个关系中,因而不需要把关系名作为前缀。这种命名惯例的使用,要求出现在 from 子句中的关系具有可区分的名字,在某些情况下这样的要求达不到,例如当需要组合来自同一个关系的两个不同元组的信息的时候,对于这种情况,在后面我们会提到可以用更名(rename)运算来处理。  再考虑一个查询,找出 Computer Science 系的教师名字和教授的课程标识

mysql> select name, course_id     -> from instructor, teaches     -> where instructor.ID = teaches.ID and dept_name = 'Comp. Sci.'; +------------+-----------+ | name      | course_id | +------------+-----------+ | Srinivasan | CS-101    | | Srinivasan | CS-315    | | Srinivasan | CS-347    | | Katz      | CS-101    | | Katz      | CS-319    | | Brandt    | CS-190    | | Brandt    | CS-190    | | Brandt    | CS-319    | +------------+-----------+ 8 rows in set (0.00 sec)

这里 dept_name 只出现在 instructor 关系中,因此不必要写 instructor.dept_name。

通常说来,一个 SQL 查询的含义可以这么理解: 1.按照 from 子句中列出的关系产生笛卡尔积 2.在步骤 1 的结果上应用 where 子句指定的谓词筛选 3.在步骤 2 的结果上输出 select 子句指定的属性或表达式的结果

注意这是逻辑上的执行方式,实际执行会有较多的优化方式,例如尽可能地不产生一个庞大的笛卡尔积,而是只产生满足 where 子句的笛卡尔积元素。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档