mysql数据库我的笔记

数据库
   |--DB
       //含义:按照一定的数据结构来 存储  数据的 容器。

数据库管理员
   |--DBA
       |--运维数据库

数据库管理系统
   |--DBMS
       |--含义:一款软件
                  // 管理  数据库(DB)
                       //安全性
                       //访问
                       //解析用户的操作
                       //内置函数
                       //...

------------------------------------------------------

数据管理过程
   |--手工记录
   |--文件系统
   |--数据库管理系统
        |--流程
             |--应用1    ---数据库管理
             |--应用2    ---系统
                             |
                             |
                           数据库
关系型数据库
    |--核心
          |--|--列和行组成

               |--列(表头)
                   |--字段
                   |--属性

               |--行(数据)
                   |--记录

          |--保存数据的步骤
               |--第一步:先确定多少列--->先新建表的结构(定义多少列)

               |--第二步:添加数据
                   
             名字   访问时间     事由     ...                       

             张三    2019-11-11  xx
             张三    2019-11-11  xx
             ...

SQLSERVER数据库
    |--含义:SQLSERVER数据库管理系统


Mysql数据库
    |--含义:MySQL关系数据库管理系统(RDBMS),开源免费
    |--安装 5.5
         //注意
             //选择编码方式 utf-8
             //是否添加的path
             //root  root

 -------------------------------------------------


SVN地址
   |--https://pc-201903161646/svn/17一班/trunk
   

命令
---------------------------------
  |--查看版本 select version();  

  |--查看数据库(数据库实例)    show databases(); 
       //一般一个项目对应一个数据库实例
            //包含很多表

  |--选择使用具体数据库实例 use 数据库名;

  |--列出多有的表  show tables;

  |--查看表的结构 desc 表名;


MYSQL体系结构(模块)
  


存储引擎
    |--含义:
         不同的存储引擎数据存储的结构是不一样的;
         不同的存储引擎特点也不一样。

                         特点                                     性能
             //MYISAM                                             强

             //INNODB    支持事务/行级锁/外键                       低
                             //对数据库的一组操作要么同时成功\失败
 
查看mysql支持的存储引擎
    |--show engines;
    |--修改存储引擎
          //安装目录下的my.ini
               //default-storage-engine=新的存储引擎;   //重新启动mysql


字符集
    |--编码:
         含义:字符和数值之间映射关系

    |--字符集
         含义:字符和编码的集合

             //gbk
             //utf-8
             //iso8859-1
             //gbk2312
             //...
    |--乱码
        含义:编码和解码不一致

mysql字符集(编码方式)
-------------------------------------------
    列出所有字符集信息
       |--show variables like '%char%';  %:任意

--------------------------------------------------------------------------------

创建数据库
   |--create database  [if not exists] 数据库名  //[] 可选
删除
   |--drop database 数据库名;

查看创建数据库信息
   |--show create database 数据库名;


ER图
-----------------
   |--含义:实体           的         关系 图
            //属性1 类型1
            //属性n 类型n



主键
   |--用来唯一区别记录的。
   |--要求:唯一&&不能为null。

   |--注意:千万不要用业务数据作为主键


复合主键
   |--用多个列来充当主键
   |--注意:
         每个列都不能为null


外键
   |--含义:某一列的数值是来自其他表的主键

约束
   |--含义:限制列要符合某些规则。

      |--非空 NOT NULL  比如:id\loginName\password\...看需求


      |--唯一 unique    比如:id\loginName\phone... 

      |--主键

      |--外键

      |--字符串的长度约束
    
      |--精度

      |--check  //定义的约束条件

User
---------------------
id  name loginName password address ... 


数据类型
   |--性能
   |--方便处理数据
   

MYSQL常用数据类型
   |--数值
        //整型
            //bit [1,64]
            //tinyint  byte
            //bool  <==>tinyint(1)
            //smallint mediunint int big int 
          
        //小数点
            //float(m,n)     //  
            //double(m,n)    //小数点的精度

            //decimal(m,n)   //价钱...

   |--时间类型
         //date 年月日
         //time 时分秒
         //datetime年月日时间分秒
         //year
         //timestamp 时间戳  


    |--字符串
        |--char(m)     比如:身份证\手机号...
        |--varchar(m)  变长
        |--text 文本   比如:文章内容
  
test1
create table department(
    dmid int primary key,
    dmname varchar(20) unique ,
    dmdirector  varchar(20) not null,
    dmloc char(8) check (dmloc in('南湖校区','浑湖校区') )
    );

create table test1(
    tid int primary key auto_increment,
    tloc enum('南湖校区','浑湖校区') 
    )character set = utf8; 

insert into person values('男','看电影,游泳,听音乐');

select * from person;

 insert into department values(1,'数学系','李进','nanhu');
 insert into department values(2,null,'李1','hunhu');
create table class(
    classid char(8),
    cla
)








案例一
   begin;  //开启事务
   insert into dept (dname,loc) values('csb','zj');
   insert into dept (dname,loc) values('yfb','gz');
   rollback


案例二
隐式结束
  隐式提交:当下列任意一种情况发生时,会发生隐式提交

    执行一个DDL(CREATE、ALTER、DROP、TRUNCATE、RENAME)语句;
    执行一个DCL(GRANT、REVOKE)语句;

  隐式回滚:当下列任意一种情况发生时,会发生隐式回滚
    客户端强行退出
    客户端连接到服务器端异常中断
    系统崩溃


   begin;  //开启事务
   delete from dept;
   create table type(
      id int primary key auto_increment,
      name varchar(30)
   )

