关于MySQL,这些基础知识你知道吗?

我是一个从汽车行业转行IT的项目经理,我是Edward,如想了解更多,请关注我的公众号【转行项目经理的逆袭之路】。MySql这块的知识,语句就像是pseudocode,虽然简单容易理解,但是较为零散,今天就来回顾总结一下。

数据库

之前通过IO技术对数据进行增删改查 相当于自己写了一个简单版的数据库软件,只不过功能简陋效率低下,将来工作中任何一个项目都需要数据库软件,如果每个项目都自己写一遍数据库软件,开发效率极低,在互联网行业中只要是使用频繁并且繁琐的工作肯定会有一个通用的解决方案.
学习数据库就是学习如何和数据库软件进行交流,SQL语言就是用于程序员和数据库软件进行交流的语言.

DBMS:

DataBaseManagementSystem 数据库管理系统(数据库软件),包括:MySQL/Oracle/SQLServer,DB2,SQLite等

常见DBMS介绍:

MySQL:开源 Oracle公司产品,08年MySQL被Sun公司收购,09年Sun公司被Oracle, 原MySQL创始人离开Oracle创建新的数据库MariaDB 市场占有率第一
Oracle:闭源 Oracle公司产品, 性能最高价格最贵的数据库. 市占率第二
SQLServer:闭源 微软公司产品,应用在微软的整套解决方案中 市占率第三
DB2:闭源 IBM公司产品,应用在IBM整套解决方案中.
SQLite:轻量级数据库,只提供基础的增删改成操作.安装包几十k,主要应用在移动设备和嵌入式设备中.
网站的整套解决方案包括: 开发语言 操作系统 web服务器软件 数据库软件

开源和闭源

开源:开发源代码 免费, 盈利方式:通过卖服务 , 会有程序员无偿的提供升级和维护
闭源:不开放源代码 盈利方式:通过卖产品+卖服务, 会有技术大拿攻击,但是没关系闭源产品的公司会养着一群人负责维护和升级.
SQL语言
Structured Query Language:结构化查询语言, 用于程序员和数据库软件(DBMS)进行交流
如何连接数据库软件: 检查mysql服务开启 window键+r 输入services.msc
开始菜单中找到Mysql/MariaDB文件夹 里面的 Mysql Client 打开后直接输入密码
如果是linux或mac系统 先打开终端 在终端中输入 mysql -u用户名 -p回车 回车后输入密码 回车
断开连接: 关闭窗口 或执行 exit;

Access denied for user 'root'@'localhost' (using password: YES)   密码错误

SQL语句的分类:

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

数据库相关SQL语句

往数据库软件中保存数据,需要先建库再建表,最后再操作表里面的数据
查询所有数据库
格式: show databases;
创建数据库
格式: create database 数据库名; 使用默认字符集创建数据 create database db1;
指定字符集格式: create database 数据库名 character set utf8/gbk;
create database db2 character set utf8; create database db3 character set gbk;
查看数据库详情
格式: show create database 数据库名; show create database db1;
删除数据库
格式: drop database 数据库名; drop database db4;
使用数据库
对表和数据进行操作时必须先使用了数据库才可以 不然会报错
格式: use 数据库名; use db1;
数据库相关练习:
分别创建mydb1和mydb2 第一个字符集utf8 第二个gbk create database mydb1 character set utf8; create database mydb2 character set gbk;
查询所有数据库检查是否创建成功 show databases;
分别查询两个数据库的字符集是否成功 show create database mydb1; show create database mydb2;
先使用mydb1 再使用mydb2 use mydb1; use mydb2;
删除两个数据库 drop database mydb1; drop database mydb2;

表相关的SQL

