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

单关系查询

SQL 查询的基本结构由三个子句构成,selectfromwhere,查询的输入是 from 子句中列出的关系,在这些关系上进行 whereselect 子句指定的运算,然后产生一个关系作为结果,即 SQL 查询的结果是一个关系,这点很重要。

先考虑一个简单的查询,找出所有教师的名字,教师的名字可以在 instructor 关系中找到,这样我们 from instructor 来查询;教师的名字出现在 name 属性中,这样我们使用 select name 子句,综合起来就是下面的查询。

  1. mysql> select name
  2. -> from instructor;
  3. +------------+
  4. | name |
  5. +------------+
  6. | Srinivasan |
  7. | Wu |
  8. | Mozart |
  9. | Einstein |
  10. | El Said |
  11. | Gold |
  12. | Katz |
  13. | Califieri |
  14. | Singh |
  15. | Crick |
  16. | Brandt |
  17. | Kim |
  18. +------------+
  19. 12 rows in set (0.01 sec)

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

  1. mysql> select dept_name
  2. -> from instructor;
  3. +------------+
  4. | dept_name |
  5. +------------+
  6. | Biology |
  7. | Comp. Sci. |
  8. | Comp. Sci. |
  9. | Comp. Sci. |
  10. | Elec. Eng. |
  11. | Finance |
  12. | Finance |
  13. | History |
  14. | History |
  15. | Music |
  16. | Physics |
  17. | Physics |
  18. +------------+
  19. 12 rows in set (0.00 sec)

注意到 Comp. Sci. 等行出现了不止一次,这是因为一个系可能有多个教师。

在关系模型的形式化数学定义中,关系是一个集合,因此关系中不包含重复的元素。但在实践中,有时我们希望保留重复,更关键的事,去掉重复是消耗较大的,因此 SQL 默认在关系以及 SQL 表达式结果中允许出现重复。

如果我们想要去掉重复,可以在 select 后加入关键字 distinct,也就是像下面这样。

  1. mysql> select distinct dept_name
  2. -> from instructor;
  3. +------------+
  4. | dept_name |
  5. +------------+
  6. | Biology |
  7. | Comp. Sci. |
  8. | Elec. Eng. |
  9. | Finance |
  10. | History |
  11. | Music |
  12. | Physics |
  13. +------------+
  14. 7 rows in set (0.01 sec)

完整地说,SQL 支持使用关键字 all 来显式指明不去掉重复,但因为标准默认的行为即保留重复元组,因此不使用 all 才是更符合习惯的写法。

select 子句还可带含有四则运算运算符的表达式,运算对象可以是常数或元组的属性,这一点对应关系代数运算中的广义投影,看下面的查询。

  1. mysql> select ID, name, dept_name, salary * 1.1
  2. -> from instructor;
  3. +-------+------------+------------+--------------+
  4. | ID | name | dept_name | salary * 1.1 |
  5. +-------+------------+------------+--------------+
  6. | 10101 | Srinivasan | Comp. Sci. | 71500.000 |
  7. | 12121 | Wu | Finance | 99000.000 |
  8. | 15151 | Mozart | Music | 44000.000 |
  9. | 22222 | Einstein | Physics | 104500.000 |
  10. | 32343 | El Said | History | 66000.000 |
  11. | 33456 | Gold | Physics | 95700.000 |
  12. | 45565 | Katz | Comp. Sci. | 82500.000 |
  13. | 58583 | Califieri | History | 68200.000 |
  14. | 76543 | Singh | Finance | 88000.000 |
  15. | 76766 | Crick | Biology | 79200.000 |
  16. | 83821 | Brandt | Comp. Sci. | 101200.000 |
  17. | 98345 | Kim | Elec. Eng. | 88000.000 |
  18. +-------+------------+------------+--------------+
  19. 12 rows in set (0.00 sec)

这个查询,如上所示,返回一个与 instructor 一样的关系,除了属性 salary 的值是原来的 1.1 倍,查询的语义是为每位教师增长 10% 的工资的结果,注意这并不修改 instructor 关系,而是返回了一个新的关系。

