MySQL全网最细总结

一.SQL语句简介

1.sql、DB、DBMS分别是什么,以及他们之间的关系?

(1)SQL(Structured Query Language):结构化查询语言
其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在不一样的地方,称为“方言”
(2)DB: DataBase(数据库,数据库实际上在硬盘上以文件的形式存在)
(3)DBMS: DataBase Management System(数据库管理系统,常见的有:MySQL Oracle DB2 Sybase SqlServer…)

2.SQL分类

(1)DDL(Data Definition Language)数据库定义语言:create drop alter,对表结构的增删改
(2)DML(Data Manipulation Language)数据库操作语言:用来对数据库表中的数据进行增删改。
关键字:insert,delete,update等
(3)DQL(Data Query Language)数据查询语言:用来查询数据表中的记录(数据) ,关键字:select,where等
(4)DCL(Data Control Language)数据控制语言:grant授权、revoke撤销权限等。
(5)TCL(事务控制语言):commit提交事务,rollback回滚事务(TCL中的T是Transaction)

二.MySql常用数据类型

在这里插入图片描述

三.数据库操作

1.创建和使用数据库

(1)使用指令创建数据库

CREATE DATABASE IF NOT EXISTS db1;

①创建数据库:
create database 数据库名称
②创建数据库,先判断不存在,再去创建
create database if not exists 数据库名称;
(2)创建一个使用utf8字符集的数据库

CREATE DATABASE db2 CHARACTER SET utf8;

(3)创建一个使用utf_8字符集,并带校对规则的数据库

CREATE DATABASE db3 CHARACTER SET utf8 COLLATE utf8_bin;

(4)校对规则utf8_bin区分大小,默认utf_8_general_ci 不区分大小写(如Tom和tom一样)

(5)使用数据库:use 数据库名;
(6)select version(); 查看mysql的版本号

2.查询和删除数据库

(1)查看当前数据库服务器中的所有数据库

SHOW DATABASES;

(2)查看当前使用的数据库
select database();

(2)查看创建的db2数据库的定义信息

SHOW CREATE DATABASE db2;

(3)在创建数据库,表的时候,为了避免关键字,可以使用反引号解决(比如数据库名为关键字create)

CREATE DATABASE `create`;

(4)删除数据库

DROP DATABASE db1;

3.备份/恢复数据库

当一个文件的扩展名是.sql,并且该文件中编写了大量的sql语句,我们称这样的文件为sql脚本。
注意:直接使用source slq路径命令可以执行sql脚本。

(1)备份,要在DOS下执行指令
mysqldump -u 用户名 -p -B 数据库1,数据库2,数据库n > 文件名.sql;

mysqldump -u root -p -B db2 > d:\\db2.sql;

(2)恢复数据库(注意:要在DOS中进入MySQL命令行再执行)

source d:\\db2.sql;

补充(备份库中的表):mysqldump -u 用户名 -p 数据库 表1 表2 表n > 文件名.sql;

四.表操作

1.创建表

CREATE TABLE table_name(
	field1 datatype,
	field2 datatype,
	field3 datatype	
)character set 字符集 collate 校对规则 engine 存储引擎

(1)field:指定列名
(2)datatype:指定列类型(字段类型)
(3)character set:如果不指定则为所在数据库字符集
(4)collate:如果不指定则为所在数据库校对规则
(5)engine:引擎

2.修改/查看表

