子查询,多列查询,合并查询,内外连接,索引,事务管理,用户管理

1. 子查询
	a. 单行子查询: 子查询当中只返回了单列,单行的数据
	b. 多行子查询: 子查询当中返回了单列多行的数据, 两个表的结果如果不在where后面加上约束条件会形成 "笛卡尔积";
	c. 多列子查询: 子查询当中返回多列数据
		使用方式: 只需要在where语句后面使用"(a列,b列) = (子查询语句)"将多个列的名称括起来
	
	查询和SMITH的部门和岗位完全相同的所有雇员
		1. 先查询部门和岗位
			Select deptno, job from where ename=”SMITH”;
				+--------+-------+
				| deptno | job   |
				+--------+-------+
				|     20 | CLERK |
				+--------+-------+  拿到部门和岗位
		2. 再去查询emp中部门号是20的, job是CLERK, 姓名不是SMITH的人
			select ename, deptno, job from emp where deptno=20 and job='CLERK' and ename!="SMITH";
				+-------+--------+-------+
				| ename | deptno | job   |
				+-------+--------+-------+
				| ADAMS |     20 | CLERK |
				+-------+--------+-------+
		多列子查询: 
			select ename, deptno, job from emp where (deptno, job)=(select deptno, job from emp where ename='SMITH');  现在并没有说明检索出来的人中不包含SMITH本人
+-------+--------+-------+
| ename | deptno | job   |
+-------+--------+-------+
| SMITH |     20 | CLERK |
| ADAMS |     20 | CLERK |
+-------+--------+-------+
			 select ename, deptno, job from emp where (deptno, job)=(select deptno, job from emp where ename='SMITH') and ename<> 'SMITH';
+-------+--------+-------+
| ename | deptno | job   |
+-------+--------+-------+
| ADAMS |     20 | CLERK |
+-------+--------+-------+


在from语句中使用子查询:
	select x1, x2, x3 from [表的名称] [select...](select当做是一个临时表)

	问题: 显示属于自己部门平均工资的员工的姓名, 部门, 工资, 平均工资
		1. 平均工资
			select ename, deptno, sal, avg(sal) from emp;
				拿到所有每一个人的姓名, 部门编号, 工资, 部门的平均工资
			select avg(sal),deptno from emp group by deptno;
+-------------+--------+
| avg(sal)    | deptno |
+-------------+--------+
| 2916.666667 |     10 |
| 2175.000000 |     20 |
| 1566.666667 |     30 |
+-------------+--------+
		2. emp表进行分组, 分成不同的部门
			select ename, deptno, sal, avg(sal) from emp, 拿到所有每一个人的姓名, 部门编号, 工资, 部门的平均工资
		
		加上判断条件

			(select deptno, avg(sal) from emp group by deptno);拿到部门编号, 部门平均工资
		比较个人的工资和部门的平均工资
	
		3. 不同的部门
			select ename, deptno, sal, avg_sal from emp, (select avg(sal) avg_sal, deptno dt from emp group by deptno) tmp where tmp.dt=emp.deptno and emp.sal > tmp.avg_sal;
+-------+--------+---------+-------------+
| ename | deptno | sal     | avg_sal     |
+-------+--------+---------+-------------+
| ALLEN |     30 | 1600.00 | 1566.666667 |
| JONES |     20 | 2975.00 | 2175.000000 |
| BLAKE |     30 | 2850.00 | 1566.666667 |
| SCOTT |     20 | 3000.00 | 2175.000000 |
| KING  |     10 | 5000.00 | 2916.666667 |
| FORD  |     20 | 3000.00 | 2175.000000 |
+-------+--------+---------+-------------+

合并查询: 	
	union: 作用是将两个查询的结果集进行合并, 会自动去除结果当中重复的行,
	union all: 作用是将两个查询的结果集进行查询, 不会自动去除结果集当中重复的行

	将工资大于2500或职位是MANAGER的人找出来
		select ename, sal, job from emp where sal > 2500 or job >=2500 union;
select ename, sal, job from emp where sal > 2500;
+-------+---------+-----------+
| ename | sal     | job       |
+-------+---------+-----------+
| JONES | 2975.00 | MANAGER   |
| BLAKE | 2850.00 | MANAGER   |
| SCOTT | 3000.00 | ANALYST   |
| KING  | 5000.00 | PRESIDENT |
| FORD  | 3000.00 | ANALYST   |
+-------+---------+-----------+
select ename, sal, job from emp where job='MANAGER';
+-------+---------+---------+
| ename | sal     | job     |
+-------+---------+---------+
| JONES | 2975.00 | MANAGER |
| BLAKE | 2850.00 | MANAGER |
| CLARK | 2450.00 | MANAGER |
+-------+---------+---------+

		select ename, sal, job from emp where sal > 2500 union select ename, sal, job from emp where job='MANAGER';