where 子句允许我们只选出那些在 from 子句的结果关系中满足特定谓词的元组。

考虑查询,找出所有在 Computer Science 系并且工资超过 70000 美元的教师的姓名。我们可以使用 where 子句写出下面的查询。

  1. mysql> select name
  2. -> from instructor
  3. -> where dept_name = 'Comp. Sci.' and salary > 70000;
  4. +--------+
  5. | name |
  6. +--------+
  7. | Katz |
  8. | Brandt |
  9. +--------+
  10. 2 rows in set (0.01 sec)

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

多关系查询

上面的查询都是基于单个关系的,但是通常我们的查询需要从多个关系中获取信息。

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

  1. mysql> select name, instructor.dept_name, building
  2. -> from instructor, department
  3. -> where instructor.dept_name = department.dept_name;
  4. +------------+------------+----------+
  5. | name | dept_name | building |
  6. +------------+------------+----------+
  7. | Crick | Biology | Watson |
  8. | Srinivasan | Comp. Sci. | Taylor |
  9. | Katz | Comp. Sci. | Taylor |
  10. | Brandt | Comp. Sci. | Taylor |
  11. | Kim | Elec. Eng. | Taylor |
  12. | Wu | Finance | Painter |
  13. | Singh | Finance | Painter |
  14. | El Said | History | Painter |
  15. | Califieri | History | Painter |
  16. | Mozart | Music | Packard |
  17. | Einstein | Physics | Watson |
  18. | Gold | Physics | Watson |
  19. +------------+------------+----------+
  20. 12 rows in set (0.00 sec)

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

再考虑一个查询,找出 Computer Science 系的教师名字和教授的课程标识

  1. mysql> select name, course_id
  2. -> from instructor, teaches
  3. -> where instructor.ID = teaches.ID and dept_name = 'Comp. Sci.';
  4. +------------+-----------+
  5. | name | course_id |
  6. +------------+-----------+
  7. | Srinivasan | CS-101 |
  8. | Srinivasan | CS-315 |
  9. | Srinivasan | CS-347 |
  10. | Katz | CS-101 |
  11. | Katz | CS-319 |
  12. | Brandt | CS-190 |
  13. | Brandt | CS-190 |
  14. | Brandt | CS-319 |
  15. +------------+-----------+
  16. 8 rows in set (0.00 sec)

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

通常说来,一个 SQL 查询的含义可以这么理解:

  1. 按照 from 子句中列出的关系产生笛卡尔积
  2. 在步骤 1 的结果上应用 where 子句指定的谓词筛选
  3. 在步骤 2 的结果上输出 select 子句指定的属性或表达式的结果

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

