一、多表查询
查询语法
/*
查询语法:
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'@'%';