操作表时一定保证已经使用了某个数据库 不然会报以下错: ERROR 1046 (3D000): No database selected
创建表
格式: create table 表名(字段名 字段类型,字段名 字段类型); create table student(name varchar(10),age int);
指定字符集格式: create table 表名(字段名 类型,字段名 类型) charset=utf8/gbk; create table person(name varchar(10),gender varchar(5))charset=gbk;
查询所有表
格式: show tables;
查询表详情
格式: show create table 表名; show create table person;
查看表字段
格式: desc 表名; desc student;
删除表
格式: drop table 表名: drop table student;
修改表名
格式: rename table 原名 to 新名; rename table person to t_person;
添加表字段
最后添加格式: alter table 表名 add 字段名 类型;
最前面添加:alter table 表名 add 字段名 类型 first;
在某个字段后面添加 alter table 表名 add 字段名 类型 after xxx; alter table tperson add salary int; alter table tperson add id int first; alter table t_person add age int after name;
删除表字段
格式: alter table 表名 drop 字段名; alter table t_person drop salary;
修改表字段
格式: alter table 表名 change 原名 新名 新类型; alter table t_person change age salary int;

表相关SQL语句回顾

创建 create table t1(name varchar(10),age int)charset=utf8;
查询所有 show tables;
查询表详情 show create table t1;
查询表字段 desc t1
删除表 drop table t1;
修改表名 rename table t1 to t2;
添加表字段 alter table t1 add salary int first/ after xxx;
删除表字段 alter table t1 drop salary;
修改表字段 alter table t1 change 原名 新名 新类型;

表相关练习题:

创建数据库mydb1 字符集utf8 并使用该数据库 create database mydb1 character set utf8; use mydb1;
在mydb1中创建员工表emp 字段有name 表字符集也是utf8 create table emp(name varchar(10)) charset=utf8;
添加表字段age在最后 alter table emp add age int;
添加id字段在最前面 alter table emp add id int first;
添加性别gender在name后面 alter table emp add gender varchar(5) after name;
修改gender为工资sal
alter table emp change gender sal int;
删除age字段
alter table emp drop age;
修改表名为temp
rename table emp to temp;
删除temp表
drop table temp;
删除数据库
drop database mydb1;

在这里插入图片描述

数据相关SQL

执行数据相关的SQL 必须保证已经使用了某个数据库,并且存在数据所对应的表格 create database mydb2 character set utf8; use mydb2; create table person(name varchar(10),age int)charset=utf8;

插入数据

全表插入格式(要求值的数量和顺序必须和表字段一致): insert into 表名 values(值1,值2,值3); insert into person values(‘Tom’,18);
指定字段插入格式(要求值的数量和顺序必须和指定的一致): insert into 表名(字段名1,字段名2)values(值1,值2); insert into person(name)values(‘Jerry’);
批量插入数据格式: 在values后面写多组值即可f insert into person values(‘Lucy’,20),(‘Lily’,21); insert into person(name)values(‘zhangsan’),(‘lisi’);
插入中文: insert into person values(‘刘德华’,30); 如果执行以上代码出现错误提示,提示里面包含16进制的错误信息 执行以下SQL set names gbk;

查询数据

格式: select 字段信息 from 表名 where 条件;
举例: 查询person表中所有的名字
select name from person;
查询person表中年龄大于20的名字和年龄
select name,age from person where age>20; 查询person表中所有数据的所有字段信息
select * from person;

修改数据

格式: update 表名 set 字段名=xxx,字段名=xxx where 条件;
举例: update person set age=8 where name=‘Tom’; update person set age=10 where age is null;

删除数据

格式: delete from 表名 where 条件;
举例:
删除Tom delete from person where name=‘Tom’;
删除年龄小于20岁的 delete from person where age<20;
删除所有数据 delete from person;
在这里插入图片描述

增删改查回顾:

插入数据 insert into 表名 values(值1,值2);
查询数据 select 字段信息 from 表名 where 条件;
修改数据 update 表名 set 字段名=xxx where 条件;
删除数据 delete from 表名 where 条件;

数据类型