基于 MySQL 的数据库实践(基本查询)的更多相关文章

  1. 基于 MySQL 的数据库实践(准备工作)

    背景 本学期在北京大学选修了<数据库概论>的实验班课程,由于 SQL 语法并不是特别理论的内容,因此课上暂时也没有特别展开.出于探索数据库领域的兴趣,使用国内普遍使用的数据库软件 MySQ ...

  2. 基于 MySQL 的数据库实践(自然连接)

    在基本查询一节的示例中,我们有从 instructor 和 teaches 表组合信息,匹配条件是 instructor.ID 等于 teaches.ID 的查询,ID 属性是两个表中具有相同名称的所 ...

  3. MySQL(三) 数据库表的查询操作【重要】

    序言 1.MySQL表操作(创建表,查询表结构,更改表字段等), 2.MySQL的数据类型(CHAR.VARCHAR.BLOB,等), 本节比较重要,对数据表数据进行查询操作,其中可能大家不熟悉的就对 ...

  4. mysql基础-数据库表简单查询-记录(五)

    0x01 MySQL的查询操作 单表查询:简单查询                 多表查询:连续查询                联合查询 选择和投影 投影:挑选要符合的字段     select ...

  5. 新浪微博基于MySQL的分布式数据库实践

    提起微博,相信大家都是很了解的.但是有谁知道微博的数据库架构是怎样的呢?在今天举行的2011数据库技术大会上,新浪首席DBA杨海潮为我们详细解读了新浪微博的数据库架构——基于MySQL的分布式数据库实 ...

  6. 企业运维 | MySQL关系型数据库在Docker与Kubernetes容器环境中快速搭建部署主从实践

    [点击 关注「 WeiyiGeek」公众号 ] 设为「️ 星标」每天带你玩转网络安全运维.应用开发.物联网IOT学习! 希望各位看友[关注.点赞.评论.收藏.投币],助力每一个梦想. 本章目录 目录 ...

  7. 基于Mysql数据库亿级数据下的分库分表方案

    移动互联网时代,海量的用户数据每天都在产生,基于用户使用数据的用户行为分析等这样的分析,都需要依靠数据都统计和分析,当数据量小时,问题没有暴露出来,数据库方面的优化显得不太重要,一旦数据量越来越大时, ...

  8. 0818基于360开源数据库流量审计MySQL Sniffer

    开源数据库流量审计MySQL Sniffer 我最推崇的数据库安全产品就是基于流量的数据库审计,因为它不需要更改网络结构,并且也是最关键的是,不影响数据库服务器性能,不用苦口婆心的劝数据库管理员安装监 ...

  9. 基于 MySQL Binlog 的 Elasticsearch 数据同步实践 原

    一.背景 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品.订单等数据的多维度检索. 使用 Elasticsearch 存储业务数据可以 ...

随机推荐

  1. Android_scaleType属性

    这里我们重点理解ImageView的属性android:scaleType,即ImageView.setScaleType(ImageView.ScaleType).android:scaleType ...

  2. Hive 报错:java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.metastore.HiveMetaStoreClient

    在配置好hive后启动报错信息如下: [walloce@bigdata-study- hive--cdh5.3.6]$ bin/hive Logging initialized using confi ...

  3. CountDownLatch 源码解析—— await()

    上一篇文章说了一下CountDownLatch的使用方法.这篇文章就从源码层面说一下await() 的原理. 我们已经知道await 能够让当前线程处于阻塞状态,直到锁存器计数为零(或者线程中断). ...

  4. Linux进程间通信-消息队列(mqueue)

    前面两篇文章分解介绍了匿名管道和命名管道方式的进程间通信,本文将介绍Linux消息队列(posix)的通信机制和特点. 1.消息队列 消息队列的实现分为两种,一种为System V的消息队列,一种是P ...

  5. java虚拟机的内存分配与回收机制

    分为4个方面来介绍内存分配与回收,分别是内存是如何分配的.哪些内存需要回收.在什么情况下执行回收.如何监控和优化GC机制. java GC(Garbage Collction)垃圾回收机制,是java ...

  6. beta冲刺2

    q前言:今天晚上大概把github的的相关东西弄上了.然后把之前做的一些修改什么的也上传上去了.目测之后的话就是在自己这边改完然后直接上github那边去复制粘贴替换掉了. 昨天的问题:github这 ...

  7. Alpha第四天

    Alpha第四天 听说 031502543 周龙荣(队长) 031502615 李家鹏 031502632 伍晨薇 031502637 张柽 031502639 郑秦 1.前言 任务分配是VV.ZQ. ...

  8. 雷云Razer Synapse2.0使用测评 -第二次作业

    雷蛇云驱动Razer Synapse2.0使用测评 雷蛇(Razer)是全球顶级游戏设备品牌之一,1998年由CEO Min-Liang Tan和Robert "Razerguy" ...

  9. 从PRISM开始学WPF(六)MVVM(二)Command?

    从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WPF(三)Prism-Region? 从PRISM开始学WPF(四)Prism-Module? ...

  10. Linux环境下发布.net core

    一.安装Linux环境 1. 安装VM虚拟机和操作系统 VM虚拟工具安装的过程详见:http://blog.csdn.net/stpeace/article/details/78598333.直接按照 ...