目录
8. 对比 TRUNCATE TABLE 和 DELETE FROM
一、数据库概述
1.为什么使用数据库?
①持久化:把数据保存到可掉电式存储设备中以供之后使用。大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以“固化”,而持久化的实现过程大多通过各种关系数据库来完成
②持久化的主要作用是将内存中的数据储存在关系数据库中,当然也可以存储在磁盘文件中
2.数据库与数据库管理系统
2.1数据库相关概念
① DB:数据库(Database)即存储数据的“仓库”,其本质是一个文件系统。保存了一系列有组织的数据。
② DBMS:数据库管理系统(Database Management System)是一种操作和管理数据库的大型软件,用于建立、使用和维护数据库,对数据库进行统一管理和控制。用户通过数据库管理系统访问数据库中表内的数据。
③ SQL:结构化查询语言(Structured Query Language)专门用来与数据库通信的语言。
2.2数据库与数据库管理系统的关系
数据库管理系统可以管理多个数据库,一般开发人员会针对每一个应用创建一个数据库。为保存应用中实体的数据,一般会在数据库中创建多张表,以保存程序中实体用户的数据。
数据库管理系统、数据库和表的关系如图所示:
2.3常见的数据库管理系统排名(DBMS)
链接:https://db-engines.com/en/ranking
3.RDBMS和非RDBMS
从排名中可以看出,关系型数据库绝对是主流,其中使用最多的是Oracle、MySQL和SQL Server。这些都是关系型数据库(RDBMS)
3.1关系型数据库(RDBMS)
3.1.1
- 这种类型的数据库是最古老的数据库类型,关系型数据库模型是把复杂的数据结构归结为简单的二元关系(即二维表格形式)
- 关系型数据库以行(row)和列(column)的形式存储数据,以便用户理解。这一系列的行和列被称为表(table),一组表组成一个库(database)
- 表与表之间的数据记录有关系。现实世界中的各种实体以及实体之间的各种联系均用关系模型来表示。关系型数据库,就是建立在关系模型基础上的数据库。
- SQL就是关系型数据库的查询语言。
3.1.2
- 复杂查询
- 可以用SQL语句方便的在一张表以及多张表之间做非常复杂的数据查询
- 事务支持
- 使得对于安全性能很高的数据访问要求得以实现
3.2 非关系型数据库
3.2.1 介绍
非关系型数据库,可以看成关系型数据库的阉割版本,基于键值对储存数据,不需要经过SQL层的解析,性能非常高。同时,减少不常用的功能,进一步提升性能。
4.关系型数据库的设计规则
- 关系型数据库的典型数据结构就是数据表,这些数据表的组成都是结构化的。
- 将数据放到表中,再将表放到库中。
- 一个数据库可以拥有多张表,每个表都有一个名字,用来标识自己。表名具有唯一性。
- 表具有一些特性,这些特性定义了数据在表中如何存储,类似Java和python中类的设计。
4.1 表、记录、字段
- E-R(entity-relationship,实体-联系)模型中的三个重要概念:实体集、属性、联系集。
- 一个实体集(class)对应数据库中的一个表(table),一个实例(instance)则对于数据库中的一行(row),也称一条记录(record)。一个属性(attribute)对于数据库中的一列(column),也称一个字段(field)。
4.2 表的关联关系
- 表与表之间的数据记录有关系。现实世界的各种实体以及实体之间的各种联系均用关系模型表示。
- 四种:一对一、一对多、多对多、自我引用
4.2.1一对一关联
- 在实际开发中应用不多,因为一对一可以创建成一张表。
- 举例:学生表:学号、姓名、年龄、性别、手机号、身份证号......
- 拆分为两个表:两个表的记录是一一对应关系
- 基础信息表(常用信息):学号、姓名、年龄、性别...
- 档案信息表(不常用信息):学号、手机号、身份证号...
- 两种建表原则:
- 外键唯一:主表的主键的从表的外键(唯一),形成主外键关系,外键唯一。
- 外键是主键:主表的主键和从表的主键,形成主外键关系。
4.2.2 一对多关系
- 常见实例场景:客户表和订单表、分类表和商品表、部门表和员工表。
- 一对比建表原则:在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键
4.2.3 多对多关系
要表示多对多关系,必须创建第三个表,通常称为联接表,它将多对多关系划分为两个一对多关系。将这两个表的主键都插入到第三个表中。
二、基本的SELECT语句
1.SQL语言的规则与规范
1.1基本规则
- SQL可以写在一行或多行。为了提高句子可读性,各子句分行写,必要时使用缩进。
- 每条命令以;或\g或\G结束
- 关键字不能被缩写或分行
- 关于标点符号
- 必须保证所有的()、单引号、双引号的成对的
- 必须使用英文状态下的半角输入方式
- 字符串型和日期时间类型的数据可以使用单引号表示
- 列的别名,尽量使用双引号,而且不建议省略 as
1.2SQL大小写规范(建议)
- MySQL在windows环境下是不区分大小写的
- MySQL在Linux环境下是区分大小写的
- 推进采用统一书写规范
- 数据库名、表名、表的别名、字段名、字段别名等都小写
- SQL关键字、函数名、绑定变量等都大写
1.3注释
可以使用如下格式的注释结构
单行注释:#注释文字(MySQL特有)
单行注释:-- 注释文字(-- 后面必须包含一个空格)
多行注释:/*注释文字*/
2. 基本的SELECT语句
2.1 SELECT ... FROM ...
SELECT 字段名 FROM 表名
2.2 列的别名
- as(alias):别名,可以省略
- 列的别名可以使用一对双引号引起来
举例:
SELECT employee_id emp_id,last_name as lname,department_id "部门id" FROM employees;
2.3 去除重复行
查询员工表中一共有哪些部门id?
- 没有去重的
SELECT department_id FROM employees;
- 去重的
SELECT DISTINCT department_id FROM employees;
2.4 空值参与运算
空值:null,不等同于0,'','null'。空值参与运算,结果也为空!
SELECT employee_id,salary "月工资",salary*(1+commission_pct)*12 "年工资",commission_pct FROM employees;
实际问题解决方案 IFNULL函数
SELECT employee_id,salary "月工资",salary*(1+IFNULL(commission_pct,0))*12 "年工资",commission_pct FROM employees;
2.5 着重号(``)
表名、字段名等与关键字重复时使用。
2.6 查询常数
SELECT 123,order_id,order_name FROM `order`; #123即为常数,也可使用单引号
2.7 显示表结构
DESCRIBE employees;
DESC employees;
3. 过滤数据
关键字:WHERE,必须声明在FROM的后面且相邻
举例:查询90号部门的员工信息
SELECT * FROM employees WHERE department_id = 90;
三、运算符
1. 算术运算符
1.1 加法与减法运算符
SELECT 100,100+0,100-0,100+50-30,100+35.5,100-4.5 FROM DUAL;
注意:在SQL中,‘+’没有连接的作用,只表示加法运算!
2. 比较运算符
比较运算符用来对表达式左边的操作数和右边的操作数进行比较,比较的结果为真则返回1,比较的结果为假则返回0,其他情况返回NULL。
比较运算符经常被用来作为SELECT查询语句的条件来使用,返回符合条件的结果记录。
REGEXP运算符用来匹配字符串,语法格式为:expr REGEXP 匹配条件。如果expr满足匹配条件,返回1;不满足,返回0。若expr或匹配条件任意一个为NULL,则结果为NULL。
REGEXP运算常用通配符:
- '^'匹配以该字符后面的字符开头的字符串
- '$'匹配以该字符前面的字符结尾的字符串
- '.'匹配任意一个单字符
- ”[...]“匹配在括号内的任何字符。例如:”[abc]“匹配"a","b"或"c"。为了命名字符的范围,使用一个'-'。"[a-z]"匹配任何字母,"[0-9]"匹配任何数字。
- '*'匹配零个或多个在它前面的字符。例如:"x*"匹配任何数量的'x'字符,"[0-9]*"匹配任何数量的数字,而'*'匹配任何数量的任何字符。
3. 逻辑运算符
注意:
OR可以和AND 一起使用,但是在使用时注意两者的优先级,由于AND的优先级高于OR,因此先对AND两边的操作数进行操作,再与OR中的操作数结合。
4. 位运算符
在一定范围内满足:每向左移动1位,相当于乘以2;每向右移动1位,相当于除以2。
5. 运算符优先级
四、排序与分页
1. 排序数据
1.1 排序规则
- 使用ORDER BY子句排序
- ASC(ascend):升序(默认)
- DESC(descend):降序
- ORDER BY子句在SELECT语句的结尾
举例:按照salary从高到低的顺序显示员工信息
SELECT employee_id,last_name,salary FROM employees ORDER BY salary DESC;
注意:列的别名只能在ORDER BY中使用!
二级排序,举例:显示员工信息,按照department_id的降序排列,再按照salary的升序排列
SELECT employee_id,salary,department_id FROM employees ORDER BY department_id DESC,salary ASC;
2. 分页
2.1 实现规则
关键字:LIMIT,必须放在整个语句的最后!
举例:每页显示20条记录,此时显示第1页
SELECT employee_id,last_name FROM employees LIMIT 0,20;
总结:每页显示pageSize条记录,此时显示第pageNo页
公式:LIMIT (pageNo - 1)* pageSize,pageSize;
2.2 WHERE ORDER BY LIMIT声明的顺序
SELECT employee_id,last_name,salary
FROM employees
WHERE salary>6000
ORDER BY salary
DESC LIMIT 0,10;
注意:MySQL8.0新特性:LIMIT ... OFFSET 偏移量
举例:LIMIT 2 OFFSET 0(查询第1,2条数据)
五、多表查询
多表查询,也称关联查询,指两个或更多个表一起完成查询操作。
前提条件:这些一起查询的表之间是有关系的(一对一、一对多),它们之间一定是有关联字段,这个关联字段可能建立了外键,也可能没有建立外键。比如:员工表和部门表,这两个表依靠“部门编号”进行关联。
1. 一个案例引发的多表查询
1.1 案例说明
SELECT employee_id,department_name
FROM employees,departments
#连接条件
WHERE employees.department_id = departments.department_id
练习:查询员工的employee_id,last_name,department_id,city
SELECT employee_id,last_name,department_name,city
FROM employees e,departments d,locations l
WHERE e.department_id = d.department_id AND d.location_id = l.location_id
结论:如果有n个表实现多表查询,则需要至少n-1个连接条件 !
2. 多表查询的分类
2.1 等值连接 vs 非等值连接
非等值连接举例:查询员工工资以及对应等级
SELECT last_name,salary,grade_level
FROM employees e,job_grades j
WHERE e.salary BETWEEN j.lowest_sal AND j.highest_sal;
2.2 自连接 vs 非自连接
自连接举例:查询员工id,姓名及其管理者的id和姓名
SELECT emp1.employee_id,emp1.last_name,emp2.employee_id,emp2.last_name
FROM employees emp1,employees emp2
WHERE emp1.manager_id = emp2.employee_id
2.3 内连接 vs 外连接
内连接:合并具有同一列的两个以上的表的行,结果集中不包含一个表与另一个表不匹配的行
外连接:两个表在连接过程中除了返回满足条件的行以外还返回左(或右)表中不满足条件的行,这种连接称为左(或右)外连接。没有匹配的行时,结果表中相应的列为空(NULL)。
如果是左外连接,则连接条件中左边的表也成为主表,右边的表称为从表。
如果是右外连接,则连接条件中右边的表也成为主表,左边的表称为从表。
SQL99语法内连接(JOIN...ON...)
SELECT employee_id,last_name,department_name,city
#INNER可以省略
FROM employees e INNER JOIN departments d ON e.department_id = d.department_id
JOIN locations l ON d.location_id = l.location_id
SQL99语法外连接(JOIN...ON...)
举例:查询所有的员工的last_name,department_name信息
SELECT last_name,department_name
#LEFT OUTER JOIN 左外连接 OUTER可以省略
FROM employees e LEFT OUTER JOIN departments d
ON e.department_id = d.department_id
2.4 UNION的使用
合并查询结果
利用UNION关键字,可以给出多条SELECT语句,并将它们的结果组合成单个结果集。合并时,两个表对应的列数和数据类型必须相同,并且相互对应。各个SELECT语句之间使用UNION或UNION ALL关键字分割。
语法格式:
SELECT column,....FROM table1
UNION [ALL]
SELECT column,....FROM table1
UNION操作符
UNION ALL操作符
注意: 执行UNION ALL语句时所需要的资源比UNION语句少。如果明确知道合并数据后的结果数据不存在重复数据,或不需要去重,则尽量使用UNION ALL,提高查询效率。
2.5 7种SQL JOINS的实现
A:员工表 B:部门表
2.5.1 内连接
SELECT employee_id,department_name
FROM employees e JOIN departments d
ON e.department_id=d.department_id;
2.5.2 左外连接
SELECT employee_id,department_name
FROM employees e LEFT JOIN departments d
ON e.department_id=d.department_id;
2.5.3 右外连接
SELECT employee_id,department_name
FROM employees e RIGHT JOIN departments d
ON e.department_id=d.department_id;
2.5.4
SELECT employee_id,department_name
FROM employees e LEFT JOIN departments d
ON e.department_id=d.department_id
WHERE d.department_id IS NULL;
2.5.5
SELECT employee_id,department_name
FROM employees e RIGHT JOIN departments d
ON e.department_id=d.department_id
WHERE e.department_id IS NULL;
2.5.6 满外连接
方式一:2 UNION ALL 5
SELECT employee_id,department_name
FROM employees e LEFT JOIN departments d
ON e.department_id=d.department_id
UNION ALL
SELECT employee_id,department_name
FROM employees e RIGHT JOIN departments d
ON e.department_id=d.department_id
WHERE e.department_id IS NULL;
方式二:3 UNION ALL 4
2.5.7
方式:4 UNION ALL 5
2.6 自然连接
SQL99在SQL92的基础上提供了一些特殊语法,比如NATURAL JOIN用来表示自然连接。我们可以把自然连接理解为SQL92中的等值连接。它会帮你自动连接查询两张表中所有相同的字段,然后进行等值连接。
SQL92:
SELECT employee_id,department_name
FROM employees e JOIN departments d
ON e.department_id=d.department_id
AND e.manager_id=d.manager_id;
SQL99:
SELECT employee_id,department_name
FROM employees e NATURAL JOIN departments d;
2.7 USING连接
当我们进行连接的时候,SQL99还支持使用USING指定数据表里的同名字段进行等值连接。但是只能配个JOIN使用。比如:
SELECT employee_id,department_name
FROM employees e JOIN departments d
USING (department_id);
注意:我们要控制连接表的数量。多表连接就相当于嵌套for循环一样,非常消耗资源,会让SQL查询性能下降的很严重,因此不要连接不必要的表。在需要DBMS中,也都会有最大连接表的限制。
【强制】:超过3个表,禁止使用JOIN。需要JOIN的字段,数据类型保持绝对一致;多表连接查询时,保证被关联的字段需要有索引
六、单行函数
说明:
- 操作数据对象
- 接受参数返回一个结果
- 只对一行进行转换
- 每行返回一个结果
- 可以嵌套
- 参数可以是一列或一个值
1.数值函数
1.1基本函数
1.2 角度与弧度互换函数
1.3 三角函数
2.字符串函数
注意:MySQL中,字符串的位置是从1开始的!