整数类型: int(m)和bigint(m) bigint等效java中的long, m代表显示长度 需要结合zerofill关键字使用 create table t1(name varchar(10),age int(10) zerofill); insert into t1 values(‘Tom’,18); select * from t1;
浮点数: double(m,d) m代表总长度 d代表小数长度 58.234 m=5 d=3 ,超高精度的浮点数decimal(m,d)只有涉及超高精度运算时使用.
字符串:
char(m): 固定长度 m=10 存"abc" 占10,执行效率略高 最大255
varchar(m):可变长度 m=10 存"abc" 占3,更节省存储空间, 最大65535 超过255建议使用text
text(m):可变长度,最大值65535.
日期:
date: 只能保存年月日
time: 只能保存时分秒
datetime:保存年月日时分秒,默认值是null,最大值9999-12-31
timestamp:时间戳(距离1970年毫秒数),保存年月日时分秒,默认值当前系统时间,最大值2038-1-19
举例: create table tdate(t1 date,t2 time,t3 datetime,t4 timestamp); insert into tdate values(‘2020-1-18’,null,null,null); insert into t_date values(null,‘17:35:18’,‘2020-3-17 12:30:23’,null);

主键约束 primary key

主键: 表示数据唯一性的字段称为主键
约束: 约束是创建表时给表字段添加的限制条件
主键约束: 限制主键的值唯一且非空
测试: create table t1(id int primary key,name varchar(10)); insert into t1 values(1,‘aaa’); insert into t1 values(1,‘bbb’); //报错 主键值不能重复 Duplicate entry ‘1’ for key ‘PRIMARY’ insert into t1 values(null,‘ccc’);//报错 主键值不能为null Column ‘id’ cannot be null
主键+自增 auto_increment
自增规则:从历史最大值+1
测试: create table t2(id int primary key auto_increment,name varchar(10)); insert into t2 values(null,‘aaa’); 1 insert into t2 values(null,‘bbb’); 2 insert into t2 values(10,‘ccc’); 10 insert into t2 values(null,‘ddd’); 11 delete from t2 where id>=10; insert into t2 values(null,‘eee’); 12

导入*.sql文件

把下载的emp.sql 放到d盘根目录
source d:/emp.sql;
如果导入后 执行select * from emp 发现有乱码 执行 set names gbk;

去重distinct

查询员工表中有哪些不同的工作 select distinct job from emp;
is null 和 is not null

判断某个字段的值为null时不能使用

查询没有上级领导的员工信息 select * from emp where mgr is null;
查询有上级领导的员工姓名和上级领导编号 select ename,mgr from emp where mgr is not null;

比较运算符 > < >= <= = !=和<>

查询员工工资小于等于3000的员工姓名和工资 select ename,sal from emp where sal<=3000;
查询工作不是程序员的员工姓名和工作(两种写法) select ename,job from emp where job!=‘程序员’; select ename,job from emp where job<>‘程序员’;

and 和 or

如果查询数据时使用了多个条件,多个条件同时满足使用and, 多个条件满足一个就可以使用or
and类似java中的&& , or类似java中的||
查询1号部门工资大于1500的员工信息 select * from emp where deptno=1 and sal>1500;
查询工作是人事或者工资大于3000的员工姓名,工作和工资. select ename,job,sal from emp where job=‘人事’ or sal>3000;

in(x,y,z)

当查询某个字段的值为多个的时候使用in关键字
查询工资为1500,3000,5000的员工信息 select * from emp where sal=1500 or sal=3000 or sal=5000; select * from emp where sal in(1500,3000,5000);
between x and y
查询工资在1000到2000之间的员工信息(包括1000和2000) select * from emp where sal>=1000 and sal<=2000; select * from emp where sal between 1000 and 2000;
查询工资在1000到2000以外的员工信息 select * from emp where sal not between 1000 and 2000;
查询工资不等于5000,3000,800的员工信息 select * from emp where sal not in(800,3000,5000);

综合练习

查询有上级领导并且是3号部门的员工信息 select * from emp where mgr is not null and deptno=3;
查询2号部门工资在1000到2000之间的员工姓名 工资和部门编号 select ename,sal,deptno from emp where deptno=2 and sal between 1000 and 2000;
查询1号部门工资为800和1600的员工信息 select * from emp where deptno=1 and sal in(800,1600);
查询1号和2号部门工资高于2000的员工信息 select * from emp where deptno in(1,2) and sal>2000;
查询员工表中出现的部门编号有哪几个 select distinct deptno from emp;

模糊查询like

:代表1个未知字符
%:代表0或多个未知字符
举例:
以x开头 x%
以x结尾 %x
包含x %x%
第二个字符是x x%
倒数第三个是x %x