<<<<<<< .mine
begin;
insert into test values (1,'a');
insert into test values (2,'b');
savepoint s1;
insert into test values (3,'c');
insert into test values (4,'d');
delete from  test where id in (1,3);
rollback to s1;
delete from test where id in (2,4);
commit;
||||||| .r7









=======
案例三 设置还原点、回滚点;注意了:这个两者操作不会结束事务

  //设置还原点
  savepoint 还原点的名称

  rollback to 还原点的名


  分析一
  begin;
  insert into dept(dname,loc)values('ceshibu','gz');
  rollback;  #当前事务结束了

  insert into dept(dname,loc)values('yafabu','sz');
  savepoint a;
  insert into dept(dname,loc)values('manager','sz');
  rollback;

  分析二
  begin;
  insert into dept(dname,loc)values('ceshibu','gz');
  rollback;

  begin;
  insert into dept(dname,loc)values('yafabu','sz');
  savepoint a;
  insert into dept(dname,loc)values('manager','sz');
  rollback to a;

  分析三
  begin;
  insert into dept(dname,loc)values('ceshibu','gz');
  rollback;

>>>>>>> .r9
  begin;
  insert into dept(dname,loc)values('yafabu','sz');
  savepoint a;
  insert into dept(dname,loc)values('manager','sz');
  savepoint b;
  insert into dept(dname,loc)values('scb','sz');
  rollback to b;
  delete from dept;
  commit;

SQL
   |--DDL
   |--DML  insert update delete 
   |--TPL
   |--DQL
        |--SELECT 


空值NULL
   |--是一种特殊值,没有赋值\不确定值
SELECT
-------------------------------------------
    含义:DQL,用于检索数据
    语法
        select * || 列名  from 表名 [where=conditions] 

    算术运算符
        |-- + - * / %  用于改变结果
        |--优先级和数学是一样的。
             |--可以通过() 改变优先级

案例空值处理
#mysql 自带的函数
#IFNULL(expr1,expr2)
select EMPNO,SAL*12 + ifnull(COMM,0) from emp;

列别名
    |--语法  
        |--as alias
        |--alias

    |--案例 
        select EMPNO,SAL*12 + ifnull(COMM,0) as money from emp;
        select EMPNO,SAL*12 + ifnull(COMM,0) money from emp;

    |--注意点
        |--如果别名有空格 或 特殊字符 需要添加 单引号 或 双引号


#消除重复行
语法
   |--DISTINCT * || 列名1,列名n
   select DISTINCT DEPTNO,EMPNO  from emp;
 

#消除重复行
语法
   |--DISTINCT * || 列名1,列名n
   select DISTINCT DEPTNO,EMPNO  from emp;


条件查询
   |--select ... from 表名 where 条件表达式
                                    //> >= < <= != 

   |--
      select * from emp where DEPTNO = 20
      select * from emp where DEPTNO = 20 || DEPTNO = 30;
      select * from emp where DEPTNO=20 and SAL > 1000; 

      select  * from emp where DEPTNO NOT IN (20,30)
      select  * from emp where DEPTNO IN (20,30)

   |--日期比较
        |--注意:必须添加单引号包含
        SELECT *FROM emp WHERE HIREDATE >'1985-01-01'
   |--between 下限 and 上限 //包含边界
        SELECT *FROM emp where sal BETWEEN 1000 AND 1500

   |--like
      SELECT *FROM emp where ENAME LIKE 'S%' #%任意个字符  _一个字符
      SELECT *FROM emp where ENAME LIKE '%S%' #%任意个字符  _一个字符
      SELECT *FROM emp where ENAME LIKE '%S_' #%任意个字符  _一个字符

      //模糊查询中包含_  %的处理方式
      select *from emp where JOB like 'MAN@_%' ESCAPE '@'
      select *from emp where JOB like 'MAN@%%' ESCAPE '@'

   |--is null is not null
      select *from emp where MGR is null       //查找老大
      select *from emp where MGR is not null   //查找被管理的员工

逻辑运算符
   |--and 
   |--or
   |--not

   案例
      ... WHERE sal NOT BETWEEN 3000 AND 5000
      ... WHERE ename NOT LIKE 'D%’
 
 |--排序(结果进行排序)

     ...  order by 列名 || 别名 asc(默认) || desc 
     案例
        |--select *from emp ORDER BY HIREDATE DESC 
        |--select *,12*sal + IFNULL(COMM,0) as money from emp ORDER BY money
        |--SELECT  ename, deptno, sal FROM emp  ORDER BY  deptno, sal DESC;

 |--分页
     语法 
        |--limit 跳过前面多少条,显示多少条
 
      为什么要分页
         |--性能

      案例

      #select *from emp limit 0,4;    //page=1  pageSize=4
      #select *from emp limit 4,4;    //page=2  pageSize=4
      
      #分页模型
      select *from emp limit (page-1)*4,pageSize; 

   
mysql函数
    |--含义:内置,直接调用
    |--分类
         |--单行函数 
         |--多行函数
    |--