+-------+---------+-----------+
| ename | sal     | job       |
+-------+---------+-----------+
| JONES | 2975.00 | MANAGER   |
| BLAKE | 2850.00 | MANAGER   |
| SCOTT | 3000.00 | ANALYST   |
| KING  | 5000.00 | PRESIDENT |
| FORD  | 3000.00 | ANALYST   |
| CLARK | 2450.00 | MANAGER   |
+-------+---------+-----------+进行去重
		select ename, sal, job from emp where sal > 2500 union all select ename, sal, job from emp where job='MANAGER';
+-------+---------+-----------+
| ename | sal     | job       |
+-------+---------+-----------+
| JONES | 2975.00 | MANAGER   |
| BLAKE | 2850.00 | MANAGER   |
| SCOTT | 3000.00 | ANALYST   |
| KING  | 5000.00 | PRESIDENT |
| FORD  | 3000.00 | ANALYST   |
| JONES | 2975.00 | MANAGER   |
| BLAKE | 2850.00 | MANAGER   |
| CLARK | 2450.00 | MANAGER   |
+-------+---------+-----------+相当于将结果1和结果2拼接起来



内外连接:
	-- 用前面的写法 
		select ename, dname from EMP, DEPT where EMP.deptno=DEPT.deptno and ename='SMITH'; 
	-- 用标准的内连接写法 
		select ename, dname from EMP inner join DEPT on EMP.deptno=DEPT.deptno and ename='SMITH';(将,变成了inner join, where变成了on)


外连接: 
	连接是指要在多个表当去查询,
左外连接: 左侧的表完全显示
	from 表1 left join 表2 on 约束条件
		select * from stu left join exam on stu.id=exam.id;
+------+------+------+-------+
| id   | name | id   | grade |
+------+------+------+-------+
|    1 | jack |    1 |    56 |
|    2 | tom  |    2 |    76 |
|    3 | kity | NULL |  NULL |
|    4 | nono | NULL |  NULL |
+------+------+------+-------+

右外连接: 右侧的表完全显示 
	from 表1 right join 表2 on 约束条件
		select * from stu right join exam on stu.id=exam.id;
+------+------+------+-------+
| id   | name | id   | grade |
+------+------+------+-------+
|    1 | jack |    1 |    56 |
|    2 | tom  |    2 |    76 |
| NULL | NULL |   11 |     8 |
+------+------+------+-------+
		select * from exam left join stu on stu.id=exam.id;
+------+-------+------+------+
| id   | grade | id   | name |
+------+-------+------+------+
|    1 |    56 |    1 | jack |
|    2 |    76 |    2 | tom  |
|   11 |     8 | NULL | NULL |
+------+-------+------+------+

	只需要关心sql语句当中的select查询的位置   根据SQL语句select1, select2的位置来决定左右
	

索引:
	1. 常见的索引
		主键索引(primary key): 在一个表当中设置了主键, 则就会创建一个主键索引
		唯一索引(unique key): 在一个表当中设置了唯一键, 则就会创建一个唯一索引
		普遍索引: 
		全文索引
	2. 建立了一个二叉树的结构, 将设置成为索引的字段的内容, 通过二叉树维护起来;
	

主键索引:
	主键的特性: 不能重复, 不能为NULL		
	按照主键的值, 构建一课二叉树, 准确说是b+树;
	
如果一张表当中创建了索引,也就是会创建二叉树结构, 对增删查改的效率是否有影响???
增: 会有影响, 因为需要更新二叉树
删: 会有影响, 因为需要更新二叉树
改: 会有影响, 因为需要更新二叉树

查: 查询的时候如果用到索引字段的值, 作为查询条件, 效率会大大地增加 (前面三个性能的损失微不足道, 最重要的是查)
	
查看索引: show keys from [类名称]

	show keys from t1\G;

2个索引(1个是主键, 一个是普通)
*************************** 1. row ***************************
        Table: t1   
   Non_unique: 0                               唯一索引 : 0表示唯一索引, 1表示不是唯一索引
     Key_name: PRIMARY                         主键索引
 Seq_in_index: 1 
  Column_name: id                              主键索引在id列
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
*************************** 2. row *************************** 
        Table: t1
   Non_unique: 1                               普通索引
     Key_name: qq                               
 Seq_in_index: 1
  Column_name: qq                             
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment: 
Index_comment: 

	desc t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | NO   | PRI | NULL    |       |  
| name  | varchar(20) | YES  |     | NULL    |       |
| qq    | int(11)     | YES  | MUL | NULL    |       |
+-------+-------------+------+-----+---------+-------+
Key为PRI则是主键索引
Key为MUL则是普通索引