以x开头 倒数第二个是y x%y_
查询员工表中姓孙的员工姓名 select ename from emp where ename like ‘孙%’;
查询名字以精结尾的员工信息 select * from emp where ename like ‘%精’;
查询工作中包含销售的员工姓名和工作 select ename,job from emp where job like ‘%销售%’;

排序 order by

格式: order by 字段 asc(默认升序)/desc降序 写在SQL语句的后面
查询工资高于2000的员工信息,按照工资升序排序 select * from emp where sal>2000 order by sal;
查询每个员工的姓名,工资和部门编号,按照部门编号降序排序 select ename,sal,deptno from emp order by deptno desc;
多字段排序,在order by后面写多个字段 通过逗号分隔
查询每个员工的姓名,工资和部门编号,按照部门编号降序排序,如果部门编号一致则按照工资降序排序 select ename,sal,deptno from emp order by deptno desc,sal desc;
查询1号和2号部门的员工信息按照部门编号升序排序,如果部门编号一致则按照工资降序排序 select * from emp where deptno in(1,2) order by deptno, sal desc;

分页查询

格式: limit 跳过的条数,请求条数(也代表每页条数) , 写在SQL语句的最后
请求员工表中按照工资降序排序前3条数据(请求第一页的3条数据) select * from emp order by sal desc limit 0,3;
查询员工表中工资降序排序的第4 5 6条数据 select * from emp order by sal desc limit 3,3;
查询员工表中第三页的2条数据(请求第5和第6条数据) select * from emp limit 4,2;
查询工资最低的员工信息 select * from emp order by sal limit 0,1;
查询员工表中工资升序第四页的2条数据 select * from emp order by sal limit 6,2;
综合练习题
查询员工表中名字里第二个字是八的员工姓名和工资 select ename,sal from emp where ename like ‘_八%’;
查询工作中包含售字的员工姓名和工作 select ename,job from emp where job like ‘%售%’;
查询工资高于1000块钱的员工姓名和工资,按照工资降序排序,查询第二页的3条数据 select ename,sal from emp where sal>1000 order by sal desc limit 3,3;

数值计算+ - * /

查询每个员工的姓名,工资和年终奖(3个月的工资) select ename,sal,sal*3 from emp;

别名,可以对查询的字段起别名

select ename as ‘名字’,sal as ‘工资’,sal3 as ‘年终奖’ from emp; select ename ‘名字’,sal ‘工资’,sal3 ‘年终奖’ from emp; select ename 名字,sal 工资,sal*3 年终奖 from emp;
查询每个员工姓名,工资和涨薪5块钱之后的工资 select ename,sal,sal+5 涨薪后 from emp;

聚合函数

聚合函数是对查询的多条数据进行统计查询,包括:求平均值,最大值,最小值,求和,计数
平均值avg
查询1号部门的平均工资 select avg(sal) from emp where deptno=1;
查询程序员的平均工资 select avg(sal) from emp where job=‘程序员’;
最大值max
查询3号部门的最高工资 select max(sal) from emp where deptno=3;
最小值min
查询销售的最低工资 select min(sal) from emp where job=‘销售’;
求和sum
查询2号部门的工资总和 select sum(sal) from emp where deptno=2;
计数count
查询工资高于2000的员工人数 select count() from emp where sal>2000;
查询2号部门的人数 select count(
) from emp where deptno=2;

练习题

查询员工表中工资高于2000的员工姓名和工资,按照工资升序排序,查询第二页的2条数据 select ename,sal from emp where sal>2000 order by sal limit 2,2;
查询和销售相关的工作的工资总和 select sum(sal) from emp where job like ‘%销售%’; 6625
查询程序员人数
select count(*) from emp where job=‘程序员’; 2
查询1号部门中有领导的员工中的最高工资 select max(sal) from emp where deptno=1 and mgr is not null;
查询2号部门的最高工资和最低工资 起别名 select max(sal) 最高工资,min(sal) 最低工资 from emp where deptno=2;
查询1号部门里面名字中包含空字的员工姓名
select ename from emp where deptno=1 and ename like ‘%空%’;