(1)添加列
ALTER TABLE tablename
ADD (column1 datatype [表达式语句]
,column2 datatype [表达式语句);

-- t_user表上新增一个varchar类型的image列(要求在email后面)
ALTER TABLE t_user 
  ADD image VARCHAR (32) NOT NULL DEFAULT ''
  AFTER email;

补充:给已经存在数据的表添加自动增长字段

ALTER TABLE 表名
ADD COLUMN 字段名 INT AUTO_INCREMENT PRIMARY KEY;

(2)修改列
ALTER TABLE tablename
MODIFY (column1 datatype [表达式语句];
,column2 datatype [表达式语句))
(3)删除列
ALTER TABLE tablename
DROP column;
(4)修改表名
RENAME TABLE 表名 to 新表名;
(5)修改表字符集
alter table 表名 character set 字符集;
(6)desc 表名; // 查看表的结构

五.CRUD语句

提示:
(1)任何一条sql语句以“ ;”结尾
(2)sql语句不区分大小写

1.Insert语句

insert into 表名(列名1,列名2,...列名n) values(1,2,...,值n);

细节:
(1)插入的数据要与字段的数据类型相同,比如把‘abc’添加到int类型会报错
(2)数据的长度应在列的规定范围内,例如:不能将一个长度为80的字符串加入到长度为40的列中
(3)在values中列出的数据位置必须与被加入的列的排列位置相对应
(4)字符和日期类型数据应包含在单引号中
(5)列可以插入空值(前提是该字段允许为空)
(6)如果是给表中的所有字段添加数据,可以不写前面的字段名称

insert into 表名 values(1,2,...值n);

(7)默认值的使用,当不给某个字段值时,如果有默认值就会添加,否则报错

2.Delete语句

delete from 表名 [where 条件];

(1)如果不加条件,则删除表中所有记录
(2)如果要删除所有记录
delete from 表名; – 不推荐使用。有多少条记录就会执行多少次删除操作
TRUNCATE TABLE 表名; – 推荐使用,效率更高,先删除表,然后再创建一张一样的表

3.Update语句

update 表名 set 列名1 = 值1,列名2 = 值2,…[where 条件];
(1)set子句指示要修改哪些列和要赋予那些值
(2)where子句指定应更新哪些列;如果没有where子句,则更新所有的行
(3)如果需要修改多个字段,可以通过set 字段1=值1,字段2=值2…

4.Select语句

4.1 基本语法

select
	字段列表
from
	表名列表
where
	条件列表
group by
	分组字段
having
	分组之后的条件
order by 
	排序字段 排序方式	
limit
	分页限定

以上语句的执行顺序:
(1)首先执行where语句过滤原始数据
(2)执行group by进行分组
(3)执行having对分组数据进行操作
(4)执行select选出数据
(5)执行order by排序

原则:能在where中过滤的数据,尽量在where中过滤,效率较高。having的过滤是专门对分组之后的数据进行过滤的。

4.2 基础查询

(1)多个字段的查询

select 字段名1,字段名2...from 表名;

注意:如果查询所有字段,则可以使用*来替代字段列表(实际开发不建议使用,效率较低)
(2)去除重复:distinct只能出现在所有字段的最前面。

select distinct deptno,job from emp;

(4)给查询结果的列起别名:as(as也可以省略)
①语法:

select columnname as 别名 from 表名;

②别名中有中文(标准sql语句要求单引号,mysql中单双都可以):

select salary * 12 as '年薪' from emp;  

4.3 条件查询

条件查询需要用到where语句,where必须放到from语句表的后面,支持如下运算符:

在这里插入图片描述
(1)between and除了可以使用在数字方面之外,还可以使用在字符串方面。

select ename from emp where ename between 'A' and 'C';

(2)在数据库当中NULL不是一个值,代表什么也没有,为空。空不是一个值,不能用等号衡量。
必须使用 is null或者is not null

select ename,sal,comm from emp where comm is null;

(3)in等同于or,select ename,job from emp where sal in(800, 5000); // in后面的值不是区间,是具体的值。
not in: 不在这几个值当中。
(4)找出名字中第二个字母是A的?

select ename from emp where ename like '_A%';
+--------+
| ename  |
+--------+
| WARD   |
| MARTIN |
| JAMES  |
+--------+

4.4 排序查询

(1)语法:order by 子句
select * from 表名 order by 排序字段1 排序方式1,排序字段2 排序方式2...
(2)排序方式:
①ASC:升序,默认的
②DESC:降序
(3)order by 子句应位于select语句的结尾

4.5 分页查询

(1)语法:limit 开始的索引,每页查询的条数
(2)公式:开始的索引 = (当前的页码 - 1) * 每页显示的条数

#从第1条开始,查询4条(索引默认从0开始)
SELECT * FROM t_product WHERE STATUS = 1 ORDER BY priority DESC LIMIT 0,4;

#取前10条
select * from table_name limit 10

(3)limit是一个MySQL“方言”

4.6 分组统计

(1)使用group by子句对列进行分组,按照某个字段或者某些字段进行分组

select  column1,column2,column3 ... from 表名 group by column;

(2)使用having是对分组之后的数据进行再次过滤

select column1,column2,column3... 
		from  表名
		group by column having AVG(sal) < 2000;

五.函数

1.分组函数

(1)分组函数还有另一个名字:多行处理函数。
(2)多行处理函数的特点:输入多行,最终输出的结果是1行。
(3)分组函数自动忽略NULL。
(4)分组函数一般都会和group by联合使用,这也是为什么它被称为分组函数的原因。
并且任何一个分组函数都是在group by语句执行结束之后才会执行的。当一条sql语句
没有group by的话,整张表的数据会自成一组。
(5)SQL语句当中有一个语法规则,分组函数不可直接使用在where子句当中(因为group by是在where执行之后才会执行)
(6)当一条语句中有group by的话,select后面只能跟分组函数和参与分组的字段。

1.1 统计函数count

(1)count:返回行的总数

select count(*) | count(列名) from table_name [where 条件]

补充:count(*),count(1)以及count(列名)的区别

执行效果上 :
①count(*)包括了所有的列,相当于行数,在统计结果的时候, 不会忽略列值为NULL
②count(1)忽略所有列,用1代表代码行,在统计结果的时候, 不会忽略列值为NULL
③count(列名)只包括列名那一列,在统计结果的时候,会忽略列值为空(这里的空不是只空字符串或者0,而是表示null)的计数, 即某个字段值为NULL时,不统计。

执行效率上:
①列名为主键,count(列名)会比count(1)快
②列名不为主键,count(1)会比count(列名)快
③如果表多个列并且没有主键,则 count(1)的执行效率优于 count(*)
④如果有主键,则 select count(主键)的执行效率是最优的
⑤如果表只有一个字段,则 select count(*)最优。
扩展:count(主键ID)比count(1)慢
count(主键 ID) 计数中要去除null,而count(1)计的数是所有的行数。如果使用InnoDB存储引擎的话:
①count(主键 ID)会遍历主键索引树,先把每一行的ID值取出来,判断是否为空,不空的行才会+1,最后返回累计值。必然耗时!
②对于count(1),InnoDB引擎会扫描主键索引树,因为不需要判断空值,直接按行累计+1,最后返回累计值。

1.2 合计函数max/min

select max(列名) from 表名 [where 条件]

1.3 sum 求和

select sum(sal) from emp;

1.4 avg 平均值

select avg(sal) from emp;

2.单行处理函数

(1)什么是单行处理函数?
输入一行,输出一行。
(2)ifnull(可能为NULL的数据,会被当做什么处理) : 属于单行处理函数。

select ename,ifnull(comm,0) as comm from emp;

3.字符串相关函数

(1)CHARSET(str)]// 返回字符串字符集(例如utf8)
(2)CONCAT(string1[,…]) // 连接字符串,将多个列拼接成一列
(3)INSTR(string,substring) // 返回substring在string中出现的位置,没有则返回0
(4)将string转换成大/小写
①UCASE(string) // 转换成大写
②LCASE(string) // 转换成小写
(5)从string中取length个字符串
①LEFT(string,length) // 从string中的左边起取length个字符串
②RIGHT(string,length) // 从string中的右边起取length个字符串
(6)LENGTH(string) // 获取string长度(按照字节)
(7)REPLACE(str,search_str,replace_str) // 在str中用replace_str替换search_str
(8)STRCMP(string1,string2) // 逐字符比较两个字符串的大小(大于返回1,等于返回0,小于返回-1)
(9)SUBSTRING(str,position[,length]) // 从str的position开始[从1开始计算],取length个字符串
(10)TRIM(string) // 去除前后端空格
①LTRIM(string) // 去除前端空格
②RTRIM(string) // 去除后端空格