数学函数
   
   select ABS(9) as result from dual; //获取绝对值

   select SQRT(4) FROM dual;          //开平方
   select SQRT(-4) FROM dual;         //开平方
      SELECT  ROUND(rand()*50) FROM DUAL;   //随机数加返回整数
   select MOD(9,3) FROM dual;         //求余数

   SELECT CEIL(-9.1) FROM DUAL;       //返回大于x的最小整数值  
   SELECT CEIL(9.1) FROM DUAL;        //返回大于x的最小整数值

   SELECT FLOOR(-9.1) FROM DUAL;      //返回小于x的最大整数值
   SELECT FLOOR(9.1) FROM DUAL;       //返回小于x的最大整数值

   SELECT ROUND(9.8) FROM DUAL;       //返回整数

   SELECT ROUND(9.86,1) FROM DUAL; #第二个参数如果是正数保留小数点多少位

   SELECT ROUND(922.86,-2) FROM DUAL; 结果为1000,与四舍五入有点相似 #第二个参数如果是负数保留小数点左边多少位变成0

      SELECT  TRUNCATE(10.232412,4) FROM DUAL;    TRUNCATE(x,y):截取函数,返回被舍弃的小数点后y位的数字x
   SELECT  log(exp(2))  FROM DUAL;   //exp为e^2 
   //其他 sin cos log ....
 


字符串函数
   CONCAT(s1,s2,…)  //简单拼接
   CONCAT_WS(x,s1,s2,…)  //使用x作为分隔符拼接

   INSERT(s1,x,len,s2);  //x如果是负数含义??

   LOWER (str)
   UPPER(str)
   LEFT(s,n)
   RIGHT(s,n)

   LPAD(s1,len,s2)  //左边开始填充
   RPAD(s1,len,s2)  //右边开始填充

   #select LTRIM("  abc   ") from DUAL;

   #select RTRIM("  abc   ") from DUAL;


#select TRIM("  abc   ") from DUAL;
SELECT rEPEAT('ABC',3) FROM DUAL;

比较字符串大小函数STRCMP(s1,s2):若所有的字符串均相同,则返回0,若根据当前分类次序,第一个参数小于第二个,则返回-1,其它情况返回1。


字符串替换函数REPLACE(s,s1,s2):将s字符串中的s1字符替换成s2。

SUBSTRING(s,n,len)

REVERSE(s)





 select concat(upper(left(ename,1)),lower(right(ename,length(ename)-1))) as name ,length(ename) as namelength from emp where left(ename,1) like "J%" or
 left(ename,1) like  "A%" or left(ename,1) like "M%" ORDER BY ename asc ;

select round(datediff("2000-01-01",hiredate)/30,0) as time ,hiredate from emp;

日期和时间函数
   |--CURDATE()  获取当前时间 年月日

   //TODO 
   |--select TIMEDIFF('18:00:00',10000) from dual;  

   DATEDIFF //两个日期相差的天数
   select DATEDIFF('2019-7-14','2019-7-1') from dual;  

   #%Y  %m  %d %H  %i %S  
   DATE_FORMAT(date,format)
   TIME_FORMAT(time,format)
   SELECT DATE_FORMAT(now(),'%Y年%m月%d日 %H时%i分%S秒');


   作业


流程控制函数
   |--CASE 
      |--语法1   使用的场景: 
          CASE 值

             WHEN '比较值1'
             THEN '结果1'

             WHEN '比较值2'
             THEN '结果2'
          END

      |--CASE  
            WHEN 表达式 THEN '成立结果' ELSE '其他'
         END
 

 //薪水

   //<= 4000 

  select 
  CASE 
     WHEN sal <=4000 THEN 'low'
     ELSE 'height'
  END 
   from emp;


   |--IF
      select if(sal<=4000,'low','height') from emp;

      //TODO 工资分位三个档次
      

   |--IFNULL
      //..

   |--NULLIF
      //TODO 


其他函数
   |--MD5 不可逆的加密算法
        //消息摘要
            //密码加密
            //文件校验(校验文件是否被人修改过)

 
-----------

碰撞破解
   |--将常用的明文-->密文-->保存到数据库

关联查询
   |--笛卡尔积
        |--含义:两张表记录乘机
        |--原因
             |--没有设置关联的条件


等值关联查询

  //查找员工编号\姓名\部门编号\工作地点信息
  select e.empno,e.ename,e.deptno,d.loc from emp e,dept d where e.deptno =d.deptno;

  //查找员工编号\姓名\部门编号信息,但是工作地点是在NEW YORK
  select e.empno,e.ename,e.deptno,d.loc from emp e,dept d where e.deptno = d.deptno and d.loc='NEW YORK';

非等值关联查询
  //查看所有员工信息\薪水级别
  select e.*,g.grade from emp e,salgrade g where e.sal between g.losal and g.hisal

自关联
  查询每个员工的姓名 和直接上级姓名  //TODO 没有上级领导的员工没有加载出来
  select e1.ename,e2.ename from emp e1,emp e2 where e1.mgr=e2.empno;



多表连接的关键点
    |--确定表
    |--确定关系

3.查询每个经理所管理的人数,经理编号,经理姓名,要求包括没有经理的人员信息。
查询比自己部门平均工资高的员工姓名,工资,部门编号,部门平均工资
select e.ename,e.sal,e.deptno,em.avgsal
from emp e,(select deptno,avg(sal) as avgsal from emp group by deptno)  em
where e.deptno=em.deptno
and e.sal>em.avgsal;
   |--交叉查询