分组查询

题目需求中每个xx 就以xx作为分组的字段
查询员工表的平均工资 select avg(sal) from emp;
查询1号部门的平均工资 select avg(sal) from emp where deptno=1;

查询每个部门的平均工资 select deptno,avg(sal) from emp group by deptno;

查询每个工作的最高工资 select job,max(sal) from emp group by job;
查询每个部门的人数 select deptno,count() from emp group by deptno;
查询每种工作的工资总和 select job,sum(sal) from emp group by job;
查询每个部门工资高于1000块钱的员工人数 select deptno,count(
) from emp where sal>1000 group by deptno;
查询1号和2号部门的最高工资 select deptno,max(sal) from emp where deptno in(1,2) group by deptno;
查询1号和2号部门中每种工作的工资总和 select job,sum(sal) from emp where deptno in(1,2) group by job;

having

where后面只能写普通字段条件,聚合函数不能写在where后面
having后面专门写聚合函数的条件,而且是和分组查询结合使用

各个关键字的顺序:

select …from 表名 where 普通字段条件 group by 分组字段名 having 聚合函数条件 order by 排序字段名 limit …;

查询每个部门的平均工资,只查询平均工资高于2000的信息 select deptno,avg(sal) from emp group by deptno having avg(sal)>2000;

查询每种工作的人数,只查询人数为1的信息 select job,count() from emp group by job having count()=1;
查询每个部门的平均工资,只查询工资在1000到3000之间的,并且过滤掉平均工资低于2000的信息. select deptno,avg(sal) from emp where sal between 1000 and 3000 group by deptno having avg(sal)>=2000;

在这里插入图片描述

MySQL 事务

MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!

在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。
事务用来管理 insert,update,delete 语句
一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。

持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

事务控制语句:

BEGIN 或 START TRANSACTION 显式地开启一个事务;

COMMIT 也可以使用 COMMIT WORK,不过二者是等价的。COMMIT 会提交事务,并使已对数据库进行的所有修改成为永久性的;

ROLLBACK 也可以使用 ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;

SAVEPOINT identifier,SAVEPOINT 允许在事务中创建一个保存点,一个事务中可以有多个 SAVEPOINT;

RELEASE SAVEPOINT identifier 删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;

ROLLBACK TO identifier 把事务回滚到标记点;

SET TRANSACTION 用来设置事务的隔离级别。InnoDB 存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE。

事务测试

mysql> use RUNOOB;
Database changed
mysql> CREATE TABLE runoob_transaction_test( id int(5)) engine=innodb;  # 创建数据表
Query OK, 0 rows affected (0.04 sec)
 
mysql> select * from runoob_transaction_test;
Empty set (0.01 sec)
 
mysql> begin;  # 开始事务
Query OK, 0 rows affected (0.00 sec)
 
mysql> insert into runoob_transaction_test value(5);
Query OK, 1 rows affected (0.01 sec)
 
mysql> insert into runoob_transaction_test value(6);
Query OK, 1 rows affected (0.00 sec)
 
mysql> commit; # 提交事务
Query OK, 0 rows affected (0.01 sec)
 
mysql>  select * from runoob_transaction_test;
+------+
| id   |
+------+
| 5    |
| 6    |
+------+
2 rows in set (0.01 sec)
 
mysql> begin;    # 开始事务
Query OK, 0 rows affected (0.00 sec)
 
mysql>  insert into runoob_transaction_test values(7);
Query OK, 1 rows affected (0.00 sec)
 
mysql> rollback;   # 回滚
Query OK, 0 rows affected (0.00 sec)
 
mysql>   select * from runoob_transaction_test;   # 因为回滚所以数据没有插入
+------+
| id   |
+------+
| 5    |
| 6    |
+------+
2 rows in set (0.01 sec)
 
mysql>

DCL

一、grant 普通数据用户,查询、插入、更新、删除 数据库中所有表数据的权利。

grant select on testdb.* to common_user@’%’
grant insert on testdb.* to common_user@’%’
grant update on testdb.* to common_user@’%’
grant delete on testdb.* to common_user@’%’
或者,用一条 MySQL 命令来替代:

grant select, insert, update, delete on testdb.* to common_user@’%’

二、grant 数据库开发人员,创建表、索引、视图、存储过程、函数。。。等权限。

grant 创建、修改、删除 MySQL 数据表结构权限。

grant create on testdb.* to developer@‘192.168.0.%’;
grant alter on testdb.* to developer@‘192.168.0.%’;
grant drop on testdb.* to developer@‘192.168.0.%’;
grant 操作 MySQL 外键权限。

grant references on testdb.* to developer@‘192.168.0.%’;
grant 操作 MySQL 临时表权限。

grant create temporary tables on testdb.* to developer@‘192.168.0.%’;
grant 操作 MySQL 索引权限。

grant index on testdb.* to developer@‘192.168.0.%’;
grant 操作 MySQL 视图、查看视图源代码 权限。

grant create view on testdb.* to developer@‘192.168.0.%’;
grant show view on testdb.* to developer@‘192.168.0.%’;
grant 操作 MySQL 存储过程、函数 权限。

grant create routine on testdb.* to developer@‘192.168.0.%’; – now, can show procedure status
grant alter routine on testdb.* to developer@‘192.168.0.%’; – now, you can drop a procedure
grant execute on testdb.* to developer@‘192.168.0.%’;

三、grant 普通 DBA 管理某个 MySQL 数据库的权限

grant all privileges on testdb to dba@‘localhost’
其中,关键字 privileges 可以省略。

四、grant 高级 DBA 管理 MySQL 中所有数据库的权限。

grant all on . to dba@‘localhost’

五、MySQL grant 权限,分别可以作用在多个层次上。

  1. grant 作用在整个 MySQL 服务器上:

grant select on . to dba@localhost; – dba 可以查询 MySQL 中所有数据库中的表。
grant all on . to dba@localhost; – dba 可以管理 MySQL 中的所有数据库
2. grant 作用在单个数据库上:

grant select on testdb.* to dba@localhost; – dba 可以查询 testdb 中的表。
3. grant 作用在单个数据表上:

grant select, insert, update, delete on testdb.orders to dba@localhost;
这里在给一个用户授权多张表时,可以多次执行以上语句。例如:

grant select(user_id,username) on smp.users to mo_user@’%’ identified by ‘123345’;
grant select on smp.mo_sms to mo_user@’%’ identified by ‘123345’;
4. grant 作用在表中的列上:

grant select(id, se, rank) on testdb.apache_log to dba@localhost;
5. grant 作用在存储过程、函数上:

grant execute on procedure testdb.pr_add to ‘dba’@‘localhost’
grant execute on function testdb.fn_add to ‘dba’@‘localhost’

六、查看 MySQL 用户权限

查看当前用户(自己)权限:

show grants;
查看其他 MySQL 用户权限:

show grants for dba@localhost;

七、撤销已经赋予给 MySQL 用户权限的权限。

revoke 跟 grant 的语法差不多,只需要把关键字 to 换成 from 即可:

grant all on . to dba@localhost;
revoke all on . from dba@localhost;

八、MySQL grant、revoke 用户权限注意事项

  1. grant, revoke 用户权限后,该用户只有重新连接 MySQL 数据库,权限才能生效。

  2. 如果想让授权的用户,也可以将这些权限 grant 给其他用户,需要选项 grant option
    grant select on testdb.* to dba@localhost with grant option;
    这个特性一般用不到。实际中,数据库权限最好由 DBA 来统一管理。

注意:创建完成后需要执行 FLUSH PRIVILEGES 语句。

高级SQL

子查询(嵌套查询)

查询工资高于1号部门平均工资的员工信息 select avg(sal) from emp where deptno=1; select * from emp where sal>2325;
把上面两条合并成一条 select * from emp where sal>(select avg(sal) from emp where deptno=1);
查询拿最高工资的员工信息 select * from emp where sal=(select max(sal) from emp);
查询工资高于2号部门最低工资的员工信息 select * from emp where sal>(select min(sal) from emp where deptno=2);
查询和孙悟空相同工作的其他员工信息 select * from emp where job=(select job from emp where ename=‘孙悟空’) and ename!=‘孙悟空’;
查询拿最低工资员工的同事们的信息(同事指同一部门的员工) select min(sal) from emp; select deptno from emp where sal=(select min(sal) from emp);