全文索引:
	前提: 存储引擎需要是MyISAM
	innodb存储引擎支持事务(线程安全), 而MyISAM不支持! 所以不用全文索引

删除索引:
	1. alter table [表名称] drop primary key;
	2. alter table [表名称] drop index [索引名称];   ---> key_name

事务管理:
	1. 相当于多线程当中的线程互斥
	2. 保证多个客户端访问数据库的同一张表的时候, 不会产生数据二义性的问题
	3. 事务的基本操作
		3.1 开始事务 start transaction;

		3.2 创建一个保存点 savepoint xx;
		3.3 回滚 rollback to xx;
		3.4 提交事务 commit; 
进行一个操作前, 可以先创建一个保存点, 如果误操作,可以返回到保存点(操作之前的状态)
提交事务之后, 再rollback, 就会出现错误, 不能再返回了


注意: 
	1. 当提交事务完成之后,就不能再回到之前保存的的保存点了, 因为已经提交了事务
	2. innodb是支持事务, MyISAM不支持事务

事务的隔离级别:
	1. 无隔离级别
		脏读: 读到的数据并不是真实的(无效)的数据
		不可重复读/检索: 前后两次读到的结果是不一致的, 
		幻读: 前后读到的数据条目数都是不一致的, 在同一个事务中第一次读到了x条, 第二次读到了x+n条

查看隔离级别:
	select @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+

更改隔离级别:
	set session transaction islation level[事务的隔离级别];
	

视图:
	1. 视图就是一个虚拟的表, 虚拟表当中的数据来源于真实存在的表, 
	2. 视图可以当做是一个表来进行操作;
	3. 修改视图当中的内容也会同步修改真实表当中的数据, 同理, 修改真实表当中
的数据也会更新视图当中的内容

	如何创建一个视图:
		create view [视图的名称] as select语句;
+--------+--------+-----------+------+---------------------+---------+---------+--------+
| empno  | ename  | job       | mgr  | hiredate            | sal     | comm    | deptno |
+--------+--------+-----------+------+---------------------+---------+---------+--------+
| 007369 | SMITH  | CLERK     | 7902 | 1980-12-17 00:00:00 |  800.00 |    NULL |     20 |
| 007499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 00:00:00 | 1600.00 |  300.00 |     30 |
| 007521 | WARD   | SALESMAN  | 7698 | 1981-02-22 00:00:00 | 1250.00 |  500.00 |     30 |
| 007566 | JONES  | MANAGER   | 7839 | 1981-04-02 00:00:00 | 2975.00 |    NULL |     20 |
| 007654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 00:00:00 | 1250.00 | 1400.00 |     30 |
| 007698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 |    NULL |     30 |
| 007782 | CLARK  | MANAGER   | 7839 | 1981-06-09 00:00:00 | 2450.00 |    NULL |     10 |
| 007788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 00:00:00 | 3000.00 |    NULL |     20 |
| 007839 | KING   | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 |    NULL |     10 |
| 007844 | TURNER | SALESMAN  | 7698 | 1981-09-08 00:00:00 | 1500.00 |    0.00 |     30 |
| 007876 | ADAMS  | CLERK     | 7788 | 1987-05-23 00:00:00 | 1100.00 |    NULL |     20 |
| 007900 | JAMES  | CLERK     | 7698 | 1981-12-03 00:00:00 |  950.00 |    NULL |     30 |
| 007902 | FORD   | ANALYST   | 7566 | 1981-12-03 00:00:00 | 3000.00 |    NULL |     20 |
| 007934 | MILLER | CLERK     | 7782 | 1982-01-23 00:00:00 | 1300.00 |    NULL |     10 |
+--------+--------+-----------+------+---------------------+---------+---------+--------+

	create view emp_view as select empno, ename, job from emp;

	select * from emp_view;
+--------+--------+-----------+
| empno  | ename  | job       |
+--------+--------+-----------+
| 007369 | SMITH  | CLERK     |
| 007499 | ALLEN  | SALESMAN  |
| 007521 | WARD   | SALESMAN  |
| 007566 | JONES  | MANAGER   |
| 007654 | MARTIN | SALESMAN  |
| 007698 | BLAKE  | MANAGER   |
| 007782 | CLARK  | MANAGER   |
| 007788 | SCOTT  | ANALYST   |
| 007839 | KING   | PRESIDENT |
| 007844 | TURNER | SALESMAN  |
| 007876 | ADAMS  | CLERK     |
| 007900 | JAMES  | CLERK     |
| 007902 | FORD   | ANALYST   |
| 007934 | MILLER | CLERK     |
+--------+--------+-----------+ 展示前三列

	select ename from emp_view; 只看第一列