例子:

-- (1)CHARSET(str) 返回字符串字符集(例如utf8)
SELECT CHARSET(ename) FROM emp;
-- (2)CONCAT(string1[,...]) 连接字符串,将多个列拼接成一列
SELECT CONCAT(ename,' 工作是 ',job) FROM emp;
-- (3)INSTR(string,substring) 返回substring在string中出现的位置,没有则返回0
-- DUAL 亚元表(是一个系统表,可以作为测试表使用)
SELECT INSTR('xuexiJava','Java') FROM DUAL;
-- (4.1)UCASE(string) 转换成大写
SELECT UCASE(ename) FROM emp;
-- (4.2)LCASE(string) 转换成小写
SELECT LCASE(ename) FROM emp;
-- (5.1)LEFT(string,length) 从string中的左边起取length个字符串
-- (5.2)RIGHT(string,length) 从string中的右边起取length个字符串
SELECT LEFT(ename,2) FROM emp;
-- (6)LENGTH(string) 获取string长度(按照字节)
SELECT LENGTH(ename) FROM emp;
-- (7)REPLACE(str,search_str,replace_str) 在str中用replace_str替换search_str
-- 将manager替换成 经理
SELECT ename,REPLACE(job,'MANAGER','经理') FROM emp;
-- (8)STRCMP(string1,string2) 逐字符比较两个字符串的大小(大于返回1,等于返回0,小于返回-1)
SELECT STRCMP('你好','好好') FROM DUAL;
-- (9)SUBSTRING(str,position[,length])
SELECT SUBSTRING(ename,1,3) FROM emp;
--(10)trim(string) // 去除前后端空格
SELECT LTRIM(' 我爱学java ') FROM emp;
SELECT RTRIM(' 我爱学JavaScript ') FROM emp;
SELECT TRIM(' 我爱学习 ') FROM emp;