select * from emp where deptno=(select deptno from emp where sal=(select min(sal) from emp)) and sal!=(select min(sal) from emp);

查询白骨精的部门信息(需要用到dept部门表) select deptno from emp where ename=‘白骨精’; select * from dept where deptno=(select deptno from emp where ename=‘白骨精’);
查询所有员工的部门信息(部门只有1,2,3但是部门表里面有1,2,3,4 只根据员工表中出现的部门编号去查询部门信息)
先查询员工表中出现的部门编号 select distinct deptno from emp;
通过查询到的部门编号查询部门信息 select * from dept where deptno in(select distinct deptno from emp);

关联关系

创建表时,表与表之间存在的业务关系称为关联关系
外键: 用于建立关系的字段称为外键
有哪些关系:
一对一:有AB两张表,A表中1条数据对应B表中的1条数据,同时B表中1条数据也对应A表中的一条数据.称为一对一关系
应用场景: 将原属于一张表的数据拆分成两张表进行数据保存时,使用1对1的关系.
如何建立一对一的关系? (将一张表拆成两张表(主表和从表)) 在从表中添加外键指向主表的主键
在这里插入图片描述
一对多:有AB两张表,A表中1条数据对应B表中的多条数据,同时B表中1条数据对应A表中的一条数据.称为一对多关系
应用场景: 比如员工表和部门表的关系
如何建立关系? 一对多关系中存在两张表,一个表是1(部门表),一个表是多(员工表),在多的表中添加外键指向另外一张表的主键
在这里插入图片描述
多对多:有AB两张表,A表中1条数据对应B表中的多条数据,同时B表中1条数据也对应A表中的多条数据.称为多对多关系
应用场景: 比如老师表和学生表
如何建立关系? 需要通过一个中间关系表建立关系,在关系表中添加两个外键分别指向两个主表的主键
在这里插入图片描述

关联查询

关联查询是查询存在关联关系多张表的查询方式
三种关联查询的方式: 1. 等值连接 2.内连接 3.外连接
关联查询必须写关联关系,如果不写会得到两个表结果的乘积,这个乘积称为笛卡尔积,笛卡尔积是一个错误的查询结果,由于工作中数据量巨大笛卡尔积有可能会导致内存溢出.
等值连接
格式: select 字段信息 from A,B where 关联关系 and 其它条件
举例:
查询工资高于2000的员工的姓名,工资和对应的部门名 select e.ename,e.sal,d.dname from emp e,dept d where e.deptno=d.deptno and e.sal>2000;
查询不是程序员的员工姓名,工作和部门所在地 select e.ename,e.job,d.loc from emp e,dept d where e.deptno=d.deptno and e.job!=‘程序员’;
内连接
格式: select 字段信息 from A join B on 关联关系 where 其它条件
举例:
查询工资高于2000的员工的姓名,工资和对应的部门名 select e.ename,e.sal,d.dname from emp e join dept d on e.deptno=d.deptno where e.sal>2000;
查询不是程序员的员工姓名,工作和部门所在地 select e.ename,e.job,d.loc from emp e join dept d on e.deptno=d.deptno where e.job!=‘程序员’;
等值连接和内连接查询到的都是两张表的交集数据,但是内连接代码结构更直观推荐使用
外连接
外连接查询的是一张表的全部和另外一张表的交集数据
格式: select 字段信息 from A left/right join B on 关联关系 where 其它条件
举例:

查询所有部门名和对应的员工姓名 select d.dname,e.ename from emp e join dept d on e.deptno=d.deptno;
查询所有员工的姓名和部门所在地
由于员工表里面全部是交集数据所以先插入一条数据 insert into emp(empno,ename) values(20,‘灭霸’);
select e.ename,d.dname from emp e left join dept d on e.deptno=d.deptno;

原创文章 46 获赞 7 访问量 2065

猜你喜欢

转载自blog.csdn.net/EdwardWH/article/details/105873812