MySQL常用操作汇总

    xiaoxiao2022-07-02  158

    MySQL之DDL常用命令

    create database study1; create database study2 character set gbk; show databases; show create database study2; alter database study2 character set utf8; show create database study2; drop database study2; use study1; select database(); create table employee( id int, name varchar(20), sex char(1), birthday date, job varchar(50), salary double ); show tables; desc employee; alter table employee add address varchar(100); alter table employee modify job varchar(30); alter table employee drop address; rename table employee to user; show create table user; alter table user character set gbk; alter table user change name username varchar(20); drop table user;

    MySQL之DML常用命令

     delete只是删除表中的数据,不删除表,删除后的数据可以恢复。  truncate删除是把表直接drop掉,然后再创建一个同样的新表。删除的数据不能找回。执行速度比delete快。

    use study1; create table emp( id int, name varchar(100), sex char(6), birthday date, salary float(10,2) ); insert into emp values (1,'andy','male','1995-05-15',10000); insert into emp (id,name,sex,birthday,salary) values (2,'paul','male','1996-06-15',15000); insert into emp (id,name,sex,birthday,salary) values (3,'lucy','female','1998-07-11',8000); insert into emp (id,name,sex,birthday,salary) values (4,'james','male','1985-08-10',50000), (5,'marry','female','1987-06-15',30000), (6,'carter','male','1995-05-15',10000); select * from emp; update emp set salary=80000 where name='james'; delete from emp where name='lucy'; delete from emp; truncate table emp;

    MySQL之DQL常用命令

    create database monkey1024; use monkey1024; create table dept( deptno int(2), dname varchar(14), loc varchar(13) ); delete from dept; insert into dept values(10,'accounting','new york'); insert into dept values(20,'research','dallas'); insert into dept values(30,'sales','chicago'); insert into dept values(40,'operations','boston'); select * from dept; drop table dept; create table emp( empno int(4), ename varchar(10), job varchar(9), mgr int(4), hiredate date, sal double(7,2), comm double(7,2), deptno int(2) ); insert into emp values(7369,'smith','clerk',7902,'1980-12-17',800,null,20); insert into emp values(7499,'allen','salesman',7698,'1981-02-20',1600,300,30); insert into emp values(7521,'ward','salesman',7698,'1981-02-22',1250,500,30); INSERT INTO emp values(7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL,20); INSERT INTO emp values(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30); INSERT INTO emp values(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,NULL,30); INSERT INTO emp values(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,NULL,10); INSERT INTO emp values(7788,'SCOTT','ANALYST',7566,'1987-04-19',3000,NULL,20); INSERT INTO emp values(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10); INSERT INTO emp values(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30); INSERT INTO emp values(7876,'ADAMS','CLERK',7788,'1987-05-23',1100,NULL,20); INSERT INTO emp values(7900,'JAMES','CLERK',7698,'1981-12-03',950,NULL,30); INSERT INTO emp values(7902,'FORD','ANALYST',7566,'1981-12-03',3000,NULL,20); INSERT INTO emp values(7934,'MILLER','CLERK',7782,'1982-01-23',1300,NULL,10); select * from emp; create table salgrade( grade int(11), hisal int(11), losal int(11) ); insert into salgrade values(1,1200,700); insert into salgrade values(2,1400,1201); insert into salgrade values(3,2000,1401); insert into salgrade values(4,3000,2001); insert into salgrade values(5,9999,3001); select ename from emp; select empno,ename from emp; select * from emp; select empno,ename,sal*12 from emp; select empno,ename,sal*12 as yearsal from emp; select empno,ename,sal*12 yearsal from emp; select empno,ename,sal*12 as '年薪' from emp; select empno,ename,sal from emp where sal=5000; select empno,ename,job from emp where job='manager'; select empno,ename,sal from emp where sal<> 5000; select empno,ename,sal from emp where sal>=1600 and sal<=3000; select empno,ename,sal from emp where sal between 1600 and 3000; select empno,ename,comm from emp where comm is null; select empno,ename,comm from emp where comm is not null; select empno,ename,job,sal from emp where job='manager' and sal>2500; select ename,job from emp where job='salesman' or job='manager'; select * from emp where sal>1800 and (deptno=20 or deptno=30); select ename,job from emp where job in('salesman','manager'); select ename,sal from emp where sal not in (1600,3000); select ename from emp where ename like 'm%'; select ename from emp where ename like '%n'; select ename from emp where ename like '%o%'; select ename from emp where ename like '_a%';

    MySQL排序和处理函数

    select ename,sal from emp order by sal; select ename,job,sal from emp where job='manager' order by sal; select ename,sal from emp order by sal asc; select ename,sal from emp order by sal desc; select ename,job,sal from emp order by job desc,sal desc; select * from emp order by 6; select lower(ename) as ename from emp; select upper(ename) as ename from emp; select substr(ename,2,1) from emp; select ename from emp where substr(ename,2,1)='a'; select ename from emp where ename like '_A%'; select ename,length(ename) as nameLength from emp; select ename,ifnull(comm,0) from emp; select sal+ifnull(comm,0) from emp; select ename,(sal+ifnull(comm,100))*12 yearsal from emp; select ename,sal,job, (case job when 'manager' then sal*1.1 when 'salesman' then sal*1.5 else sal end) as newsal from emp; select * from emp where job=trim(' manager '); select round(sal,1) from emp; select rand(),sal from emp; select round(rand()*100),sal from emp; select ename,hiredate from emp where hiredate='1981-12-03'; select ename,hiredate from emp where hiredate = str_to_date('02-20-1981','%m-%d-%Y'); select ename,date_format(hiredate,'%m-%d-%Y') hiredate from emp;

    MySQL分组和聚合函数

    select sum(sal) from emp; select sum(sal+ifnull(comm,0)) from emp; select avg(sal) as avgsal from emp; select max(sal) as maxsal from emp; select max(hiredate) as lastemp from emp; select min(sal) as minsal from emp; select count(*) from emp; select count(comm) from emp; /*count函数不会统计数据为null的记录*/ select count(*),sum(sal),avg(sal),max(sal),min(sal) from emp; /*distinct去除重复记录*/ select distinct job from emp; select count(distinct job) from emp; select distinct job,deptno from emp; select sal from emp; select max(sal) as maxsal from emp; select max(sal) as maxsal from emp group by job; /*按职位分组,找出最高薪水*/ select job,max(sal) as maxsal from emp group by job; /*在有group by的DQL询问中,select语句后面只能跟聚合函数+参与分组的字段*/ select ename,job,max(sal) as maxsal from emp group by job; select job,max(sal) as maxsal from emp group by job order by maxsal; select deptno,avg(sal) as avgsal from emp group by deptno; /*group by后面可以写多个字段,数据库会分别对这些字段进行分组*/ select deptno,job,max(sal) as maxsal from emp group by deptno,job; select job,max(sal) as maxsal from emp where job <> 'manager' group by job; /*下面写法不正确,where后面不能直接使用聚合函数*/ select job,avg(sal) as avgsal from emp where avg(sal)>2000 group by job; /*where和having的区别 where和having都是为了完成数据的过滤,它们后面都是添加条件; where是在group by之前完成过滤; having是在group by之后完成过滤*/ select job,avg(sal) from emp group by job having avg(sal)>2000; select xx from xx where xx group by xx having xx order by xx; /*from:将硬盘上的表文件加载到内存 where:将符合条件的数据筛选出来。生成一张新的临时表 group by:根据列中的数据种类,将当前临时表划分成若干个新的临时表 having:可以过滤掉group by生成的不符合条件的临时表 select:对当前临时表进行整列读取 order by:对select生成的临时表,进行重新排序,生成新的临时表 limit:对最终生成的临时表的数据行,进行截取*/

    MySQL之连接查询

    use monkey1024; # emp和dept两张表中数量的乘积 select e.ename,d.dname from emp e,dept d; select e.ename,d.dname from emp e,dept d where e.deptno = d.deptno; select d.dname,e.ename from emp e join dept d on e.deptno=d.deptno; # 内连接查询出的数据是两张表的交集,即上图中C所表示的部分 select d.dname,e.ename from emp inner join dept d on e.deptno=d.deptno; # inner可以省略 select d.dname,e.ename from emp e join dept d on e.deptno = d.deptno; select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno; select e.name,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal; select a.ename empname,b.ename leadername from emp a join emp b on a.mgr=b.empno; # 自连接 /*左外连接包含左边表的全部行(不管右边的表是否存在与它匹配的行),和 右边表中全部匹配的行*/ select e.ename,d.dname from dept d left outer join emp e on e.deptno=d.deptno; # outer可以省略 select e.ename,d.dname from dept d left join emp e on e.deptno=d.deptno; /*右外连接包含右边表的全部行(不管左边的表中是否存在与它匹配的行),和 左边表中全部匹配的行*/ select e.ename,d.dname from emp e right outer join dept d on e.deptno=d.deptno; #outer可以省略 select e.ename,d.dname from emp e right join dept d on e.deptno=d.deptno; # 右外连接都可以改写成左外连接,左外连接都可改写成右外连接 select a.ename empname,b.ename leadername from emp a left join emp b on a.mgr=b.empno; select e.ename,d.dname,e.sal,s.grade from emp e join dept d on e.deptno=d.deptno join salgrade s on e.sal between s.losal and s.hisal;

    MySQL查询其他内容

    # select语句嵌套select语句被称为子查询 select ename,sal from emp where sal>(select avg(sal) from emp); select t.deptno,t.avgsal,s.grade from salgrade s join (select deptno,avg(sal) as avgsal from emp group by deptno) t on t.avgsal between s.losal and s.hisal order by t.deptno; # 使用union合并结果,合并结果集时查询字段的个数必须一致 select empno,ename,job from emp where job='manager' union select empno,ename,job from emp where job='salesman'; /*limit limit起始下标m,长度n, m:记录开始的index,默认从0开始,表示第一条记录; n:指从第m+1条开始,取n条;*/ select * from emp limit 0,5; select * from emp limit 5; select ename,sal from emp order by sal desc limit 0,5; select ename,sal from emp order by sal desc limit 5; select ename,sal from emp order by sal desc limit 2,7;

    MySQL存储引擎简介

    什么是存储引擎?

    存储引擎是通过采用不同的技术将数据存储在文件或内存中,不同的技术有不同的存储机制,其功能和能力也不同,通过选择不同的技术,可以获得特殊的速度或功能,从而提高应用的性能,存储引擎是MySQL特有的

    常用的存储引擎

    MyIsam

    节省数据库空间,当数据读远大于修改时,可以使用该存储引擎

    InnoDB

    支持事务,如果数据修改较多时,可以使用该存储引擎

    Memory

    存储在内存中,速度快,如果存储非永久性数据时,可以使用该存储引擎

     

    show engines; create table table_name( no int)engine=myisam; alter table table_name engine=innodb; show create table emp;

    事务transaction

    什么是事务

    通常一个事务对应一个完整的业务,例如银行转账,事务可以保证多个操作原子性,要么全部成功要么全部失败

    1001的账户向1002的账户进行转账500元的操作,此时将会执行两条SQL语句

    update t_bank set money=500 where account=1001; update t_bank set money=2500 where account=1002;

    如果上面的sql语句第一条执行成功了,但是由于某些原因第二条sql语句执行失败了,此时账户1001上的金额变成了500,而账户1002上的金额是2000,这样就不正确了。 为了能够正常的执行业务,上面两条sql语句要么全部执行成功,要么全部执行失败,因为他们是最小的业务单元,不能再进行拆分了。

    当一条sql语句执行结束后,并不会立即修改数据库表中的数据,而是在内存中记录一下,第二条sql语句执行成功后,才会修改数据库表中的数据,如果第二条sql语句执行失败了,则将清空内存中的记录,此时并不会修改数据库表中的数据,要实现这样的功能,就必须使用事务来完成。

    事务具有四个特征

    原子性:

    事务是最小单元,不可再分;

    一致性:

    事务要求所有的DML语句操作的时候,必须保证同时成功或同时失败;

    隔离性:

    一个事务不会影响其他事务的执行

    持久性:

    在事务完成之后,该事务对数据库所作的更改将持久地保存在数据库中,并不会被回滚;

    MySQL事务的提交和回滚

    MySQL中默认情况下,事务是自动提交的,当执行一条DML语句时,就开启并且自动提交了事务。可以通过下面的语句查看事务是否是自动提交的:

    show variables like '%commit%';

    如果想要关闭MySQL事务的自动提交,可以使用下面语句手动开启事务:

    create table t_bank( account int(10) primary key, money int(15) ); insert into t_bank values (1001,1000),(1002,2000); select * from t_bank; start transaction; update t_bank set money=500 where account=1001; update t_bank set money=2500 where account=1002; # 此时事务将会回滚,清空内存中的记录,不会修改数据库中的字段值 rollback; # 提交事务 commit;

    事务的隔离级别

    read uncommitted读未提交

    事务A和事务B,事务A未提交的数据,事务B可以读取,这里读取到的数据叫做“脏数据”,该级别最低,一般只是理论上存在,数据库的默认隔离级别都高于该级别。

    read committed读已提交

    事务A和事务B,事务A提交的数据,事务B才可以读取到,换句话说:对方事务提交之后的数据,当前事务才可读取到,可以避免读取脏数据,但是改级别会有不可重复读的问题,事务B读取一条数据,当事务A修改这条数据并提交后,事务B再读取这条数据时,数据发生了变化,即事务B每次读取的数据有可能不一致,这种情况叫做“不可重复读".

    repeteable read重复读

    MySQL默认的隔离级别是重复读,该级别可以达到”重复读“的效果,但是会有”幻读“的问题,即事务A 读取数据,此时事务B修改了这条数据,但是事务A读取的还是之前的旧数据,这样就出现了幻读。

    serializable 串行化

    事务A和事务B,事务A在操作数据库表中数据的时候,事务B只能排队等待,这样保证了同一个时间点上只有一个事务操作数据库,该级别可以解决“幻读”的问题。但是这种级别一般很少使用,因为吞吐量太低,用户体验不好。

    MySQL索引和视图

    索引的作用

    索引相当于一本字典目录,能够提高数据库的查询效率,表中每一个字段都可添加索引。主键会自动添加索引,在查询时,如果能通过主键查询的尽量使用主键查询,效率高。 MySQL数据库表中的检索方式有两种:

    全表扫描(效率低) 例如:select * from emp where ename = ‘KING';如果ename字段没有添加索引的话,就会发生全表扫描。通过索引检索

    什么情况下适合添加索引

    该字段数据量庞大;该字段很少的DML操作(由于索引也需要维护,DML操作多的话,也影响检索效率);该字段经常出现在where条件中;

    注意:实际开发中会根据项目需求等综合因素来做调整,添加索引并不能保证一定能够提升检索效率,索引添加不当也有可能会导致效率降低。

    create index 索引名 on 表名 (列名); create index dept_dname_index on dept(dname); # 查看索引 show index from 表名; show index from dept; # 删除索引 drop index 索引名 on 表名; drop index dept_dname_index on dept; /*视图 视图其实就是一个查询结果,视图的作用可以隐藏表的实现细节*/ create view 视图名称 as 查询语句; create view e_info as select empno,ename,sal from emp; # 使用视图 select * from e_info; # 修改视图 alter view 视图名称 as 查询语句 alter view e_info as select ename,job from emp; # 删除视图 drop view if exists 视图名称; drop view if exists e_info;

    练习

    use monkey1024; select deptno,max(sal) as maxsal from emp group by deptno; select e.ename, t.deptno,t.maxsal from emp e join (select deptno,max(sal) as maxsal from emp group by deptno) t on e.deptno=t.deptno where t.maxsal = e.sal; select deptno,avg(sal) as avgSal from emp group by deptno; select e.ename,t.deptno,e.sal from emp e join (select deptno,avg(sal) as avgSal from emp group by deptno) t on e.deptno=t.deptno where e.sal>t.avgSal; select deptno,avg(sal) as avgSal from emp group by deptno; select t.deptno,t.avgSal,s.grade from salgrade s join (select deptno,avg(sal) as avgSal from emp group by deptno) t on t.avgSal between s.losal and s.hisal; select ename,sal from emp order by sal desc limit 0,1; select deptno,avg(sal) from emp group by deptno; select max(t.avgSal) as maxSal from (select deptno,avg(sal) as avgSal from emp group by deptno) t; select deptno,avg(sal) as avgSal from emp group by deptno having avgSal = (select max(t.avgSal) as maxSal from (select deptno,avg(sal) as avgSal from emp group by deptno ) t); select deptno,avg(sal) as avgSal from emp group by deptno order by avgSal desc limit 0,1; select d.dname, t.deptno,t.avgSal from dept d join (select deptno,avg(sal) as avgSal from emp group by deptno order by avgSal desc limit 0,1) t on d.deptno=t.deptno; select deptno,avg(sal) as avgSal from emp group by deptno; select distinct mgr from emp where mgr is not null; select max(sal) as maxSal from emp where empno not in(select distinct mgr from emp where mgr is not null); select e.ename from emp e join (select distinct (mgr) as mgr from emp where mgr is not null) t on e.empno =t.mgr where e.sal>(select max(sal) as maxSal from emp where empno not in (select distinct (mgr) from emp where mgr is not null)); select e.empno,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal; select t.grade,count(t.empno) from (select e.empno,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal) t group by t.grade; select a.empno,a.ename,a.hiredate from emp a join emp b on a.mgr = b.empno where a.hiredate < b.hiredate; select count(e.empno),e.deptno from emp e group by e.deptno having count(e.empno)>=5; select d.dname from dept d join (select count(e.empno),e.deptno from emp e group by e.deptno having count(e.empno)>=5) t on d.deptno=t.deptno; select job,min(sal) as minSal from emp group by job having min(sal)>1500; select job,min(sal) as minSal,count(*) as total from emp group by job having min (sal)>1500; select deptno from dept where dname='salse'; select e.ename from emp e where e.deptno=(select deptno from dept where dname='sales'); select d.dname,count(e.ename) as total,sum(e.sal) as totalSal from emp e right join dept d on e.deptno=d.deptno group by d.dname; select d.dname,count(e.ename) as total,sum(e.sal) as totalSal from emp e right join dept d on e.deptno=d.deptno where d.dname like '%s%' group by d.dname;

    面试题

    有3个表S(学生表),C(课程表),SC(学生选课表) S(SNO,SNAME)代表(学号,姓名) C(CNO,CNAME,CTEACHER)代表(课号,课名,教师) SC(SNO,CNO,SCGRADE)代表(学号,课号,成绩) 问题:

    找出没选过“黎明”老师的所有学生姓名。列出2门以上(含2门)不及格学生姓名及平均成绩。即学过1号课程又学过2号课所有学生的姓名。

    初始化数据:

    drop table if exists sc; create table sc( sno varchar(200), cno varchar(200), scgrade varchar(200)) default charset=utf8; drop table if exists c; create table c( cno varchar(200), cname varchar(200), cteacher varchar(200)) default charset=utf8; drop table if exists s; create table s( sno varchar(200), sname varchar(200)) default charset=utf8; desc sc; insert into c (cno,cname,cteacher) values ('1','语文','张'); insert into c (cno,cname,cteacher) values ('2','政治','王'); insert into c (cno,cname,cteacher) values ('3','英语','李'); insert into c (cno,cname,cteacher) values ('4','数学','赵'); insert into c (cno,cname,cteacher) values ('5','物理','黎明'); insert into s (sno,sname) values ('1','学生1'); insert into s (sno,sname) values ('2','学生2'); insert into s (sno,sname) values ('3','学生3'); insert into s (sno,sname) values ('4','学生4'); insert into sc (sno,cno,scgrade) values ('1','1','40'); INSERT INTO sc (sno,cno,scgrade) VALUES ( '1', '2', '30'); INSERT INTO sc (sno,cno,scgrade) VALUES ( '1', '3', '20'); INSERT INTO sc (sno,cno,scgrade) VALUES ( '1', '4', '80'); INSERT INTO sc (sno,cno,scgrade) VALUES ( '1', '5', '60'); INSERT INTO sc (sno,cno,scgrade) VALUES ( '2', '1', '60'); INSERT INTO sc (sno,cno,scgrade) VALUES ( '2', '2', '60'); INSERT INTO sc (sno,cno,scgrade) VALUES ( '2', '3', '60'); INSERT INTO sc (sno,cno,scgrade) VALUES ( '2', '4', '60'); INSERT INTO sc (sno,cno,scgrade) VALUES ( '2', '5', '40'); INSERT INTO sc (sno,cno,scgrade) VALUES ( '3', '1', '60'); INSERT INTO sc (sno,cno,scgrade) VALUES ( '3', '3', '80'); select * from s; select cno from c where cteacher='黎明'; select sno from sc where CNO='5'; select sno,sname from s where sno not in (select sno from sc where cno=(select cno from c where cteacher='黎明')); select sno from sc where scgrade<60 group by sno having count(*)>=2; select t2.sn,avg(t1.scgrade) as avgScgrade from sc t1 join (select sno from sc where scgrade<60 group by sno having count(*)>=2) t2 on t1.sno=t2.sno group by t2.sno; select s.sname from s join (select t1.sno from (select sno from sc where cno=1) t1 join (select sno from sc where cno=2) t2 on t1.sno=t2.sno) t3 on s.sno=t3.sno;

     

     

     

     

    最新回复(0)