4.时间函数

(1)Mysql时间加减函数为:
①DATE_ADD() 函数向日期添加指定的时间间隔。
②DATE_SUB() 函数向日期减少指定的时间间隔。
(2)语法
DATE_ADD(date,INTERVAL expr type)
DATE_SUB(date,INTERVAL expr type)
①date 参数是合法的日期表达式。
②expr参数是您希望添加的时间间隔。
③type 参数可以是下列值:

在这里插入图片描述

(4)例子

UPDATE storage_location SET silence_time_out = DATE_ADD(silence_time_out,INTERVAL 5 HOUR),alarm_time_out =DATE_ADD(alarm_time_out,INTERVAL 5 HOUR) WHERE region_id = '22163';

六.MySQL约束

约束用于对表中的数据进行限定,从而保证数据的正确性、有效性和完整性。在MySQL中,约束包括:primary key(主键约束),not null(非空约束),unique(唯一约束),foreign key(外键约束)和check约束五种。

1.primary key(主键)约束

1.1 primary key(主键)的基本使用
字段名 字段类型 primary key
1.2 primary key的细节说明
(1)primary key不能重复,且不能为null
(2)一张表最多只能有一个主键,但可以是复合主键

CREATE TABLE t18(
		 id INT,
		`name` VARCHAR ( 32 ), 
		 email VARCHAR ( 32 ),
		 PRIMARY KEY(id,`name`) -- 这里就是复合主键
		);

(3)主键的指定方式有两种
①直接在字段名后指定:字段名 primary key

CREATE TABLE t19(
	 id INT ,
	`name` VARCHAR(32) PRIMARY KEY, -- 直接在字段名后写
	 email VARCHAR(32)
);

②在表定义的最后写: primary key(列名)

