四、MYSQL多表和事物

一、多表查询

查询语法

 /*
 查询语法:
	select
		列名列表
	from
		表名列表
	where.... 
 */
 -- 准备数据
 # 创建部门表
	CREATE TABLE dept(
		id INT PRIMARY KEY AUTO_INCREMENT,
		NAME VARCHAR(20)
	);
	INSERT INTO dept (NAME) VALUES ('开发部'),('市场部'),('财务部');
	# 创建员工表
	CREATE TABLE emp (
		id INT PRIMARY KEY AUTO_INCREMENT,
		NAME VARCHAR(10),
		gender CHAR(1), -- 性别
		salary DOUBLE, -- 工资
		join_date DATE, -- 入职日期
		dept_id INT,
		FOREIGN KEY (dept_id) REFERENCES dept(id) -- 外键,关联部门表(部门表的主键)
	);
	INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('孙悟空','男',7200,'2013-02-24',1);
	INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('猪八戒','男',3600,'2010-12-02',2);
	INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('唐僧','男',9000,'2008-08-08',2);
	INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('白骨精','女',5000,'2015-10-07',3);
	INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女',4500,'2011-03-14',1);
  • 笛卡尔积:
    • 有两个集合A,B .取这两个集合的所有组成情况。
    • 要完成多表查询,需要消除无用的数据
  • 多表查询的分类:
    1、内联查询
    • 隐式内连接:使用where条件消除无用数据
-- 1、隐式内连接
select * from emp,dept where emp.dept_id = dept.id;
-- 2、查询员工表的名称,性别,部门表的名称
select emp.name,emp.gender,dept.name from emp,dept where emp.dept_id = dept.id;
-- 3、简化查询,并且格式化
SELECT
	e.NAME,
	e.gender,
	d.NAME 
FROM
	emp e,
	dept d 
WHERE
e.dept_id = d.id;
  • 显式内连接:
-- 语法:select 字段 from  表名1 inner join 表名2 where 
SELECT
	e.NAME,
	e.gender,
	d.NAME 
FROM
	emp e
	INNER JOIN dept d ON e.dept_id = d.id;
	* 内连接查询问题:
			1、从哪些表中查询数据
			2、条件是什么
			3、查询哪些字段 

2、外联查询
* 左外连接

/*
语法:select 字段 from  表名1 left [outer] join 表名2  on 条件;
*/
-- 查询所有员工信息,如果员工有部门,则查询部门,如果没有部门,则不显式部门名称
-- 左外连接查询的是左表所有数据及其交集部分
SELECT
	e.*,
	d.`NAME` 
FROM
	emp e
	LEFT JOIN dept d ON e.dept_id = d.id;
	* 右外连接
/*
语法:select 字段 from  表名1 right [outer] join 表名2  on 条件;
*/
-- 查询所有员工信息,如果员工有部门,则查询部门,如果没有部门,则不显式部门名称
-- 右外连接查询的是右表所有数据及其交集部分
SELECT
	e.*,
	d.`NAME` 
FROM
	emp e
	LEFT JOIN dept d ON e.dept_id = d.id;

3、子查询

  • 查询中嵌套查询,称嵌套查询为子查询
  • 基础演示
-- 查询工资最高的员工信息
-- 1、查询工资最高为9000
select MAX(salary) from emp;
--- 2、查询员工信息,薪资等于9000
select * from emp where salary=9000;

-- 嵌套查询,一个语句搞定
SELECT
	*
FROM
	emp e
WHERE
	salary = ( SELECT MAX( salary ) FROM emp s );
  • 子查询的不同情况
    1、子查询的结果是单行单列的:
    * 子查询可以作为条件,使用运算符去判断。运算符 :>、 >=、 <、 <=、 =、 !=
--- 查询员工工资小于平均工资的人
SELECT
	* 
FROM
	emp e 
WHERE
	e.salary < ( SELECT AVG( salary ) FROM emp );

2、子查询的结果是多行单列的;

  • 子查询可以作为条件,使用in运算符来判断
-- 查询财务部所有员工信息
SELECT
	* 
FROM
	emp 
WHERE
	id IN (
SELECT
	id 
FROM
	dept 
WHERE
	NAME IN ( '财务部', '市场部' ) 
	);

3、子查询的结果是多行多列的。

  • 子查询可以作为一张虚拟表,参与查询
-- 查询员工的入职日期是2011-11-11之后的员工信息和部门信息
SELECT 
	a.*,
	d.`name`
FROM 
	(SELECT 
	* 
FROM
	emp e
WHERE
	e.join_date> '2011-11-11') a,
	dept d
WHERE 
	a.dept_id=d.id;

-- 普通内连接查询
SELECT 
	e.* ,
	d.`name`
FROM
	emp e,
	dept d
WHERE
	e.join_date> '2011-11-11' AND
	d.id=e.dept_id;