+--------+
| ename  |
+--------+
| SMITH  |
| ALLEN  |
| WARD   |
| JONES  |
| MARTIN |
| BLAKE  |
| CLARK  |
| SCOTT  |
| KING   |
| TURNER |
| ADAMS  |
| JAMES  |
| FORD   |
| MILLER |
+--------+

	更改: update emp_view set ename='Angela' where ename='SMITH';
	select ename from emp_view;
+--------+
| ename  |
+--------+
| Angela |
| ALLEN  |
| WARD   |
| JONES  |
| MARTIN |
| BLAKE  |
| CLARK  |
| SCOTT  |
| KING   |
| TURNER |
| ADAMS  |
| JAMES  |
| FORD   |
| MILLER |
+--------+
 	select * from emp;
+--------+--------+-----------+------+---------------------+---------+---------+--------+
| empno  | ename  | job       | mgr  | hiredate            | sal     | comm    | deptno |
+--------+--------+-----------+------+---------------------+---------+---------+--------+
| 007369 | Angela | CLERK     | 7902 | 1980-12-17 00:00:00 |  800.00 |    NULL |     20 |
| 007499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 00:00:00 | 1600.00 |  300.00 |     30 |
| 007521 | WARD   | SALESMAN  | 7698 | 1981-02-22 00:00:00 | 1250.00 |  500.00 |     30 |
| 007566 | JONES  | MANAGER   | 7839 | 1981-04-02 00:00:00 | 2975.00 |    NULL |     20 |
| 007654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 00:00:00 | 1250.00 | 1400.00 |     30 |
| 007698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 |    NULL |     30 |
| 007782 | CLARK  | MANAGER   | 7839 | 1981-06-09 00:00:00 | 2450.00 |    NULL |     10 |
| 007788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 00:00:00 | 3000.00 |    NULL |     20 |
| 007839 | KING   | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 |    NULL |     10 |
| 007844 | TURNER | SALESMAN  | 7698 | 1981-09-08 00:00:00 | 1500.00 |    0.00 |     30 |
| 007876 | ADAMS  | CLERK     | 7788 | 1987-05-23 00:00:00 | 1100.00 |    NULL |     20 |
| 007900 | JAMES  | CLERK     | 7698 | 1981-12-03 00:00:00 |  950.00 |    NULL |     30 |
| 007902 | FORD   | ANALYST   | 7566 | 1981-12-03 00:00:00 | 3000.00 |    NULL |     20 |
| 007934 | MILLER | CLERK     | 7782 | 1982-01-23 00:00:00 | 1300.00 |    NULL |     10 |
+--------+--------+-----------+------+---------------------+---------+---------+--------+

修改视图的内容也就同步修改了真实表的内容, 而修改真实表的内容也会修改视图的内容删除视图:
	drop view [视图名称]; 删除之后, 再去查找 就没了

创建视图的数目是没有限制的;


用户管理:
	mysql的用户管理相当于linux操作系统的多用户管理
		linux操作系统当中
			root
			y2
			其他用户
	原因: 不想给数据库操作人员, 所有数据库的操作权限, 所以分用户; 可以设置用户只能看到某一个具体的数据库;
	不同的用户看到不同的数据库

mysql当中的用户名名称变现形式, root@localhost
	localhost: 表示允许root用户从本地(数据库所在的机器)连接数据库
	127.0.0.0:表示允许root用户从本地(数据库所在的机器)连接数据库
	%:表示可以从任意的ip地址连接到数据库
	前三个都是ipv4的
	::1: ipv6版本的IP地址
	

创建用户:
	create user '用户名’@‘允许从哪里连接上来’identified by '密码’
删除用户:
	drop user '用户名’@‘允许从哪里连接上来’
修改用户密码:
	root用户可以修改其他用户
		set password for ‘用户名’@‘允许从哪里连接上来’ = password(新密码);
	其他用户可以修改自己的密码
		set password = password(新密码);

如何给用户创建权限?
	1. 刚刚创建出来的用户是没有任何权限的,
	2. 语法:
		grant 权限列表(_priv)on 库名称/库名称.表名称 to '用户名’@‘允许登录的位置’[密码]
		权限列表:
			select: 只能检索不能插入
			all: 所有权限
		库名称或者库名称.表名称
			*.*: 表示当前mysql当中的所有数据库和所有数据表
			数据库名称.*: 对某一个数据库当中的所有表

	grant all on mysql.* to 'y2'@'localhost';  
现在y2用户就可以使用mysql数据库了(use mysql)
	
删除一个用户的权限(收回权限):
	revock 权限列表 (_priv)on 库名称或者库名称.表名称 from '用户名’@‘允许从哪里连接上来’
	revock all on mysql.* from 'y2'@'localhost’;
	现在该用户就不能再使用mysql了

你可能感兴趣的:(数据库知识点,mysql)