CREATE TABLE t20(
	 id INT,
	`name` VARCHAR(32),
	email VARCHAR(32),
	PRIMARY KEY(`name`) -- 在表定义最后写 primary key(列名)

(4)使用desc表名,可以看到primary key的使用情况
(5)在实际开发中,每个表往往都会设计一个主键

2.not null(非空)

如果在列上定义了not null,那么某一列的值不能为null
字段名 字段类型 not null

3.unique(唯一)

(1)当定义了唯一约束后,该列值是不能重复的
字段名 字段类型 unique
(2)使用细节
①如果没有指定not null,则unique字段可以有多个null
②一张表可以有多个unique字段

4.foreign key(外键)

(1)让表与表之间产生关系,从而保证数据的正确性
FOREIGN KEY(本表字段名) REFERENCES 主表名(主键名/unique字段名)

-- 创建主表
CREATE TABLE my_class(
	id INT PRIMARY key, -- 班级编号
	`name` VARCHAR(32) NOT NULL DEFAULT '');
-- 	创建从表
CREATE TABLE my_stu(
	id INT PRIMARY KEY, -- 学生编号
	`name` VARCHAR(32) NOT NULL DEFAULT '',
	class_id INT, -- 学生所在班级的编号
-- 	下面指定外键关系
	FOREIGN KEY (class_id) REFERENCES my_class(id));

在这里插入图片描述

(2)使用细节:
①外键约束要定义在从表上,主表必须具有主键约束或是unique约束。
②表的类型是innodb,这样的表才支持外键
③外键字段的类型要和主表中关联字段的类型一致(长度可以不同)
④外键字段的值,必须要在主表关联的字段中出现过,或者为null(前提是允许为null)
⑤一旦建立了外建约束,主表数据就不能随意删除了

5.check约束

(1)用于强制行数据必须满足的条件,假定在sal列定义了check约束,并要求在sal列值在1000~2000之间,那么不在1000~2000之间就会提示错误。
(2)Oracle和sql server均支持check,MySQL8之后才支持check

CREATE TABLE t23 (
	id INT PRIMARY KEY,
	`name` VARCHAR(32) ,
	sex VARCHAR(6) CHECK (sex IN('man','woman')),
	sal DOUBLE CHECK ( sal > 1000 AND sal < 2000)
);

七.索引

1.索引的原理

(1)没有索引为什么会慢?
因为需要全表扫描
(2)使用索引为什么会快?
形成一个索引的数据结构,比如二叉树
在这里插入图片描述
(3)索引的代价
①磁盘占用
②影响dml语句(update、delete、insert)语句的效率
但是我们的项目中主要为查询select语句,所以可以忽略

2.索引的类型

(1)主键索引,主键自动成为主索引(类型Primary key)
(2)唯一索引(UNIQUE)
(3)普通索引(INDEX)
(4)全文索引(FULLTEXT)[适合于MyISAM]
开发中考虑使用:全文搜索Slor和ElasticSearch(ES)

3.创建索引

-- 创建表
CREATE TABLE t25 (id INT, `name` VARCHAR (32)) ;
-- 3.1 查询表中是否有索引
SHOW INDEXES FROM t25 ;
-- 3.2添加索引
-- (1)添加唯一索引
CREATE UNIQUE INDEX id_index ON t25 (id) ;
-- (2)添加普通索引方式1
CREATE INDEX id_index ON t25 (id) ;
-- (2)添加普通索引方式2
ALTER TABLE t25 ADD INDEX id_index (id);
-- 如何选择
-- 1.如果某列的值,是不会重复的,则优先考虑使用unique索引,否则使用普通索引
-- (3)添加主键索引
CREATE TABLE t26 (id INT, `name` VARCHAR (32)) ;
ALTER TABLE t26 ADD PRIMARY KEY (id) ;

4.删除索引

-- 删除索引
DROP INDEX id_index ON t25;
-- 删除主键索引
ALTER TABLE t26 DROP PRIMARY KEY;
-- 修改索引,先删除,再添加新的索引

5.查询索引

-- 查询索引
-- 方式1
SHOW INDEX FROM t25;
-- 方式2
SHOW INDEXES FROM t25;
-- 方式3
SHOW KEYS FROM t25;
-- 方式4(索引字段key的值为MUL,该方法没有前面的方法查询结果详细)
DESC t25;

6.哪些列上适合使用索引:

(1)较频繁的作为查询条件字段的应该建立索引
(2)唯一性太差的字段不适合单独创建索引,既使频繁作为查询条件
例如性别:select * from emp where sex = ‘男’;
(3)更新非常频繁的字段不适合创建索引
(4)不会出现在where子句中的字段不该创建索引

八.连接查询

1.1 连接查询概述

1.1.1 什么是连接查询?

在实际开发中,大部分的情况下都不是从单表中查询数据,一般都是多张表联合查询取出最终的结果。在实际开发中,一般一个业务都会对应多张表,比如:学生和班级,起码两张表。

1.1.2 连接查询的分类?

(1)根据语法出现的年代来划分的话,包括:
①SQL92(一些老的DBA可能还在使用这种语法。DBA:DataBase Administrator,数据库管理员)
②SQL99(比较新的语法)
(2)根据表的连接方式来划分,包括:
①内连接:
等值连接
非等值连接
自连接
②外连接:
左外连接(左连接)
右外连接(右连接)
③全连接

1.1.3 笛卡尔积现象

(1)笛卡尔积现象:当两张表进行连接查询的时候,没有任何条件进行限制,最终的查询结果条数是两张表记录条数的乘积。
(2)怎么避免笛卡尔积现象?
当然是加条件进行过滤。
(3)思考:避免了笛卡尔积现象,会减少记录的匹配次数吗?
不会,匹配次数还是两张表记录条数的乘积,只不过显示的是有效记录。

1.2 内连接查询

1.2.1 等值连接

下面都已这两张表为例子
在这里插入图片描述
在这里插入图片描述

(1)隐式内连接:使用where条件消除无用数据(SQL92:(太老,不用了))
例子:
– 查询所有员工信息和对应的部门信息

SELECT * FROM emp,dept WHERE emp.`dept_id` = dept.`id`; 

在这里插入图片描述
– 查询员工表的名称、性别,部门表的名称

select emp.`name`,emp.`gender`,dept.`name` from emp,dept where emp.`dept_id` = dept.`id`

在这里插入图片描述
(2)显示内连接(SQL99:(常用的))
语法:select 字段列表 from 表名1 [inner] join 表名2 on 条件
例如:

-- 查询所有员工信息和对应的部门信息
SELECT * FROM emp INNER JOIN dept ON emp.`dept_id` = dept.`id`;
-- 或者
select * from emp join dept on emp.`dept_id` = dept.`id`;

1.2.2 非等值连接

(1)非等值连接最大的特点是:连接条件中的关系是非等量关系。
(2)案例:找出每个员工的工资等级,要求显示员工名、工资、工资等级。
在这里插入图片描述

select 
	e.ename,e.sal,s.grade
from
	emp e
inner join
	salgrade s
on
	e.sal between s.losal and s.hisal;

1.2.3 自连接查询

(1)自连接的特点:
①把同一张表当做两张表使用
②需要给表取别名(表名 表列名)
③列名不明确,可以指定列的别名(列名 as 列的别名)
(2)例子:
在这里插入图片描述

-- 要求:显示公司员工名字和他的上级的名字
select
	 worker.ename as '职员名',
	 boss.ename as '上级名'
from
	 emp worker,
	 emp boss
where
	worker.mgr = boss.empno; 

1.2 外链接查询

1.2.1 什么是外连接,和内连接有什么区别?

(1)内连接:
①假设A和B表进行连接,使用内连接的话,凡是A表和B表能够匹配上的记录就会查询出来,这就是内连接。
②AB两张表没有主副之分,两张表是平等的。
(2)外连接:
①假设A和B表进行连接,使用外连接的话,AB两张表中有一张表是主表,一张表是副表
②主要查询主表中的数据,捎带着查询副表,当副表中的数据没有和主表中的数据匹配上,副表自动模拟出NULL与之匹配。
(3)外连接的分类?
①左外连接(左连接):表示左边的这张表是主表。
②右外连接(右连接):表示右边的这张表是主表。
③左连接有右连接的写法,右连接也会有对应的左连接的写法。

1.2.2 左外连接(左连接)

(以下面stu和exam两张表为例)

在这里插入图片描述

在这里插入图片描述
(1)语法:select 字段列表 from 左表 left [outer] join 右表 on 条件;
(2)查询的是左表所有数据及其交集的部分。
(3)例子:

-- 查询所有人的成绩,如果没有成绩,也要显示该人的姓名和id,成绩显示为空
SELECT stu.`id`,stu.`name`,exam.`grade` FROM stu LEFT JOIN exam ON stu.`id`=exam.`id`;

在这里插入图片描述

1.2.3 右外连接(右连接)

(1)语法:select 字段列表 from 左表 right [outer] join 右表 on 条件;
(2)查询的是右表所有数据及其交集的部分
(3)例子:

-- 显示所有成绩,如果没有名字匹配显示为空
SELECT stu.`id`,stu.`name`,exam.`grade`FROM stu RIGHT JOIN exam ON stu.`id`=exam.`id`;

在这里插入图片描述

1.3 三张表怎么连接查询?

找出每一个员工的部门名称、工资等级、以及上级领导。

select 
	e.ename '员工',d.dname,s.grade,e1.ename '领导'
from
	emp e
join
	dept d
on
	e.deptno = d.deptno
join
	salgrade s
on
	e.sal between s.losal and s.hisal
left join
	emp e1
on
	e.mgr = e1.empno;

9.子查询

9.1 什么是子查询?子查询都可以出现在哪里?

(1) 什么是子查询?
select语句当中嵌套select语句,被嵌套的select语句是子查询。
(2)子查询可以出现在哪里?

select
		..(select).
	from
		..(select).
	where
		..(select).
		

(3)以下例子中使用的表

在这里插入图片描述
在这里插入图片描述

9.2 where子句中使用子查询

(1)案例:找出高于平均薪资的员工信息。
select * from emp where sal > avg(sal); //错误的写法,where后面不能直接使用分组函数
(2)正确写法

select * from emp where sal > (select avg(sal) from emp);

9.3 from后面嵌套子查询

(1)案例:找出每个部门平均薪水的等级。
(2)sql语句
①第一步:找出每个部门平均薪水(按照部门编号分组,求sal的平均值)
②第二步:将以上的查询结果当做临时表t,让t表和salgrade s表连接,条件是:
t.avgsal between s.losal and s.hisal

select 
	t.*,s.grade
from
	(select deptno,avg(sal) as avgsal from emp group by deptno) t
join
	salgrade s
on
	t.avgsal between s.losal and s.hisal;

9.4 在select后面嵌套子查询

(1)案例:找出每个员工所在的部门名称,要求显示员工名和部门名
(2)sql:

select 
	e.ename,(select d.dname from dept d where e.deptno = d.deptno) as dname 
from 
	emp e;

十.union

(1)可以将查询结果集相加
(2)案例:找出工作岗位是SALESMAN和MANAGER的员工?
第一种:select ename,job from emp where job = 'MANAGER' or job = 'SALESMAN';
第二种:select ename,job from emp where job in('MANAGER','SALESMAN');
±-------±---------+
| ename | job |
±-------±---------+
| ALLEN | SALESMAN |
| WARD | SALESMAN |
| JONES | MANAGER |
| MARTIN | SALESMAN |
| BLAKE | MANAGER |
| CLARK | MANAGER |
| TURNER | SALESMAN |
±-------±---------+
第三种:union

select ename,job from emp where job = 'MANAGER'
union
select ename,job from emp where job = 'SALESMAN';

十一.事务

1.什么是事务:
事务用于保证数据的一致性,它由一组相关的dml语句组成,该组的dml语句要么全部成功,要么全部失败。如:转账就要用事务来处理,用以保证数据的一致性。
2.事务和锁
当执行事务操作时(dml语句),MySQL会在表上加锁,防止其他用户改变表的数据。
3.mysql数据库控制台事务的几个重要操作
(1)start transaction – 开始一个事务
(2)savepoint 保存点名 – 设置保存点
(3)rollback to 保存点名 – 回退事务
(4)rollback – 回退全部事务
(5)commit – 提交事务,所有的操作生效,不能回退

4.事务的隔离级别
多个事务之间是隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
在这里插入图片描述
(1)读未提交:允许Transaction1读取Transaction2未提交的修改。
(2)读已提交:要求Transaction1只能读取Transaction2已提交的修改。
(3)可重复读:确保Transaction1可以多次从一个字段中读取到相同的值,即Transaction1执行期间禁止
其它事务对这个字段进行更新。
(4)串行化:确保Transaction1可以多次从一个表中读取到相同的行,在Transaction1执行期间,禁止其它
事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下。
注意:
①Oracle默认为读已提交,MySQL默认为可重复读
②加锁:如果他发现一个事务中有一张表正在操作,没有提交;另一个事务操作时,他会卡在这个地方,他不会操作
5.存在问题
(1)脏读:当一个事务读取到另一个事务尚未提交的改变(update,insert,delete)时,产生脏读
(2)不可重复读:不可重复读是指在事务1内,读取了一个数据,事务1还没有结束时,事务2也访问了这个数据,修改或删除了这个数据,并提交。紧接着,事务1又读取这个数据。由于事务2的修改,那么事务1两次读到的数据可能是不一样的,因此称为是不可重复读。
(事务1想读取开启事务那一刻的数据,结果却读到了修改或删除后的数据)
(3)幻读:幻读是指在事务1内,读取了一个数据,事务1还没有结束时,事务2也访问了这个数据,添加了这个数据,并提交。紧接着,事务1又读取这个数据。由于事务2的添加,那么事务1两次读到的数据可能是不一样的,因此称为是幻读。
(事务1想读取事务开启那一刻的数据,结果却读到了添加后的数据)

6.存储引擎
在这里插入图片描述
(1)InnoDB:
①支持事务
②支持外键
③支持行级锁
(2)MyISAM
①添加速度快
②不支持外键和事务
③支持表级锁
(3)memory
①数据存储在内存中(关闭mysql服务,数据丢失,但表还在)
②执行速度快(没有IO读写)
③默认支持索引(hash表)

在这里插入图片描述

  • 81
    点赞
  • 889
    收藏
    觉得还不错? 一键收藏
  • 30
    评论
OpenStack是一种开源的云计算管理平台,它提供了一整套的云计算基础设施服务,包括计算、网络、存储、身份认证等。在实践中,OpenStack的安装通常包括以下几个主要步骤。 首先,准备环境。在安装OpenStack之前,需要确保所使用的服务器满足一定的硬件要求,并且已经正确安装了操作系统。通常推荐使用Ubuntu Server或CentOS等Linux发行版作为操作系统。 接下来,安装依赖软件。OpenStack运行需要一些其他的软件支持,如MySQL数据库、RabbitMQ消息队列中间件、Keystone身份认证服务等。这些软件可以通过包管理工具进行安装,比如apt-get或yum。 然后,安装OpenStack组件。OpenStack由多个组件组成,包括Nova计算服务、Neutron网络服务、Cinder块存储服务等。一般来说,可以使用apt-get或yum命令来安装这些组件。需要注意的是,不同的组件可能需要不同的配置文件和参数设置。 安装完成后,需要对OpenStack进行配置。配置涉及到的内容很多,包括网络配置、存储配置、身份认证配置等。这些配置可以通过修改相应的配置文件来完成,比如nova.conf、neutron.conf等。 最后,启动和测试OpenStack服务。启动过程中,需要确保各个组件的服务正常运行,并且没有错误信息输出。为了测试OpenStack安装是否成功,可以使用一些命令行工具或者图形界面来创建虚拟机、网络等资源,并进行相应的操作和管理。 总结来说,全网最全OpenStack的安装涉及到环境准备、依赖软件安装、OpenStack组件安装、配置和启动、测试等步骤。在实践中,可以参考OpenStack官方文档、社区论坛或者一些专业的安装指南来帮助完成安装过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值