欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

**MySql多表与事务 篇3/共3篇 [史上最全重点,web基础day04] *

程序员文章站 2022-05-30 18:23:45
...

多表查询:

1. 注意:
	1. 起别名之后是不能用原名的,所以起别名的时候执行sql语句注意句中是否含有原名。
	2. 如果是左外连接,左边的表的数据都会被查询出来。
	3. 每一张的虚拟表都必须有一个别名

2. 事务:
	如果一个包含多个步骤的业务被同时操作,这些业务要么同时完成要么同时失败。
	
	执行增删改的时候会涉及到事务,其实mysql默认提交事务,所以一句代码如果执行失败,则该行代码不会产生任何影响,回滚。
	
	如果开启事务了,不会默认提交事务了,当执行多个事务中的操作,如果有任意一个步骤出问题,应该回滚当执行多个事务中的操作,如果都没有出问题,则再提交事务。
	
	开启事务实际上就是将自动提交变成手动提交事务。
	
3. 事务的四大特征[面试容易考]:
	1.原子性:是不可分割的最小操作单位,一个事务要么同时成功,要么同时失败(不会成功一半,失败一半,即不可再分割);
	2.持久性:当事务提交或回滚后,数据库库会持久化的保存数据。
	3.隔离性:多个事务之间,相互独立。
	4.一致性:事务操作后,数据总量不变。(能量守恒)


4. SQL分类:
	DDL:操作数据库和表
	DML:增删改表中的数据
	DQL:查询表中数据
	DCL:管理用户,授权

5. DBA:数据库管理员
	1. 管理用户
	2. 授权
	DCL:管理用户,授权

MYSQL的多表查询:

1.如何清除笛卡尔积现象的影响:
	* 我们发现不是所有的数据组合都是有用的,只有员工表.dept_id=部门表.id 的数据才是有用的。所以需要条件过滤掉没用的数据。

2. 内连接:
	* 用左边表的记录去匹配右边表的记录,如果符合条件的显示。如:从表.外键=主表.主键

3. 隐式内连接:看不到join关键字,条件使用where指定
	* select 字段名 from 左表,右表 where 条件
4. 显式内连接:使用inner join ...on 可以省略inner

5. 左外连接:使用left outer join ...on,outer 可以省略
	* 可以用左边表的记录去匹配右边表的记录,如果符合条件则显示:否则,显示null;
	* 可以理解为:在内连接的基础上保证左表的数据全部显示(左表是部门,右表是员工);

6. 右外连接:使用right outer join...on,outer 可以省略
	* select 字段名 from 左表 right [outer]join 右表on 条件
	* 用右边的记录去匹配左表的记录,符合条件的则显示:否则,显示null;

7. 子查询的概念:
	1.一个查询的结果做为另一个查询的条件
	2.有查询的嵌套,内部的查询称为子查询
	3.子查询要使用括号。

8. 子查询的结果是一个值的时候:
	1. 子查询的结果只要是单行单列,肯定在where 后面作为条件,父查询使用:比较运算符,如:> ,<,<>(不等于),=等;
		select 查询字段 from 表 where 字段=(子查询);
	
	2. 子查询的结果是单例多行,结果集类似于一个数组,父查询使用in运算符。
		select 查询字段 from 表 where 字段 in (字查询);
	
	3. 子查询的结果只要是多列,肯定在from后面做表
		select 查询字段 from (子查询) 表别名 where 条件;
		* 子查询作为表需要取别名,否则这张表没有名称则无法访问表中的字段。
	
	4. 总结:
		子查询结果只要是单列,则在where后面作为条件
		子查询结果只要是多列,则在from后面作为表进行二次查询。

事务的操作

1. 事务:
	* 事务的应用场景说明:事务执行是一个整体,所有的SQL语句都必须执行成功。如果其中有1条SQL语句出现异常,则所有的SQL语句都要回滚,整个业务执行失败。

2. 手动提交事务使用过程:
	1.执行成功的情况: 开启事务——》执行多条SQL语句——》成功提交事务。
	2.执行失败的情况:开启事务——》执行多条SQL语句——》事物的额回滚。

3. SQL语句:
	* 开启事务:start transaction;
	* 提交事务:commit;
	* 回滚事务: rollback;

	* 总结:如果事务中有SQL语句没有问题,commit提交事务,会对数据库数据的数据进行改变。如果事务中SQL语句有问题,rollback回滚事务,会回退到开启事务时的状态。

4. 自动提交事务:
	* MYSQL默认每一条DML(增删改)语句都是一个单独的事务,每条语句都会自动开启一个事务,语句执行完毕自动提交事务,MYSQL默认开始自动提交事务。

