做者|不剪发的Tony老师php
本文介绍关系数据库的设计思想:在 SQL 中,一切皆关系。sql
在计算机领域有许多伟大的设计理念和思想,例如:数据库
在 Unix 中,一切皆文件。编程
在面向对象的编程语言中,一切皆对象。数据结构
关系数据库一样也有本身的设计思想:在 SQL 中,一切皆关系。编程语言
关系模型ide
关系模型(Relational model)由 E.F.Codd 博士于 1970 年提出,以集合论中的关系概念为基础;不管是现实世界中的实体对象仍是它们之间的联系都使用关系表示。咱们在数据库系统中看到的关系就是二维表(Table),由行(Row)和列(Column)组成。所以,也能够说关系表是由数据行构成的集合。面向集合函数
SQL(结构化查询语言)是操做关系数据库的标准语言。SQL 很是接近英语,使用起来很是简单。它在设计之初就考虑了非技术人员的使用需求,咱们一般只需说明想要的结果(What),而将数据处理的过程(How)交给数据库管理系统。因此说,SQL 才是真正给人用的编程语言! 接下来咱们具体分析一下关系的各类操做语句;目的是为了让你们可以了解 SQL 是一种面向集合的编程语言,它的操做对象是集合,操做的结果也是集合。????在关系数据库中,关系、表、集合三者一般表示相同的概念。
SELECT employee_id, first_name, last_name, hire_date
FROM employees;
它的做用就是从 employees 表中查询员工信息。显然,咱们都知道 FROM 以后是一个表(关系、集合)。不只如此,整个查询语句的结果也是一个表。因此,咱们能够将上面的查询做为表使用:
SELECT *
FROM (SELECT employee_id, first_name, last_name, hire_date
FROM employees) t;
括号内的查询语句被称为派生表,咱们给它指定了一个别名叫作 t。一样,整个查询结果也是一个表;这就意味着咱们能够继续嵌套,虽然这么作很无聊。
咱们再看一个 PostgreSQL 中的示例:
-- PostgreSQL
SELECT *
FROM upper('sql');
| upper |
|-------|
| SQL |
upper() 是一个大写转换的函数。它出现再 FROM 子句中,意味着它的结果也是一个表,只不过是 1 行 1 列的特殊表。
SELECT 子句用于指定须要查询的字段,能够包含表达式、函数值等。SELECT 在关系操做中被称为投影(Projection),看下面的示意图应该就比较好理解了。
GROUP BYspa
SELECT department_id, count(*), first_name
FROM employees
GROUP BY department_id;
该语句的目的是按照部门统计员工的数量,可是存在一个语法错误,就是 first_name 不能出如今查询列表中。缘由在于按照部门进行分组的话,每一个部门包含多个员工;没法肯定须要显示哪一个员工的姓名,这是一个逻辑上的错误。
因此说,GROUP BY 改变了集合元素(数据行)的结构,建立了一个全新的关系。分组操做的示意图以下:
UNION设计
SQL 面向集合特性最明显的体现就是 UNION(并集运算)、INTERSECT(交集运算)和 EXCEPT/MINUS(差集运算)。 这些集合运算符的做用都是将两个集合并成一个集合,所以须要知足如下条件:????SQL 中的关系概念来自数学中的集合理论,所以 UNION、INTERSECT 和 EXCEPT 分别来自集合论中的并集(∪\cup∪)、交集(∩\cap∩)和差集(∖\setminus∖)运算。须要注意的是,集合理论中的集合不容许存在重复的数据,可是 SQL 容许。所以,SQL 中的集合也被称为多重集合(multiset);多重集合与集合理论中的集合都是无序的,可是 SQL 能够经过 ORDER BY 子句对查询结果进行排序。
JOIN
在 SQL 中,不只实体对象存储在关系表中,对象之间的联系也存储在关系表中。所以,当咱们想要获取这些相关的数据时,须要使用到另外一个操做:链接查询(JOIN)。 常见的 SQL链接查类型包括内链接、外链接、交叉链接等。其中,外链接又能够分为左外链接、右外链接以及全外链接。 内链接(Inner Join)返回两个表中知足链接条件的数据,内链接的原理以下图所示:t1 RIGHT JOIN t2
t2 LEFT JOIN t1
全外链接(Full Outer Join)等价于左外链接加上右外链接,同时返回左表和右表中全部的数据;对于两个表中不知足链接条件的数据返回空值。全外链接的原理以下图所示:
????其余类型的链接还有半链接(SEMI JOIN)、反链接(ANTI JOIN)。集合操做将两个集合合并成一个更大或更小的集合;链接查询将两个集合转换成一个更大或更小的集合,同时得到了一个更大的元素(更多的列)。不少时候集合操做均可以经过链接查询来实现,例如:
SELECT department_id
FROM departments
UNION
SELECT department_id
FROM employees;
等价于:
SELECT COALESCE(d.department_id, e.department_id)
FROM departments d
FULL JOIN employees e ON (e.department_id = d.department_id);
咱们已经介绍了许多查询的示例,接下来看看其余的数据操做。
DML
DML 表示数据操做语言,也就是插入、更新和删除。如下是一个插入语句示例:CREATE TABLE test(id int);
-- MySQL、SQL Server 等
INSERT INTO test(id) VALUES (1),(2),(3);
-- Oracle
INSERT INTO test(id)
(SELECT 1 AS id FROM DUAL
UNION ALL
SELECT 2 FROM DUAL
UNION ALL
SELECT 3 FROM DUAL);
咱们经过一个 INSERT 语句插入了 3 条记录,或者说是插入了一个包含 3 条记录的关系表。由于,UNION ALL 返回的是一个关系表。VALUES 一样是指定了一个关系表,在 SQL Server 和 PostgreSQL 中支持如下语句:
SELECT *
FROM (
VALUES(1),(2),(3)
) test(id);
前面咱们已经说过,FROM 以后是一个关系表,因此这里的 VALUES 也是同样。因为咱们常常插入单条记录,并无意识到其实是以表为单位进行操做。
一样,UPDATE 和 DELETE 语句也都是以关系表为单位的操做;只不过咱们习惯了说更新一行数据或者删除几条记录。