今日知识点
   |--自然连接
        |--连接条件:同名并且类型需要一样
                   如果名字一样,类型不一样会报错
   |--using
        |--可以指定具体列或者几列作为连接条件

   |--on(编写连接条件)
       select e.*,d.loc from emp e join dept d on e.DEPTNO = d.DEPTNO  where 其他条件

       select e.EMPNO,e.ENAME,e.job,e.mgr,d.loc,m.ENAME as '领导' from emp e join dept d on e.DEPTNO = d.DEPTNO JOIN emp m on e.MGR = m.EMPNO;


   |--left join 
      语法:select *from 表1 left join 表2 on 表1和表2的关联条件


   |--right join 
      语法:select *from 表1 right join 表2 on 表1和表2的关联条件


分组函数
   |--含义:数据集合输入结果
   |--count(求记录数) min(最小) max(最大) avg(平均值) sum(求和)
   |--使用的地方
        select        //ok
        having        
        order by 

   |--查询入职日期最早和最晚的日期
      SELECT MIN(hiredate),max(hiredate) from emp;

   |--查找工作是SALES开头的平均月薪,月薪总和
      select AVG(sal),sum(sal)FROM emp where JOB like 'SALES%';

   |--count(*) 推荐使用count(主键)
      |--注意:返回满足条件的非空(NULL)行的数量
      SELECT COUNT(DISTINCT deptno) FROM emp; //TODO 自行描述其含义
 
   |--avg
      |--注意:空(NULL)的不会参与计算,如果需要参与计算,可以参考下面的案例
      select ceil(avg(ifnull(comm,0)))from emp;


GROUP BY
   思路:但凡看到每个字眼基本上都用到group by 分组
   语法:
   select 只能出现gourp by 的分组依据、分组函数 from emp GROUP BY 列1,...

   查询每个部门的编号,平均工资
   select DEPTNO,AVG(SAL) from emp GROUP BY DEPTNO; 

   查询 每个部门  每个岗位   的工资总和。
   select sum(sal) from emp GROUP BY DEPTNO,JOB

   查询 每个部门 最高薪水  大于2000
   select max(sal) from emp group by deptno HAVING max(sal) >= 3000
     

SELECT语句执行过程

   //案例分析
   select max(sal) maxSal,deptno from emp where deptno>20 group by deptno HAVING maxSal >= 3000

   //from   //给了表的别名

   //where  //不可以使用列的别名

   //group by 

   //select 

   //having //可以使用列的别名

   //order by 



子查询
   |--使用的位置
     WHERE子句

     HAVING子句

     FROM子句

    查询出比JONES为雇员工资高的其他雇员
    select *from emp where sal > (select sal from emp where ename ='JONES')


    显示   和雇员7369从事相同工作  并且工资大于雇员7876的  雇员的姓名和工作。

      SELECT
        ename,
        job
      FROM
        emp
      WHERE
        job = (
          SELECT
            job
          FROM
            emp
          WHERE
            empno = 7369
        )
      AND sal > (
        SELECT
          sal
        FROM
          emp
        WHERE
          empno = 7876
      )

    查询工资最低的员工姓名,岗位及工资
      select ename,job,sal from emp where sal = (select min(sal) from emp)

    查询  部门最低工资比20部门最低工资高的  部门编号及最低工资
      SELECT
        deptno,
        min(sal) minSal
      FROM
        emp
      GROUP BY
        deptno
      HAVING
        minSal > (
          SELECT
            min(sal)
          FROM
            emp
          WHERE
            deptNO = 20
        )

#查询 经理的姓名,工资
select ename,sal from emp where empno  in (select mgr from emp)

 

  all
    |--含义:满足全部条件即可。

    >all 等价于 max
    <all 等价于 min
    =all  

    查询  部门编号不为20,且工资比20部门所有员工工资高的   员工编号,姓名,职位,工资。
    SELECT
      empno,
      ename,
      job,
      sal
    FROM
      emp
    WHERE
      sal > ALL (
        SELECT
          sal
        FROM
          emp
        WHERE
          deptno = 20
      )
    AND deptno != 20;



    #查询  部门编号不为10,且工资比 10部门所有员工 工资低  的   员工编号,姓名,职位,工资。
      SELECT
        empno,
        ename,
        job,
        sal
      FROM
        emp
      WHERE
        sal < ALL (
          SELECT
            sal
          FROM
            emp
          WHERE
            deptno = 10
        )
      AND deptno != 10;

any
   含义:有一个满足条件即可。

    >any
    <any
    =any 等价于in  

   #查询 部门编号不为10,且工资 比10部门任意一名员工 工资高的    员工编号,姓名,职位,工资。
    SELECT
      empno,
      ename,
      sal
    FROM
      emp
    WHERE
      deptno != 10
    AND sal > ANY (
      SELECT
        sal
      FROM
        emp
      WHERE
        deptno = 10
    )


   #查询 部门编号不为10,且工资 比10部门任意一名员工 工资低的    员工编号,姓名,职位,工资。
    SELECT
      empno,
      ename,
      sal
    FROM
      emp
    WHERE
      deptno != 10
    AND sal < ANY (
      SELECT
        sal
      FROM
        emp
      WHERE
        deptno = 10
    )

    #查询是经理的员工姓名,工资
      SELECT
        ename,
        sal
      FROM
        emp
      WHERE
        empno = ANY (SELECT mgr FROM emp)