5. 事务原理:
	* 事务开启之后,所有的操作都会临时保存到事务日志中,事务日志只有在得到commit命令才会同步到数据表中,其他任何情况都回清空事务日志(rollback,断开连接)


6. 事务的步骤:
	1.客户端连接数据库服务器,创建连接时创建此用户临时日志文件
	2.开启事务以后,所有的操作都会先写入到临时日志文件中
	3.所有的查询操作从表中查询,但会经过日志文件加工后才返回
	4.如果事务提交则将日志文件中的数据写到表中,否则清空日志文件。

7. 回滚点:
	1. 设置回滚点:savepoint  名字
	2. 回到回滚点:rollback to 名字

	3. 具体操作:
		1.将数据还原到1000
		2.开启事务
		3.让张三账号减3次钱,每次10块
		4.设置回滚点:savepoint three_times;
		5.让张三账号减4次钱,每次10块。
		6.回到回滚点:rollback to three_times;

	4. 总结:设置回滚点可以让我们在失败的时候回到回滚点,而不是回到事务开启的时候。

8. 事务的隔离级别:
	1. 原子性:每个事务都是一个整体,不可再拆分,事务中所有的SQL语句要么都执行成功,要么都失败。
	2. 一致性:事务在执行前数据库的状态与执行后数据库的状态保持一致。
	3. 隔离性:事务与事务之间不应该相互影响,执行时也是保持隔离的状态。
	4. 持久性:一旦事务执行成功,对数据库的修改是持久的,就算关机也是保存下来的。


9. 事务的隔离级别:事务在操作时的理想状态:所有的事务之间保持距离,互不影响。因为并发操作,多个用户同时访问同一个数据。可能引发并发访问问题。
	1. 脏读:一个事务读取到了另一个事务中尚未提交的数据。
	2. 不可重复读[虚读]:一个事务中两次读取的数据内容不一致,要求的是一个事务中多次读取时数据是一致的,这是事务update 时引发的问题
	3. 幻读:一个事务中两次读取的数据的数量不一致,要求在一个事务多次读取的数据的数量是一致的,这是insert或delete时引发的问题。

10. MYSQL数据库有四种隔离级别:
	读已提交:read uncommited 各种问题都会出现
	读已提交:read commited 消灭掉了脏读问题
	可重复读:repeatable read 消灭掉了脏读和可重复读问题
	串行化:serializable	消灭掉了所有问题

11. 设置隔离级别:
	1. 查询隔离级别:select @@tx_isolation;
	2. 设置隔离级别:set global transaction isolation level 级别字符集;
	3. 设置事务隔离级别,需要退出MYSQL再重新登录才能看到隔离级别的变化。
	4. 结论:使用serializable 隔离级别,一个事务没有执行完,其他事务的SQL执行不了,可以挡住幻读。

权限管理

1. DCL:我们现在使用的都是root 用户,超级管理员拥有全部的权限,但是一个公司里面的数据库服务器上面可能同时运行着很多个项目的数据库,所以我们应该可以根据不同的项目建立不同的用户,分配不同的权限来管理和维护数据库。
	* 创建用户:
		语法:create user '用户名'@'主机名' identified by '密码';
2. 关键字说明:
	'用户名':将创建的用户名
	'主机名':指定该用户在哪个主机上可以登陆,如果是本地用户可用localhose ,如果想让用户可以从任意远程主机登陆,可以使用通配符%
	'密码':该用户的登陆密码,密码可以为空,如果为空则该用户可以不需要密码登陆服务器。
	
3. 给用户授权:
	grant 权限1,权限2...on 数据库.表名 to '用户名'@'主机名';
	
	grant...on...to 授权关键字

4. 数据库名.表名:该用户可以操作哪个数据库的哪些表,如果要授予该用户对所有数据库和表的相应擦欧总权限,则可用*表示,如*.*
	'用户名'@'主机名':给哪个用户授权,注:有两对单引号。	
	grant create,alter,insert,update,select on test.* to 'user1'@'localhost';

5. REVOKE…ON…FROM 撤销授权的关键字
	权限  用户的权限,如 CREATE、ALTER、SELECT、INSERT、UPDATE 等,所有的权
	限则使用 ALL
	数据库名. 表名  对哪些数据库的哪些表,如果要取消该用户对所有数据库和表的操作权限则可用*表
	示,如*.*
	' 用户名'@' 主机名'  给哪个用户撤销
	
	修改密码:
	set password for ' 用户名'@' 主机名' = password('