今日内容
  • 多表查询
  • 事务
  • DCL用于控制权限和管理用户,DBA完成:SQL中四类DDL  DML  DQL  DCL
一、多表查询
1.多表查询_概述
1.1 查询语法
    select 
            列名列表
    from
            表名列表
    where
            ……
笛卡尔积:
        有两个集合A,B,取这两个集合的所有组成情况
        完成多表查询,需要消除无用的数据
1.2 多表查询的分类
内连接查询、外连接查询、子查询
2. 内连接查询
    • 隐式内连接:使用where条件消除无用的数据
      -- 隐式内连接
      SELECT * FROM emp,dept WHERE emp.`dept_id`=dept.`id`;
      -- 通常会查询某些字段
      -- 查询员工表名称、性别及部门表的名称
      SELECT emp.name,gender,dept.name FROM emp,dept WHERE emp.`dept_id`=dept.`id`;
      -- 为表起别名,公司的实际写法,写到多行分开写
      SELECT
      t1.`name`,t1.`gender`,t2.`name`
      FROM
      emp t1,dept t2
      WHERE
      t1.`dept_id`=t2.`id`;
      -- 更正规的写法
      SELECT
      t1.`name`,-- 员工表名称
      t1.`gender',-- 员工表性别
      t2.`NAME` -- 部门表名称
      FROM
      emp t1,
      dept t2
      WHERE
      t1.`dept_id`=t2.`id`;
    • 显式内连接
      • 语法: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.查询条件是什么
      • 3.查询哪些字段
3.外连接查询
    • 左外连接:
      • 语法:select 字段列表 from 表1 left [outer] join 表2 on 条件;
      • 查询的是左表所有数据及其交集
    • 右外连接
      • 语法:select 字段列表 from 表1 right[outer] join 表2 on 条件;
      • 查询的是右表所有数据及其交集
-- 左外连接
SELECT * FROM dept;
SELECT * FROM emp;
-- 新入职员工,无任何部门,外键可以为空
-- 查询所有员工信息,如果员工有部门,则查询部门的名称,没有部门则不显示部门名称
-- 内连接
SELECT
t1.*,t2.`name`
FROM
emp t1,dept t2
WHERE
t1.`dept_id`=t2.`id`;
-- 白龙马查询不到
-- 利用左外连接显示白龙马
SELECT t1.*,t2.name FROM emp t1 LEFT JOIN dept t2 ON t1.`dept_id`=t2.`id`;
-- 右外连接
SELECT t1.*,t2.name FROM emp t1 RIGHT JOIN dept t2 ON t1.`dept_id`=t2.`id`;
-- 右外连接2ok
SELECT t1.*,t2.name FROM dept t2 RIGHT JOIN emp t1 ON t1.`dept_id`=t2.`id`;
4.子查询
4.1概念:查询中嵌套查询,称嵌套查询为子查询
-- 查询工资最高的员工信息
-- 1.查询最高的工资是多少9000
SELECT MAX(salary) FROM emp;
-- 2.查询员工信息,并且工资等于9000的
SELECT * FROM emp WHERE emp.`salary`=9000;
-- 一条SQL完成此操作
SELECT * FROM emp WHERE emp.`salary`=(SELECT MAX(salary) FROM emp);
4.2 子查询的不同情况
  • 子查询的结果是单行单列的
    • 子查询可以作为条件,使用运算符去判断。运算符:> >= < <= =
    • 查询平均工资
-- 子查询的结果是单行单列的时候
-- 查询员工工资小于平均工资的人 4680
SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);
  • 子查询的结果是多行单列的
    • 查询的结果是多行单列的,可以使用运算符in来判断
-- 子查询,查询的结果是多行单列的,可以使用运算符in来判断
-- 查询财务部和市场部所有员工的信息
SELECT id FROM dept WHERE NAME='财务部' OR NAME='市场部';
SELECT * FROM emp WHERE dept_id=3 OR dept_id=2;
-- 合并为一条SQL
-- 多个字段or,可以简化为in
SELECT * FROM emp WHERE dept_id IN (2,3);
SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME='财务部' OR NAME='市场部');
  • 子查询的结果是多行多列的
    • 查询员工的入职日期为2011-11-11之后的员工信息和部门信息
    • 多行多列的,子查询可以作为一张虚拟表参与表的查询
-- 子查询
-- 查询员工的入职日期为2011-11-11之后的员工信息和部门信息
SELECT * FROM emp WHERE emp.`join_date` > '2011-11-11';
-- 还要查询部门信息,上表和部门信息做关联
SELECT * FROM dept t1, (SELECT * FROM emp WHERE emp.`join_date` > '2011-11-11') t2
WHERE t1.id=t2.id;
-- 普通内连接
SELECT * FROM emp t1,dept t2 WHERE t1.`dept_id`=t2.`id` AND t1.`join_date` > '2011-11-11';
5.多表查询-练习
-- 需求:

-- 1.查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职务描述
/*
分析:
1.员工编号,员工姓名,工资属于emp表,职务名称,职务描述属于job表
2.查询条件:emp.job_id=job.id
*/
SELECT
t1.`id`,-- 员工编号
t1.`ename`,-- 员工姓名
t1.`salary`,-- 员工工资
t2.`description`,-- 职务描述
t2.`jname`-- 职务名称
FROM
emp t1,
job t2
WHERE
t1.`job_id`=t2.`id`;
-- 2.查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置
/*
分析:
1.员工编号,员工姓名,工资 查询自 emp,职务名称,职务描述 查询自 job,部门名称,部门位置 查询自 dept
2.条件:emp.job_id=jpb.id AND emp.dept_id=dept.id
*/
SELECT
t1.`id`,-- 员工编号
t1.`ename`,-- 员工姓名
t1.`salary`,-- 员工工资
t2.`description`,-- 职务描述
t2.`jname`,-- 职务名称
t3.`dname`,-- 部门名称
t3.`loc`-- 部门位置 FROM
emp t1,
job t2,
dept t3
WHERE
t1.`job_id`=t2.`id` AND t1.`dept_id`=t3.`id`;
-- 3.查询员工姓名,工资,工资等级
/*
分析:
1.员工姓名,工资 emp 工资等级 salarygrade
2.条件 emp.salary >= salarygrade.losalary and emp.salary <= salarygrade.hisalary;
或 emp.salary between salarygrade.losalary and salarygrade.hisalary;
*/
SELECT
t1.`ename`,
t1.`salary`,
t2.*
FROM emp t1,salarygrade t2
WHERE t1.`salary` BETWEEN t2.`losalary` AND t2.`hisalary`;
-- 4.查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
/*
分析:
1.员工姓名,工资 emp,职务名称,职务描述 job,部门名称,部门位置 dept,工资等级 salarygrade
条件emp.job_id=jpb.id AND emp.dept_id=dept.id AND emp.salary between salarygrade.losalary and salarygrade.hisalary
*/
SELECT
t1.`ename`,t1.`salary`,t2.`jname`,t2.`description`,t3.`dname`,t3.`loc`,t4.`grade`
FROM
emp t1, job t2, dept t3, salarygrade t4
WHERE
t1.`job_id`=t2.`id`
AND t1.`dept_id`=t3.`id`
AND t1.`salary` BETWEEN t4.`losalary` AND t4.`hisalary`;
-- 5.查询出部门编号、部门名称、部门位置、部门人数【分组查询和子查询】
/*
分析:
1.部门编号、部门名称、部门位置 dept表 部门人数 emp表
2.如何查询部门的人数?使用分组查询,按照emp.dep_id完成分组,查询count(id)
3.使用子查询将第2步的查询结果和dept表进行关联查询
*/
SELECT
t1.`id`,t1.`dname`,t1.`loc`,t2.total
FROM
dept t1,(SELECT dept_id,COUNT(id) total
FROM emp
GROUP BY dept_id) t2
WHERE t1.`id`=t2.dept_id;-- 将其当做虚拟表,和部门表关联
-- 6.查询所有员工的姓名及其直接上级的姓名,没有领导的员工也需要查询
/*
分析:
1.姓名 emp, 直接上级的姓名 emp
emp表的id和mgr 是自关联的【两张表】
2.条件 emp.id=emp.mgr
3.查询左表的所有数据和交集数据
使用左外连接查询
*/
/*
select
t1.`ename`,
t1.`mgr`,
t2.`id`,
t2.`ename`
from emp t1 ,emp t2
where t1.id=t2.`mgr`;
*/
-- 查询罗贯中,唐僧等没有上级的,使用左外连接
SELECT
t1.`ename`,
t2.`mgr`,
t2.`id`,
t2.`ename`
FROM emp t1
LEFT JOIN emp t2
ON t1.`mgr`=t2.`id`
二、事务
1.基本的基本介绍
1.1 概念:
            如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败
      例子:张三给李四转账500元
    • 查询张三账户余额是否大于500
    • 张三账户金额  -500
    • 李四账户金额 +500
  • 不用事务管理,则中途失败
  • 被事务管理,出现异常,则会回滚
  • 事务的操作:开启事务、回滚、提交
    • 开启事务:start transaction
    • 回滚:rollback
    • 提交:commit
-- 创建数据表
CREATE TABLE account (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
balance DOUBLE
);
-- 添加数据
INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000);
-- 0 开启事务
START TRANSACTION;
-- 1张三给李四转账500元
-- 2查询张三账户余额是否大于500
-- 3张三账户-500
UPDATE account SET balance = balance - 500 WHERE NAME='zhangsan';
-- 李四账户+500
-- 出错了
UPDATE account SET balance =balance + 500 WHERE NAME='lisi';
SELECT * FROM account;-- 临时数据的变化,不是持久的变化
-- 发现执行没有问题,提交事务
COMMIT;
-- 发现出问题了,应该 回滚事务
ROLLBACK;-- 回滚,保证账户的安全性
1.2 MySQL数据库中,事务默认提交
  • 事务提交的两种方式
    • 自动提交:
      • MySQL就是自动提交的
      • 一条DML(增删改)语句会自动提交一次事务
    • 手动提交
      • 需要先开启事务,再提交
-- 自动提交
UPDATE account SET balance=1000;
-- 手动提交
COMMIT; -- 不自动提交,事务会默认回滚
    • 修改事务的默认提交方式【MySQL是自动提交的,Oracle是手动提交的,必须写commit才可以生效】
      • 查看事务的默认提交方式 SELECT @@autocommit; --1代表自动提交,0代表手动提交
      • 修改默认提交方式:set @@autocommit=0;

SELECT @@autocommit; -- 1代表自动提交,0代表手动提交
SET @@autocommit=0; -- 必须提交,才能正确
UPDATE account SET balance =30;
COMMIT;
2.事务的四大特征(常见的面试题)
  • 原子性:不可分割的最小操作单位,要么同时成功,要么同时失败
  • 持久性:事务一旦提交/回滚,数据库会持久化的保存数据
  • 隔离性:多个事务之间,相互独立。
  • 一致性:事务操作前后,数据总量不变
3.事务的隔离级别(了解)
3.1 概念
  • 隔离性:多个事务之间是隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别,就可以解决这些问题。
  • 存在的问题:
    • 脏读:一个事务,读取到另一个事务中没有提交的数据
    • 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样

    • 幻读:一个事务操作(DML)数据表中所有的记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。
  • 隔离级别【一般只有特殊需求才需要修改,了解即可】
    • read uncommitted:读未提交
      • 会产生的问题:脏读、不可重复读、幻读
    • read committed:读已提交(只有提交了数据,另一个事务才能读到)(Oracle默认)
      • 会产生的问题 :不可重复读、幻读
    • repeatable read:可重复读(MySQL默认)
      • 会产生的问题:幻读
    • serializable:串行化(hang)【锁表,效率低】
      • 可以解决所有的问题
    • 注意:隔离级别从小大大,安全性越来越高,但是效率越来越低
    • 数据库如何设置隔离级别
      • 查询隔离级别 select @@tx_isolation;
      • 设置隔离级别 set global transaction isolation level 级别字符串;
SELECT @@tx_isolation; -- mysql默认可重复读
-- Oracle默认读已提交
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
3.2 演示
设置窗口的隔离级别为:读未提交 
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
start transaction;
-- 转账操作,更新张三 和 李四 
update account set balance =balance -500 where  id=1;
update account set balance =balance +500 where  id=2;
3.3 事务的隔离级别--可重复读和串行化
三、DCL
1.概述
SQL分类:
  • DDL:增删改数据库和表
  • DML:增删改表中的数据
  • DQL:查询表中的数据
  • DCL:管理用户,授权
DBA:数据库管理员
2.对用户的管理操作
  • DCL:管理用户,授权
    • 管理用户
      • 添加用户:CREATE USER '用户名@主机名' identify 密码;
-- 1.切换到MySQL数据库
USE mysql;
-- 2.查询user表
SELECT * FROM USER;
-- 两个root分别表示本地数据库和远程数据库 -- 创建用户
CREATE USER '用户名@主机名' IDENTIFIED BY 密码;
CREATE USER 'zhangsan'@'localhost' IDENTIFIED BY '123';
SELECT * FROM USER;
-- 任意电脑都可访问 CREATE USER 'lisi'@'%' IDENTIFIED BY '123';
      • 删除用户
CREATE USER 'lisi'@'%' IDENTIFIED BY '123';

-- 删除用户
DROP USER '用户名'@'主机名';
DROP USER 'zhangsan'@'localhost';
      • 修改用户密码
-- 修改lisi用户密码为abc
UPDATE USER SET PASSWORD=PASSWORD('新密码') WHERE USER='用户名';
SELECT * FROM USER; UPDATE USER SET PASSWORD=PASSWORD('123') WHERE USER='lisi'; -- DCL中的简化书写形式【DCL特有的方式】
SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('密码');
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('root');

  • 忘记密码的解决方案
    • 停止MySQL的服务(需要管理员运行该cmd):net stop mysql
    • 使用无验证方式启动mysql服务:mysqld --skip-grant-tables
    • 在另一个cmd里面直接输入mysql
    • 改mysql密码:update user set password=password('root') where user='root'
    • 进程管理器结束mysqld的进程
    • cmd启动mysql服务:net start mysql
    • 重新登录
      • 查询用户
-- 1.切换到MySQL数据库
USE mysql;
-- 2.查询user表
SELECT * FROM USER;
-- 两个root分别表示本地数据库和远程数据库
百分号表示通配符,可以在任意 计算机上登录
    • 授权
3.权限管理
  • 查询权限
-- 查询权限
SHOW GRANTS FOR '用户名'@'主机名';
SHOW GRANTS FOR 'lisi'@'%';-- usage 只能查询
SHOW GRANTS FOR 'root'@'%';-- root有各种权限
  • 授予权限

-- 授予权限
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';
GRANT SELECT, DELETE , UPDATE ON db3.account TO 'lisi'@'%'; -- 给张三用户授予所有权限,在任意数据库的任意表上
-- 通配符all表示所有权限
-- 通配符 *.*表示所有数据库的所有表
GRANT ALL ON *.* TO 'zhangsan'@'localhost';
  • 撤销权限
-- 撤销权限
REVOKE 权限列表 ON 数据库.表名 FROM '用户名'@'主机名';
REVOKE UPDATE ON db3.`account` FROM 'lisi'@'%';

JavaEE Day04 MySQL多表&事务的更多相关文章

  1. day04 mysql单表查询 多表查询 pymysql的使用

    day04 mysql pymysql   一.单表查询     1.having过滤         一般用作二次筛选             也可以用作一次筛选(残缺的: 只能筛选select里面 ...

  2. MySQL多表查询、事务、DCL:内含mysql如果忘记密码解决方案

    MySQL多表查询.事务.DCL 多表查询 * 查询语法: select 列名列表 from 表名列表 where.... * 准备sql # 创建部门表 CREATE TABLE dept( id ...

  3. MySql多表查询_事务_DCL(资料三)

    今日内容 1. 多表查询 2. 事务 3. DCL 多表查询: * 查询语法: select 列名列表 from 表名列表 where.... * 准备sql # 创建部门表 CREATE TABLE ...

  4. MYSQL删除表的记录后如何使ID从1开始

    MYSQL删除表的记录后如何使ID从1开始 MYSQL删除表的记录后如何使ID从1开始 http://hi.baidu.com/289766516/blog/item/a3f85500556e2c09 ...

  5. MySQL建表规范与常见问题

    一. 表设计 库名.表名.字段名必须使用小写字母,“_”分割. 库名.表名.字段名必须不超过12个字符. 库名.表名.字段名见名知意,建议使用名词而不是动词. 建议使用InnoDB存储引擎. 存储精确 ...

  6. Mysql分表和分区的区别、分库分表介绍与区别

    分表和分区的区别: 一,什么是mysql分表,分区 什么是分表,从表面意思上看呢,就是把一张表分成N多个小表,具体请看:mysql分表的3种方法 什么是分区,分区呢就是把一张表的数据分成N多个区块,这 ...

  7. MySQL数据库的事务管理

    当前在开发ERP系统,使用到的数据库为Mysql.下面介绍下如何开启事务,以及事务隔离的机制 : 1. 检查当前数据库使用的存储引擎. show engines; 2. 修改前my.ini中的文件如下 ...

  8. MySQL存储过程之事务管理

    原文链接:http://hideto.iteye.com/blog/195275 MySQL存储过程之事务管理 ACID:Atomic.Consistent.Isolated.Durable 存储程序 ...

  9. 详解MySQL大表优化方案( 转)

    当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 单表优化 除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑.部署.运维的各种复杂度,一般以整型 ...

  10. MySQL 大表优化方案探讨

    当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 单表优化 除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑.部署.运维的各种复杂度,一般以整型 ...

随机推荐

  1. 【疑难杂症】关于pycharm无法安装插件显示网络错误问题

    今天实在受不了英文的pycharm了,想着赶紧装个中文的插件,结果插件界面给我说我网络有问题 search results are not loaded check the internet conn ...

  2. 使用Receiver接收告警信息

    告警接收器可以通过以下形式进行配置: receivers: - <receiver> ... 每一个receiver具有一个全局唯一的名称,并且对应一个或者多个通知方式: name: &l ...

  3. Spring笔记三

    Spring-03 1. AOP 1.1 概念 ​ AOP为Aspect Oriented Programming的缩写,意为:面向切面编程.他是一种可以在不修改原来的核心代码的情况下给程序动态统一进 ...

  4. Codeforces Round #708 (Div. 2)

    A题被hack,A题很简单,其实题目没看懂,直接看样例做的. B题题意是以为懂了,但是样例一直看不懂. 经验:要两两相加能被一个m整除数组sum最少,利用他们的余数就可以设为a[x], x是余数,如果 ...

  5. 聊聊Linux中CPU上下文切换

    目录 什么是CPU上下文 CPU上下文切换 上一任务的CPU上下文保存在哪? 进程上下文切换 内核空间和用户空间 top命令查看CPU资源 系统调用 进程上下文切换 和 系统调用的区别? 进程切换的常 ...

  6. MatrixOne Linux 编译文档

    MatrixOne Linux 编译文档 编译环境 硬件环境 操作系统 内存 CPU 磁盘 Windows环境下的Linux虚拟机 Linux version 3.10.0-1160.el7.x86_ ...

  7. windows下利用_popen,_wpoen创建管道进行系统命令输出数据

    转载: https://blog.csdn.net/greless/article/details/72383762 参考: http://www.linuxidc.com/Linux/2011-04 ...

  8. CQOI2015任务查询系统

    题目链接 主席树. 把区间的影响挂在左端点与右端点,建树时顺便对应的插入与删除. 维护一段值域区间的和与数字个数,查询时要注意与第k大的数相同的数可能有很多. 复杂度O(nlogn) #include ...

  9. 第一阶段:linux运维基础·1

    1. 服务器的主要硬件是?以及其作用是? cpu 相当于人体的大脑,负责计算机的运算和控制 内存 解决cpu与硬盘之间速度不匹配的问题 磁盘 永久存放数据的存储器 主板 直接或间接的将所有的设备连接在 ...

  10. day02-HTML02

    4.HTML 4.3HTML基本标签 4.3.9表格(table)标签 基本语法: <table border="边框宽度" cellspacing="空隙大小&q ...