在 FROM 子句中使用子查询
  #查询   比 自己  部门平均工资高的    员工姓名,工资,部门编号,部门平均工资
    SELECT
      e.ename,
      e.sal,
      e.deptNo,
      t.avgSal
    FROM
      emp e,
      (
        SELECT
          avg(sal) avgSal,
          deptNo
        FROM
          emp
        GROUP BY
          deptNo
      ) t
    WHERE
      e.DEPTNO = t.deptNo
    AND e.sal > t.avgSal;
  
//TODO 
子查询中的空值问题

  SELECT
    ename
  FROM
    emp
  WHERE
    empno NOT IN (SELECT mgr FROM emp);


  子查询返回的结果中含有空值
  上面的SQL语句试图查找出没有下属的雇员,逻辑上,这个SQL语句应该会返回8条记录,但是却一条也没返回,why?

  因为子查询的结果中有一条空值,这条空值导致主查询没有记录返回。这是因为所有的条件和空值比较结果都是空值。因此无论什么时候只要空值有可能成为子查询结果集合中的一部分,就不能使用NOT IN 运算符


from里面放select的情况
总结:题目里有每种即涉及到group by 且要打印出分组函数下的值 如每种的什么什么和,平均什么什么,或者最低什么什么

1.查询部门平均工资在2500元以上的部门名称及平均工资。
select dept.dname,em.avgsal
from emp,dept,(select deptno,avg(sal) as avgsal from emp group by deptno ) em
 where em.avgsal>2500 and emp.deptno=em.deptno and emp.deptno=dept.deptno
group by emp.deptno;
2.查询员工岗位中不是以“SA”开头并且平均工资在2500元以上的岗位及平均工资,并按平均工资降序排序。
select emp.job,em.avgsal
from emp,dept,(select deptno,avg(sal) as avgsal from emp group by job) em
 where em.avgsal>2500 and emp.deptno=em.deptno and emp.deptno=dept.deptno and emp.job not like "SA%"
group by emp.deptno
order by em.avgsal desc;
3.查询部门人数在2人以上的部门名称、最低工资、最高工资,并对求得的工资进行四舍五入到整数位。
select dept.dname,round(min(emp.sal)),round(max(emp.sal))
from emp,dept,(select deptno,count(*) as num from emp group by deptno) em
 where em.num>2 and emp.deptno=em.deptno and emp.deptno=dept.deptno 
group by emp.deptno;

4.查询岗位不为SALESMAN,工资和大于等于2500的岗位及每种岗位的工资和。 
select emp.job,em.sumsal
from emp,dept,(select deptno,sum(sal) as sumsal from emp group by job) em
 where em.sumsal>=2500 and emp.deptno=em.deptno and emp.deptno=dept.deptno and emp.job !="salesman"
group by emp.job;
5.显示经理号码和经理姓名,这个经理所管理员工的最低工资,
没有经理的KING也要显示,不包括最低工资小于3000的,按最低工资由高到低排序。

6.查询工资高于编号为7782的员工工资,并且和7369号员工从事相同工作的员工的编号、姓名及工资。



7.查询工资最高的员工姓名和工资。 
select ename,sal
 from emp e,(select max(sal) as maxsal from emp )em
where e.sal=em.maxsal;

;

8.查询  部门最低工资高于10号部门最低工资的  部门的编号、名称及部门最低工资。

select e.deptno,d.dname,em.minsal
from emp e,dept d, (select min(sal) as minsal10 from emp where deptno=10 )em10, (select deptno,min(sal) as minsal from emp group by deptno )em
where e.deptno=d.deptno and e.deptno=em.deptno and em.minsal>em10.minsal10
group by e.deptno;


9.查询员工工资为其部门最低工资的员工的编号和姓名及工资。
10.显示经理是KING的员工姓名,工资。
11.显示比员工SMITH参加工作时间晚的员工姓名,工资,参加工作时间。
12.使用子查询的方式查询哪些职员在NEW YORK工作。
13.写一个查询显示和员工SMITH工作在同一个部门的员工姓名,雇用日期,查询结果中排除SMITH。
14.写一个查询显示其工资比全体职员平均工资高的员工编号、姓名。
15. 显示部门名称和人数
16. 显示每个部门的最高工资的员工
17. 显示出和员工号7369部门相同的员工姓名,工资
18. 显示出和姓名中包含“W”的员工相同部门的员工姓名

4.查询部门人数大于所有部门平均人数的的部门编号,部门名称,部门人数
select e.deptno,d.dname,count(e.ename) as num
from emp e,dept d
where e.deptno=d.deptno
group by deptno
having  num>all (select avg(e.ename) from emp group by deptno);
(solor)
1.创建一个视图,通过该视图可以查询到工资在2000-5000内并且姓名中包含有A的员工编号,姓名,工资。
create view  sal2000
as select deptno,ename,sal
from emp
where sal between 2000 and 5000;
select *from sal2000
desc sal2000