二、事务

事务的基本特征

1、概念:
	* 如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。
2、操作:
	* 开启事务: start transaction;
	* 回滚: rollback;
	* 提交: commit;
3、mysql 数据库中事务默认自动提交
	* 事务提交的两种方式:
		*自动提交
			* mysql就是自动提交的
			* 一条DML(增删改)语句会自动提交一次事务。
		* 手动提交
			* ORACLE 数据库默认是手动提交
			* 需要先开启事务,再提交。 
	 * 修改事务的提交方式:
	 	* 查看事务的默认提交方式 	
	 			SELECT @@autocommit; -- 1代表自动提交,0代表手动提交
	 	* 修改事务的默认提交方式
	 			SET @@autocommit=0; -- 修改为手动提交
CREATE TABLE account (
			id INT PRIMARY KEY AUTO_INCREMENT,
			NAME VARCHAR(10),
			balance DOUBLE
		);
-- 添加数据
INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000);
		SELECT * FROM account;
UPDATE account SET balance = 1000;
-- 张三给李四转账 500 元

-- 0. 开启事务
START TRANSACTION;
-- 1. 张三账户 -500

UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';
-- 2. 李四账户 +500
-- 出错了...
UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';

-- 发现执行没有问题,提交事务
COMMIT;

-- 发现出问题了,回滚事务
ROLLBACK;

事务的四大特征

1、原子性:是不可分割的最小操作单位,要么同时成功,同时失败
2、持久性: 当事务提交或回滚后,数据库会持久化的保存数据
3、隔离性; 多个事务之间,相互独立。
4、一致性:事务操作前后,数据总量不变。

事务的隔离级别

* 概念: 多个事务之间是隔离的,相互独立的。但是多个事务操作同一批数据,则会引发一些问题,设置不同级别的隔离就可以解决这些问题。
* 存在问题:
	1、脏读: 一个事务,读渠道另一个事务中没有提交的数据
	2、不可重复读: 在同一个事务中,两次读取到的数据不一样
	3、幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。
* 隔离级别:
	1、read uncommitted :读未提交
		* 产生的问题: 脏读、不可重复读、幻读
	2、read committed :读已提交(oracle 默认)
		* 产生的问题:不可重复读、幻读
	3、repeatable read:可重复度(mysql默认)
		* 产生的问题: 幻读
	4、serializable:串行化
		* 可解决所有问题  
		
	注意:隔离级别从小到达,安全性越来越高,效率越来越低
	* 数据库查询隔离级别:
		* select @@tx_isolation;
	* 数据库设置隔离级别:
		* set global transaction isolation level  级别字符串;

三、DCL(权限控制和管理用户)

  • SQL 分类:

      1、 DDL:操作数据库和表
      2、DML:增删改表中的数据
      3、DQL:查询表中的数据
      4、DCL:管理用户,授权
    
  • DBA:数据库管理员

  • DCL :管理用户,授权

      1、管理用户
      	* 添加用户
      		* 语法 :CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
      	* 删除用户
      		* 语法:  DROP USER '用户名'@'主机名';
      	* 修改用户密码
      		* 忘记root用户密码 
      				1. cmd -- > net stop mysql 停止mysql服务
      				* 需要管理员运行该cmd
      				2. 使用无验证方式启动mysql服务: mysqld --skip-grant-tables
      				3. 打开新的cmd窗口,直接输入mysql命令,敲回车。就可以登录成功
      				4. use mysql;
      				5. update user set password = password('你的新密码') where user = 'root';
      				6. 关闭两个窗口
      				7. 打开任务管理器,手动结束mysqld.exe 的进程
      				8. 启动mysql服务
      				9. 使用新密码登录。 
      	* 查询用户
      		* 语法: select * FROM user;
      		* 通配符: %表示可以在任意 	
    
-- 1、切换到mysql数据库
use mysql;
-- 2、查询user表
select * FROM user;
-- 创建用户
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';

-- 删除用户
DROP USER '用户名'@'主机名';

-- 修改用户密码,两种方式
UPDATE user SET password=PASSWORD('新密码') WHERE `User`= '用户名'; 
SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码');

2、权限管理

	1、查询权限
	2、授予权限
	3、撤销权限
-- 1、查询权限
SHOW GRANTS FOR '用户名'@'主机名';

-- 2、 授予权限
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';
-- 单个权限,权限列表
GRANT SELECT ON 数据库名.表名 TO 'beta'@'%';
-- 多个权限,权限列表
GRANT SELECT,DELETE ON 数据库名.表名 TO 'beta'@'%';
-- 给用户授予所有权限,在任意库表上
GRANT ALL ON *.* TO 'beta'@'%';
-- 3、 撤销权限
REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';

REVOKE SELECT,DELETE ON 数据库名.表名 FROM 'beta'@'%';
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值