1.创建视图v_emp_20,包含20号部门的员工编号,姓名,年薪列(年薪=12*(工资+奖金);
2.从视图v_emp_20中查询年薪大于1万元员工的信息;
3.请为工资大于2000的员工创建视图,要求显示员工的部门信息,职位信息,工作地点;
4.针对以上视图执行insert,update,delete,语句能否成功,为什么?

   |--用户和权限管理 
       |--登录  需要校验账号\密码:
             |--host
             |--user/password

       |--授权  判断用户当前操作是否有权限
          权限表共有6个表:user、db、host、tables_priv、 columns_priv和procs_priv。
          当MySQL服务启动时,会首先读取MySQL中的权限表,并将表中的数据装入内存。当用户进行存取操作时,MySQL会根据这些表中的数据做相应的权限控制。
 

       |--User表中的权限是全局的
           比如:
           Insert_priv:Y   
           含义:当前用户能对所有数据库的所有表都有插入权限

           Insert_priv :N  
           含义:当前用户 不能对所有数据库的所有表都有插入权限;如果插入需要进一步权限校验


      |--db
           |--存储了用户对某个数据库的操作权限

      |--tables_priv
           |--记录用户对哪个数据库的哪张表的权限

      |--column_priv
           |--列的权限
------------------------------------------------------

mysql安全
    |--验证
         |--User表中判断host\user\password

    |--授权校验流程
         if(User表校验权限(全局)){
             执行操作
         }else if(从DB表校验权限){
             执行操作
         }else if(从table_priv表校验权限){
             执行操作
         }else if(从column_priv表校验权限){
             执行操作
         }else{
            报错,没有权限
         }
             
创建用户
  CREATE USER 用户名[IDENTIFIED BY [PASSWORD]'password']
  [,user[IDENTIFIED BY [PASSWORD]'password']][,…];

   create user 'crm'@'localhost' identified by '123456';  


创建用户并且授权
GRANT  priv_type  ON database.table
   TO user [IDENTIFIED BY [PASSWORD] 'password']
       [, user [IDENTIFIED BY [PASSWORD] 'password']] [,…]

       [WITH GRANT OPTION];
          //授权的权限


GRANT INSERT ON crm.* TO 'crm'@'localhost' identified by '123456' WITH GRANT OPTION; 


GRANT INSERT ON crm.emp TO 'otherCrm'@'localhost' identified by '123456' WITH GRANT OPTION; 
1.自己尝试创建一个用户user1,并授予所有数据表的SELECT和UPDATE权限

create user user_1 identified by '123456';
grant select on user_1.emp to 'otherCrm' identified by '123456' with grant option; 


创建用户
  语法:
  CREATE USER 用户名[IDENTIFIED BY [PASSWORD]'password']
  [,user[IDENTIFIED BY [PASSWORD]'password']][,…];

  案例:
  create user 'crm'@'localhost' identified by '123456';  


创建用户并且授权
  语法:
    GRANT  priv_type  ON database.table
       TO user [IDENTIFIED BY [PASSWORD] 'password']
           [, user [IDENTIFIED BY [PASSWORD] 'password']] [,…]
           [WITH GRANT OPTION];    //授权的权限
        

  案例:
  GRANT INSERT ON crm.* TO 'crm'@'localhost' identified by '123456' WITH GRANT OPTION; 

  GRANT INSERT ON crm.emp TO 'otherCrm'@'localhost' identified by '123456' WITH GRANT   OPTION; 

//删除账户并清理权限
   DROP USER otherCrm@localhost;  //删除账号并且清除对应的授权信息


//修改账户名
  //语法:
  RENAME USER old_user TO new_user,[, old_user TO new_user] [,…];

  //案例
  rename user haha@localhost to haha2@localhost;


//修改其他用户的密码
   语法:ALTER USER userIDENTIFIED BY 'password';

   案例:
   ALTER USER for crm@localhost IDENTIFIED BY '*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B';


//修改密码
    //修改指定账户的密码
    语法:SET  PASSWORD FOR [user]= PASSWORD('newpassword');
    案例:SET PASSWORD  crm@localhost = PASSWORD('ROOT');

    
    //修改自己的密码(需要重新登录)
    SET PASSWORD =PASSWORD('123456');

-------------------------------------
授权管理
   GRANT语句的基本语法格式如下。

     GRANT priv_type [(column_list)] [,priv_type [(column_list)]] [,…n]
       ON {table_name|*|*.*|database_name.*|database_name.table_name}
       TO user[IDENTIFIED BY [PASSWORD] 'password']
       [,user[IDENTIFIED BY [PASSWORD] 'password']] [,…n]
       [WITH GRANT OPTION];


  //准备环境(自行准备)

      创建CRM账户:
         对crm数据库所有的表都有插入的权限

   //案例 赋值权限案例

      //赋值删除权限
         grant delete on crm.* to crm@localhost

      //赋值更新权限
         //赋值更新所有列的权限
         grant update on crm.emp to crm@localhost

         //赋值更新指定列的权限
         grant update(empno) on crm.emp to crm@localhost
 
    //案例 收回权限

      语法:
       REVOKE ALL PRIVILEGES,GRANT OPTION
       FROM 'username'@'hostname'[,'username'@'hostname'][,…n];

      案例
        //收回所有权限,包括GRANT权限
        revoke all privileges,grant option from crm@localhost;
                              //grant option代表包括grangt权限
        //收回crm账号更新empno列的权限
        revoke update(empno) on crm.emp from crm@localhost;

    //显示已经授予的权限
       语法:
          show grants for 账号;

        案例:
          show grants for crm@localhost;

MYSQL编程
   |--过程
        |--变量
        SET  @user_variable1=expression1 
        [,user_variable2= expression2 , …]


         set @java = '1.8';
set @mysqldb = '5.x';

set @result = concat(@java,@mysqldb);
select @result;


set @maxEmpNo = (select max(empNo) from emp);
select @maxEmpNo;


--------------
set @maxEmpNo = (select max(empNo) from emp);


select @maxEmpNo;
 

select *from emp where empno = @maxEmpNo;

//系统变量
    //@@  @@version
    //CURRENT_USER



 |--存储过程
      |--含义:

          是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。
        存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程字并给定参数(需要时)来调用执行
        简单而言:就是数据库 SQL 语言层面的代码封装与重用。

    
      |--优点
          |--存储过程在服务器端运行,执行速度快。
          |--存储过程执行一次后,其执行规划就驻留在高速缓冲存储器,在以后的操作中,只需从高速缓冲存储器   中调用已编译好的二进制代码执行,提高了系统性能。
          |--封装内部实现细节,确保数据库的安全

      |--缺点
          |--不同数据库产品的语法有些不同,切换数据库产品需要重新编写对应数据库的存储过程。
 

      |--语法
          CREATE PROCEDURE 存储过程名 ([参数[,...]])
              存储过程体
 
      |--参数说明:
           [ IN | OUT | INOUT ] 参数名 类型

      |--DELIMITER关键字
           |--含义:关键子,用来指定MySQL语句的结束标志修,默认的结束符是(;),放在定义存储过程
           或函数前面。
           一般操作:
              |--DELIMITER $$ //修改语句结束符为$$
              |--DELIMITER ; //恢复结束符为;

      |--局部变量
        局部变量含义:在beign end之间定义的变量
        局部变量定义语法:
            DECLARE 局部变量名 类型 [default 默认值]
 
      |--案例一 编写一个存储过程,实现的功能是删除一个特定会员的信息
          DELIMITER $$
          create procedure pro_del_member(in memberId char(18))
            BEGIN //相当于是{

             delete from members where  身份证号 = memberId;
            
            END $$ //相当于是}
          DELIMITER ;


      |--案例二 在存储过程中使用局部变量并结合SELECT...INTO语句

          DELIMITER $$
          create procedure init_mul_variables(in memberId char(18),out resultId char(18),out resultName(varchar(30)) )
            BEGIN  
                 DECLARE resultMemberId char(18);
                 DECLARE resultMemberName varchar(30);

                select 身份证号,会员姓名 into resultMemberId,resultMemberName from members where  身份证号 = memberId;

                set resultId = resultMemberId;
                set resultName = resultMemberName;
            END $$ 
          DELIMITER ;

      |--调用
           CALL 过程名([参数1,参数...])


      |--SHOW PROCEDURE STATUS  //列出有多少过程

      |--SHOW CREATE PROCEDURE init_mul_variables  //详情

      |--删除存储过程
          DROP PROCEDURE  [IF EXISTS] 存储过程名

--------------------------------------------------------------
 

存储过程控制语句
    |--IF
       IF 条件1 THEN 语句序列1
        [ELSEIF条件2 THEN语句序列2] ...
        [ELSE  语句序列e]
       END IF

       创建存储过程,判断两个输入的参数哪一个更大

          DELIMITER $$
          create procedure compareMax(in param1 int,in param2 int,out result varchar(20))
            BEGIN  
 
               IF
                   param1 >  param2 THEN SET result = concat(param1,'>',param2);

                   ELSEIF param1 <  param2  THEN SET result = concat(param1,'<',param2);

                   ELSE SET result = concat(param1,'=',param2);

               END IF;

            END $$
          DELIMITER ;

        call compareMax(1,2,@result);
        select @result;


      |--CASE

        CASE 表达式
           WHEN 值1 THEN 语句序列1
           [WHEN值2 THEN语句序列2] ...
           [ELSE语句序列e]
        END CASE;

        或者:
        CASE
           WHEN 条件1  THEN 语句序列1
           [WHEN条件2  THEN语句序列2] ...
           [ELSE语句序列e]
        END CASE;

        案例:
        创建一个存储过程,当给定参数为U时返回“上升”,给定参数为D时返回“下降”,给定其他参数时返回“不变”。

         DELIMITER $$
          create procedure judge1(in param char(1),out result varchar(20))
            BEGIN  

            CASE param
               WHEN 'U' THEN SET result = "上升";
               WHEN 'D' THEN SET result = "下降";

               ELSE SET result = "不变";
            END CASE;
            END $$
          DELIMITER ;


          DELIMITER $$
          create procedure judge2(in param char(1),out result varchar(20))
            BEGIN  

            CASE 
               WHEN 'U'=param THEN SET result = "上升";
               WHEN 'D'=param THEN SET result = "下降";

               ELSE SET result = "不变";
            END CASE;
            END $$
          DELIMITER ;

      |--循环
          while
          WHILE语句语法格式为:

          [开始标号:] WHILE条件  DO
             程序段
          END WHILE [结束标号]

          DELIMITER $$
          create procedure fiveEach(out result varchar(100))
            BEGIN  
            DECLARE a int default 5;

            set result = '';

            WHILE a >0 DO
               set a = (a-1);
               set result = concat(result,a);
            END WHILE;
            END $$
          DELIMITER ;

call fiveEach(@result);
select @result;


//////////

REPEAT语句格式如下:
      [开始标号:] REPEAT
                    程序段
      UNTIL 条件
      END REPEAT [结束标号]


 

             DELIMITER $$
          create procedure fiveEach(out result varchar(100))
            BEGIN  
            DECLARE a int default 5;

            set result = '';

            
            END $$
          DELIMITER ;



//LOOP语句


-----------------------------
自定义函数
   |--和过程的区别
       |--自定义函数没有输出参数  out
       |--不能通过call调用
       |--return 过程是没有return
 

 语法

            CREATE FUNCTION 自定义函数名 ([参数[,...]])
            RETURNS 类型

                     函数体


//查找图书数量

 DELIMITER $$
  create function findEmpCount()
   returns int
   BEGIN 
   return (select count(*) from emp);
   END $$
 DELIMITER ;


//SHOW FUNCTION STATUS



创建一个自定义函数,返回emp表中id 姓名

 DELIMITER $$
  create function findByEmpNo(empnoParam varchar(30))
   returns varchar(30)
   BEGIN 
   return (select ename from emp where empno = empnoParam);
   END $$
 DELIMITER ;


select findByEmpNo(7369) from dual;


#

   CREATE TRIGGER 触发器名  触发时间  触发事件
               ON 表名 FOR EACH ROW  触发器动作

               /


           


               创建一个表table1,其中只有一列a。

               在表上创建一个触发器,每次插入操作时,将用户变量str的值设为“TRIGGER IS WORKING”。
    CREATE TABLE table1(a INTEGER);
 
 create trigger talbe1Trigger after insert on table1 for each row 
 SET @str= ' TRIGGER IS WORKING';

 INSERT INTO table1 VALUES(10);



#级联删除
  DELIMITER $$

  CREATE TRIGGER dept_del before DELETE
  ON dept FOR EACH ROW 
    BEGIN
        DELETE FROM emp WHERE deptno = OLD.deptno;
    END$$
  DELIMITER ;

  //

  假设数据库中有一个与Members表结构完全一样的表member_backup,


  创建一个触发器,在Members表中添加数据的时候,

   //
  调用存储过程,将member_backup表中的数据与Members表同步。

                //批量添加
                //增量
                   //member_back      member 
                     //id                   //id   
                    
                   //获取member_back 主键的最大值     
                   //获取member 主键的最大值  

                   if(==){

                   }else if(获取member主键 > 获取member_back主键){
                      遍历         5               2

                        id = 3 4 5 


                

                   }




首先,定义存储过程:创建一个与Members表结构完全一样的表


 

//java 基础
  //1.8
     //


DELIMITER $$
create procedure init_mul_variables(in memberId char(18),out resultId char(18),out resultName varchar(30))
  BEGIN  
       DECLARE resultMemberId char(18);
       DECLARE resultMemberName varchar(30);

      select 身份证号,会员姓名 into resultMemberId,resultMemberName from members where  身份证号 = memberId;

      set resultId = resultMemberId;
      set resultName = resultMemberName;
  END $$ 
DELIMITER ;
 1.
DELIMITER $$
create procedure init_delete(in memberId char(18))
  BEGIN  
      delete from members where 身份证号=memberId ;
  END $$ 
DELIMITER ;
call init_delete('430103198608201963');
SHOW PROCEDURE STATUS  //列出有多少过程

SHOW CREATE PROCEDURE init_mul_variables  //详情


ppt30例


DELIMITER $$
CREATE PROCEDURE dj_update(IN c_name  CHAR(8), IN b_name CHAR(20))
  BEGIN
    DECLARE  bh CHAR(20);
    DECLARE  sfz CHAR(18);
    DECLARE  sl TINYINT;
    SELECT 身份证号 INTO sfz  FROM Members   WHERE  会员姓名=c_name;
    SELECT 图书编号 INTO bh  FROM Book WHERE  书名=b_name;
    SELECT 订购册数 INTO sl FROM Sell  WHERE 身份证号=sfz AND 图书编号=bh;
    IF sl>=5 AND sl<=10 THEN
        UPDATE Sell SET 订购单价=订购单价*0.9  WHERE 身份证号=sfz AND 图书编号=bh;
     ELSE 
        IF sl>10 THEN
        UPDATE Sell SET 订购单价=订购单价*0.8  WHERE 身份证号=sfz AND 图书编号=bh;
       END IF;
    END IF;
  END$$
DELIMITER ;
调用存储过程dj_update:
    CALL dj_update ('张三', '网络数据库');



DELIMITER $$
create procedure init_count(in memberName char(10),in bookName varchar(40),out result varchar(20) )
begin 
        declare bookNum TINYINT;
    declare memberid char(18);
    declare bookid char(20);
    select 身份证号 into memberid from members where 会员姓名=memberName ;
    select 图书编号 into bookid from book where 书名=bookName ;

    select 订购册数 into bookNum from sell where 身份证号=memberid  and 图书编号=bookid;
    if bookNum<5 then
    set result="不打折";
    else 
    if bookNum>=5 and bookNum<=10  then
     set result="打9折";
    else if bookNum>10 then
    set  result="打8折";
    end if;
    end if;
    end if;
    end $$
    
DELIMITER ;


    CALL  init_count ('王林', '网络数据库');

猜你喜欢

转载自www.cnblogs.com/fafafa123/p/11705773.html