MySQL学习总结

####在windows命令行连接数据库

mysql -uroot -p;

####退出数据库

exit;

####

1.查看所有数据库

show databases;

2.创建数据库

create database 数据库名;

create database db2;
3.查看数据库详情
show create database db1;
4.创建数据库指定字符集
格式:    create database 数据库名 character set utf8/gbk;
    create database db3 character set gbk;
    show create database db3;//验证一下
5.删除数据库
-格式:drop database 数据库名;
    drop database db3;
6.使用数据库
-格式:use 数据库名;
    use db1;

###表相关SQL
1.创建表
格式:creat table 表名(字段1名 字段1类型,字段2名 字段2类型);
    create table person(name varchar(10),age int);
    create table student(id int, name varchar(10), chinese int, math int, english int);
2.查看所有表
格式:show tables;
3.查看表详情
格式:show create table 表名;
     show create table student;
4.创建表指定引擎和字符集
格式:create table 表名(字段1名 字段1类型,字段2名 字段2类型)engine=myisam/innodb charset=utf8/gbk;
create table t1(name varchar(10),age int)engine=myisam charset=gbk;
###表相关SQL(续)
1.查看表字段
格式:desc 表名;
    desc student;
2.删除表
格式:drop table 表名;
    drop table student;
3.修改表名
格式:rename table 原名 to 新名;
    rename table t1 to t2;
4.修改引擎和字符集
格式:alter table 表名 engine=myisam/innodb charset=utf8/gbk;
alter table t1 engine=innodb charset=utf8;
5.添加表字段
格式:alter table 表名 add 字段名 字段类型;//最后
格式:alter table 表名 add 字段名 字段类型 first;//最前面
格式:alter table 表名 add 字段名 字段类型 after xxx;//在xxx后面
    create table emp(name varchar(10));//创建
    alter table emp add age int;//最后
    alter table emp add id int first;
    alter table emp add gender varchar(5) after name;
6.删除字段
格式:alter table 表名 drop 字段名;
    alter table emp drop gender;
7.修改表字段名和类型
格式:alter table 表名 change 原字段名 新名 新类型;
    alter table emp change age gender varchar(10);
8.修改字段类型和位置
格式:alter table 表名 modify 字段名 新类型 first/after xxx;
    alter table emp modify gender varchar(5) first;
    alter table emp modify gender varchar(5) after id;
###数据相关SQL
    create database mydb1 character set utf8;
    use mydb1;
    create table emp(id int,name varchar(10),age int)engine=innodb charset=utf8;
1.插入数据(增)
全表插入格式:insert into 表名 values(值1,值2,值3);
指定字段插入格式:insert into 表名(字段1名,字段2名) value(值1,值2);
    insert into emp(id,name)values(2,'Jerry');
中文问题:
    insert into emp values(3,'刘备',30);
    如果以上代码报错执行以下命令
    set names gbk;
批量插入:
    insert into emp values(4,'关羽',25),(5,'张飞',18);
    insert into emp (name) values('悟空'),('八戒'),('沙僧');
2.查询数据
格式:select 字段信息 from 表名 where 条件;
    select name,age from emp;
    select name,age from emp where age<20;
    select * from emp;
3.修改数据
格式:update 表名 set 字段名=xxx where 条件;
    update emp set age=500 where name='悟空';
    update emp set age=10 where id=2;
4.删除数据
格式:delete from 表名 where 条件;
        delete from emp where age<20;
        delete from emp where age is null;
        delete from emp;//清空表
###主键约束
格式:create table t1 (id int primary key,name varchar(10));
    insert into t1 values(1,'AAA');//成功
    insert into t1 values(1,'BBB');//报错 不能重复
    insert into t1 values(null,'CCC');//报错 不能为null
###主键约束+自增
格式: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(3,'ccc');//3
    insert into t2 values(10,'ddd');//10
    insert into t2 values(null,'eee');//11
    delete from t2 where id>=10;
    insert into t2 values(null,'fff');//12
###注释
格式:create table t3(id int primary key auto_increment comment '这是主键',name varchar(10) comment '这是名字');
###` `的作用
用于修饰表名和字段名,可以省略
格式:create table `t4`(`id` int,`name` varchar(10));
###冗余

案例:
    集团总部下的教学研发部下的Java教研部下的张老师工资200年龄18性别男
    集团总部下的市场部下的市场A部下的小明工资5000年龄25性别男
-创建员工表和部门表
create table emp(id int primary key auto_increment,name varchar(10),age int,sal int, gender varchar(10),dept_id int);
create table dept(id int primary key auto_increment,name varchar(10),parent_id int);
-插入数据
insert into dept values(null,'集团总部',null),(null,'教学部',null),(null,'Java教研部',2),(null,'市场部',1),(null,'市场部',4);
insert into emp values(null,'张老师',18,200,'男',3),(null,'小明',25,5000,'男',5);


-创建商品表item和分类表category保存以下数据
1.保存家电分类下电视机分类下的小米电视 价格(price)1888 库存(num)200
2.办公用品分类下的打印机分类下的惠普打印机,价格1500库存100
-创建表
create table item(id int primary key auto_increment,name varchar(10),price int,num int,category_id int);
create table category(id int primary key auto_increment,name varchar(10),parent_id int);
-插入数据:
insert into category value(null,'家电',null),(null,'电视机',1),(null,'办公用品',null),(null,'打印机',3);
insert into item values (null,'小米电视',1888,200,2),(null,'惠普打印机',1500,100,4);


###事务
-事务相关的指令:
1.开启事务: begin;
2.提交事务:commit;
3,回滚:rollback;
-验证转账流程:
    create table user (id int primary key auto_increment,name varchar(10),money int,status varchar(5));
    insert into user values(null,'超人',50,'冻结'),(null,'蝙蝠侠',5000,'正常'),(null,'灭霸',20,'正常');
-转账的SQL:
    update user set money=money-2000 where id=2 and status='正常';
    update user set money=money+2000 where id=1 and status='正常';
有事务保护的情况下 回滚流程:
    1.开启事务:begin;
    2.蝙蝠侠-2000:update user set money=money-2000 where id=2 and status='正常';
    3.此时在当前终端查询数据时,数据已经改变(因为查询到的是内存中的改动),开启另外一个终端查询数据发现数据是没有改变的(因为新的终端查询到的是磁盘的数据)
    4.超人+2000:update user set money=money+2000 where id=1 and status='正常';    
    5.此时从执行结果中发现一条成功一条失败,应该执行回滚操作:rollback;
有事务保护的情况下 提交流程:
1.开启事务:begin;
2.蝙蝠侠-2000:update user set money=money-2000 where id=2 and status='正常';
3.此时仍然是在内存中改动 磁盘数据没有发生改变
4.灭霸+2000:update user set money=money+2000 where id=3 and status='正常';
5.此时两次改动都是在内存中改完,发现两次全部成功,所以执行提交 :commit;
-保存回滚点:
    -begin;
    -update user set money=1 where id=2;
    -savepoint s1;
    -update user set money=2 where id=2;
    -savepoint s2;
    -update user set money=3 where id=2;
    -rollback to s2;
-事务的ACID特性(重点)
    保证事务正确执行的四大基本要素
1.Atomicity原子性:最小不可拆分 保证全部执行成功或全部执行失败
2.Consistency一致性:从一个一致状态到另一个一致状态
3.Isolation隔离性:多个事务之间互相隔离互不影响
4.Durability持久性:当事务提交后数据保存到磁盘中持久生效


###SQL分类
####DDL Data Definition Language数据定义语言
-truncate table 表名;
    删除表并创建新表     让自增数值清零
-包括:create drop alter truncate
-不支持事务
####DML Data Manipulation Language数据操作语言
-包括:insert update delete select
-支持事务
####DQL Data Query Language 数据查询语言
-只包括:select;
###TCL Transanction Control Language 事务控制语言
-包括:begin,commit,rollback,savepoint xxx,rollback to xxx;
####DCL Data Control Language 数据控制语言
-负责分配用户权限相关的SQL


###数据类型
1.整数: int(m)和bibint(m) m代表的是显示长度,需要结合zerofill使用
    create table t_int(id int,age int(10) zerofill);
    insert into t_int values(1,18);
    select * from t_int;
2.浮点数:double(m,d) m代表的是总长度 d代表小数长度,超高精度的浮点数decimal(m,d);
    25.234         m=5     d=3
3.字符串:
-char(m) 固定长度 最大长度255 好处:执行效率略高
-varchar(m) 可变长度 好处节省空间 最大长度65535(但是超过233建议使用text)
-text(m) 可变长度 最大长度65535
4.日期:
-date:保存年月日
-time:保存时分秒
-datetime:保存年月日时分秒,默认值为null,最大9999-12-31
-timestamp(时间戳):保存年月日时分秒,默认值为当前系统时间,最大值2038-1-19
    create table t_date(t1 date,t2 time,t3 datetime,t4 timestamp);
    insert into t_date values('2019-6-20',null,null,null);
    insert into t_date values(null,'16:46:35','2019-06-20 16:30:30',null);
###导入*.sql文件
-windows:source d:/
-linux:source /home/soft01/桌面/tables.sql


###is null 和 is not null
从员工表中查询 没有上级领导的员工

select * from emp where leader is null;

###别名
select ename as '姓名' from emp;
select ename '姓名' from emp;
select ename 姓名 from emp;


###比较运算符>,<,>=,<=,=,!=和<>
select distinct job from emp;
select distinct deptno from emp;
1.查询10号部门中工资低于2000的员工信息
select * from emp where deptno=10 and sal<2000;
 select * from emp where deptno=30 or sal>3000\G;


####模糊查询 like
-%代表0或多个未知字符
-_代表单个未知
举例:第一个字符是x   x%;
    最后一个字符是y  %y
    包含  %x%
    倒数第二个字符是x %x_
    x开头y结尾 x%y
    第二个字符是x 倒数第三个字符是y _x%y__
1.select ename from emp where ename like 'j%';
2.select ename,sal from emp where ename like '_l%';
 select title from t_item where title like '%记事本%';
select ename,sal,job from emp where job like '%an%' and sal>1500;
select ename from emp where ename not like '%a%';//不包含a
select ename,sal from emp where sal between 2000 and 3000;
select title,price from t_item where price between 50 and 1000;
select ename,sal from emp where sal not between 1000 and 2000;
select ename,sal from emp where sal < 1000 or sal>2000;


###in
select * from emp where sal in(800,1300,1500);
select * from t_item where category_id in(238,917)\G;
select title,price from t_item where title like '%得力%' and price between 50 and 200;
select ename,sal,mgr from emp where mgr is not null and sal<2000;


####排序 order by
格式:order by 字段名 asc     asc:升序 desc:降序
    order by 写在where条件的后面
select ename,sal from emp where sal <3000 order by sal desc;
select ename,sal from emp where deptno=10 order by sal;
select ename,sal,comm from emp where comm>0 order by comm desc;
select title,price from t_item where price<100 order by price;
多字段排序
order by 字段1 asc/desc,字段2 asc/desc


####分页查询limit 跳过的条数,请求的条数
-请求第一页的10条数据 limit 0,10
-请求第三页的10条数据 limit 20,10
-请求第八页的5条数据 limit 35,5
-公式 limit(页数-1)*数量,数量
-请求第四页的7条数据 limit 21,7
1.select ename,sal from emp order by sal desc limit 6,3;
2.select * from emp order by sal desc limit 0,3;
3.select title,price from t_item order by price limit 10,5;
4.select * from emp where deptno=30 order by sal desc limit 0,1;


###数值计算+ - * / %
1.select ename,sal,sal*5 年终奖 from emp;
2.select title 商品标题,price 单价,num 库存,price*num 总价值 from t_item\G;
3.select ename,sal+5 加薪后 from emp;

###日期相关SQL
1.获取系统时间 now()
create table t_date(name varchar(10),birthday datetime);
 insert into t_date values('刘德华',now());
2.获取当前的年月日和当前的时分秒 curdate(),curtime()
 select curdate(),curtime();
3.select date(now());
  select time(now());
  select created_time from t_item;
  select date(created_time) from t_item;
4.提取时间分量
select extract(year from now());
select extract(month from now());
select extract(day from now());
select extract(hour from now());
select extract(minute from now());
select extract(second from now());
查询员工入职年份
select extract(year from hiredate)from emp;
5.日期格式化date_format(时间,格式);
格式规则:
%Y 四位年 2019 %y 两位年 19
%m 两位月 06   %c 一位月 6
%d 日
%H 24小时     %h 12小时
%i 分钟
%s 秒
select date_format(now(),'%Y年%m月%d号 %H点%i分%s秒');
输出:2019年06月21号 15点32分12秒
6.反向格式化 str_to_date(时间,格式)
    21.06.2019 15点36分20秒 转回 2019-06-21 15:36:20
    select str_to_date('21.06.2019 15点36分20秒','%d.%m.%Y %H点%i分%s秒');


###ifnull(x,y)
-age=ifnull(x,y) 如果x值为null则age=y否则age=x
-练习:修改奖金为null的值为0 不为null则不变
update emp set comm=ifnull(comm,0);
###聚合函数
-对查询的多条数据进行统计查询:平均值,最大值,最小值,求和,计数
1.平均值avg(字段名)
    查询员工的平均工资
    select avg(sal) from emp;
2.最大值max(字段名)
    查询20号部门的最高工资
    select max(sal) from emp where deptno=20;
3.最小值min(字段名)
    select min(sal) from emp where ename like '%a%';
4.求和sum(字段名)
    -查询10号部门工资总和
    select sum(sal) from emp where deptno=10;
5.计数count(字符段)
查询工资高于2000的员工数量
select count(*) from emp where sal>2000;
查询20号部门的平均工资,最高工资,最低工资,工资总和,员工数量
select avg(sal),max(sal),min(sal),sum(sal),count(*) from emp where deptno=20;
####字符串相关
1.字符串拼接concat(s1,s2); s1s2
    select concat('aa','bb');
    查询每个员工的姓名和工资 要求工资以元为单位
    select ename,concat(sal,'元') from emp;
2.获取字符串的长度 char_length(str);
    select char_length('abc');
    -查询每个员工的姓名和名字长度
    select ename,char_length(ename) from emp;
3.获取字符串出现的位置 instr(str,substr);
    select instr('abcdefg','d');
4.转大写和转小写
    select upper('abc'),lower('NBA');
5.截取字符串
      -左边截取 select left('abcdefg',2);
      -右边截取 select right('abcdefg',2);
      -自由截取对象 select substring('abcdefg',2,3);3代表长度
6.去空白 trim()
    select trim('    a      b    ');//只能去两端
7.重复repeat()
    select repeat('ab',5);//重复五次    
8.替换replace()
    select replace('abcdef abc','b','m');
9.反转reverse()
    select reverse('abc');     
###数学相关
-向下取整 floor(num);
    select floor(3.93);     
-四舍五入 round(num);
      select round(3.93);
-四舍五入
    select round(23.879,2);
-非四舍五入
    truncate(num,m) m代表小数位数
      select truncate(23.879,2);
-随机数 rand() 获得0-1的随机数
    select rand();
####分组查询
1.查询每个部门的平均工资
    select avg(sal) from emp group by deptno;
    select deptno,avg(sal) from emp group by deptno;    
2.查询每种工作的最高工资
    select max(sal) from emp group by job;
    select job,max(sal) from emp group by job;
3.查询每个部门的人数
    select count(*) from emp group by deptno;
    select deptno,count(*) from emp group by deptno;    
4.查询每个部门工资高于1500的人数
    select deptno,count(*) from emp where sal>1500 group by deptno;
5.查询每个主管mgr的手下人数
    select mgr,count(*) from emp group by mgr;    
      select mgr,count(*) from emp where mgr is not null group by mgr;    
####多字段分组
    group by 字段1名,字段2名
1.查询每个部门下面每种职业的平均工资
    select deptno,job,avg(sal) from emp group by deptno,job;
-格式: select......from 表名 where......group by ...... order by.......limit .......;      
练习:1.查询emp表中每个部门的编号,人数,工资总和,根据人数进行升序排序,如果人数一致根据工资总和降序排序.
    select deptno,count(*) c,sum(sal) s from emp group by deptno order by count(*),sum(sal) desc;      
     select deptno,count(*) c,sum(sal) s from emp group by deptno order by c,s desc;
    2.查询工资在1000到3000之间的员工信息,每个部门的编号,平均工资,最低工资,最高工资,根据平均工资进行升序排序
      select deptno,avg(sal) ,min(sal),max(sal) from emp where sal between 1000 and 3000 group by deptno order by avg(sal);
      3.查询有上级领导的员工,每个职业的人数,
    select job,count(*) c,sum (sal),avg(sal) a from emp where mgr is not null group by c desc,a;
#####having
-where 后面只能写普通字段的条件
-having 后面写聚合函数的条件,having和分组查询结合使用
-各个关键字的顺序:
select ......from 表名 where......group by ....having .....order by ......limit.....;
1.查询每个部门的平均工资要求平均工资大于2000
select deptno,avg(sal) a from emp where avg(sal)>2000 group by deptno; //错误
select deptno,avg(dal) a from emp group  by deptno  having a>2000;
2.select category_id,avg(price) a from t_item group by category_id having a>2000;
3.select deptno,count(*),avg(sal) a from emp group by deptno having a>2000 order by a desc;
4.select category_id,avg(price) from t_item group by category_id having category_id in(238,917);
  select category_id,avg(price) from t_item where category_id in(238,917) group by category_id ;
5.select deptno,sum(sal) s,avg(sal) a from emp where sal between 1000 and 3000 group by deptno having a>=2000 order by a;    
6.select extract(year from hiredate) y,count(*) from emp group by y;     
7.select deptno,avg(sal) a from emp group by deptno order by a desc limit 0,1;  
####子查询(嵌套查询)
1.select * from emp where sal>(select avg(sal) from emp);//查询工资高于平均工资的员工信息
2.select * from emp where sal=(select max(sal) from emp);//查询员工表中工资最高的员工信息
3.select * from emp where sal>(select max(sal) from emp where deptno=20);//查询工资高于20号部门最高工资的员工信息
4.select * from emp where ename!='jones' and job=(select job from emp where ename='jones');//查询和jones相同工作的其它员工信息
5.select min(sal) from emp;
select deptno from emp where sal=(select min(sal) from emp);
select * from emp where deptno=(第一坨) and sal !=(第二坨);//
6.select * from emp where hiredate=(select max(hiredate) from emp);//查询最后入职的员工信息
7.select * from dept where deptno=(select deptno from emp where ename ='king');//查询king的部门信息(需要用到dept表)
8.select * from dept where deptno in (select distinct deptno from emp where deptno!=40);//查询员工表中出现过的部门信息
9.select avg(sal) a from emp group by deptno order by a desc limit 0,1;//最高平均工资
  select deptno from emp group by deptno having avg(sal)=(select avg(sal) a from emp group by deptno order by a desc limit 0,1);//最高平均工资的部门
  select * from dept where deptno in (上面一坨);//查询平均工资最高的部门信息(难度最高,需要考虑并列第一的问题)
####子查询可以写的位置
1.写在where 和having后面,当作查询条件的值
2.写在创建表的时候,把查询结果保存到新的表中
  create table emp_10 as (select * from emp where deptno=10);
3.写在from后面 **一定要有别名**
    select * from emp where deptno=10;
    select ename from (select * from emp where deptno=10) t;
####关联查询
-同时用到多张表的查询方式称为关联查询
-关联查询必须写关联关系,如果不写则会得到两张表的乘积,这个乘积称为笛卡尔积,这是一个错误的查询结果,切记工作中不要出现
1.查询每一个员工的姓名和对应的部门名
    select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;
####关联查询的查询方式之 等值连接和内连接
1.等值连接:
    select * from A,B where A.x=B.x and A.y>2000;
2.内连接:
    select * from A [?inner] join B on A.x=B.x where A.y>2000;
    查询每一个员工的姓名和对应的部门名
    select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno;
    -查询工资高于2000的每个员工的姓名和对应的部门地点
    select e.ename,e.sal,d.loc from emp e join dept d on e.deptno=d.deptno where e.sal>2000;
    -查询在new york工作的员工姓名和工资
    select e.ename,e.sal from emp e join dept d on e.deptno=d.deptno where d.loc='new york';
    -查询james的部门名称和地点
    select d.dname,d.loc
    from emp e join dept d
    on e.deptno=d.deptno
    where e.ename='james';
####关联查询的查询方式之外连接
-等值连接和内连接查询的是两张表的交集数据
-外连接查询的是一张表的全部数据和另外一张表的交集数据
-格式:
    select * from A left/right join B on A.x=B.x where A.y<2000;
    -查询所有的部门名和对应的员工姓名
    select d.dname,e.ename
    from emp e right join dept d
    on e.deptno=d.deptno;
####练习
1.每个部门的人数,根据人数降序排序
select deptno,count(*) c from emp group by deptno order by c desc;
2.每个部门中,每个主管的手下人数
select deptno,mgr,count(*) from emp where mgr is not null group by deptno,mgr;
3.每种工作的平均人数
select job,avg(sal) from emp group by job;
4.每年的入职人数
select extract(year from hiredate) y,count(*) from emp group by y;
5.拿最低工资的员工信息
select * from emp where sal=(select min(sal) from emp );
6.不考虑40号部门:select deptno,count(*) from emp group by deptno having count (*) <=3;
            select * from dept where deptno in(select deptno,count(*) from emp group by deptno having count (*) <=3);
考虑40号部门:    select d.*
             from emp e right join dept d
             on e.deptno=d.deptno//靠deptno连接
        group by d.deptno
        having count(e.ename)<=3;
7.只有一个下属的主管信息
select * from emp where mgr in(select mgr from emp group by mgr having count(*)=1 and mgr is not null);
8. 每月发工资最多的部门信息
select sum(sal) from emp group by deptno order by sum(sal) desc limit 0,1;//获得最高工资总和
select deptno from emp group by deptno having sum(sal)=(select sum(sal) from emp group by deptno order by sum(sal) desc limit 0,1);//获得部门编号
select * from dept where deptno=(select deptno from emp group by deptno having sum(sal)=(select sum(sal) from emp group by deptno order by sum(sal) desc limit 0,1));//最终结果
9. 下属最多的人,查询其个人信息
select count(*) c from emp group by mgr order by c desc limit 0,1;//获得最多下属数
select mgr from emp group by mgr having count(*)=(select count(*) c from emp group by mgr order by c desc limit 0,1);//获得mgr编号
select * from emp where empno =(select mgr from emp group by mgr having count(*)=(select count(*) c from emp group by mgr order by c desc limit 0,1));//最终结果
10. 拿最高工资员工的同事信息
select max(sal) from emp;//获取最高工资
select deptno from emp where sal =(select max(sal) from emp);//获取最高工资所在部门
select empno from emp where sal =(select max(sal) from emp);//获取获得最高工资人员编号
select * from emp where deptno=(select deptno from emp where sal =(select max(sal) from emp))and empno!=(select empno from emp where sal =(select max(sal) from emp));
11. 和最后入职的员工在同一部门的员工信息 实现流程和第十题一样
select max(hiredate) from emp;
select deptno from emp where hiredate =(select max(hiredate) from emp);
select empno from emp where hiredate=(select max(hiredate) from emp);
select * from emp where deptno=(select deptno from emp where hiredate =(select max(hiredate) from emp))and empno!=(select empno from emp where hiredate=(select max(hiredate) from emp));
12. 查询平均工资高于20号平均工资的部门信息
select avg(sal) from emp group by deptno having deptno=20;//获得20号部门平均工资
select deptno from emp group by deptno having avg(sal)>(select avg(sal) from emp group by deptno having deptno=20);//平均工资高于20号部门的部门
select * from dept where deptno=(select deptno from emp group by deptno having avg(sal)>(select avg(sal) from emp group by deptno having deptno=20));
13. 查询员工信息和员工对应的部门名称
select e.*,d.dname
from emp e join dept d
on e.deptno=d.deptno;
14. 查询员工信息,部门名称,所在城市
select e.*,d.dname,d.loc
from emp e join dept d
on e.deptno=d.deptno;
15. 查询Dallas市所有的员工信息
select e.*
from emp e join dept d
on e.deptno=d.deptno
where d.loc='dallas';
16. 计算每个城市的员工数量
select d.loc,count(empno) 员工数量
from emp e join dept d
on e.deptno=d.deptno
group by d.loc;
17. 查询员工信息和他的主管姓名
//把一张表当两张表
select e.*,m.ename
from emp e  join emp m
on e.mgr=m.empno;
select e.*,m.ename
from emp e left join emp m
on e.mgr=m.empno;//可以得到所有员工,包括课king
18. 员工信息,员工主管名字,部门名
select e.*,m.ename 主管名字,d.dname 部门名
from emp e
join emp m
on e.mgr=m.empno
join dept d
on e.deptno=d.deptno;
19. 员工名和他所在部门名
select e.ename,d.dname
from emp e
join dept d
on e.deptno=d.deptno;
20. 案例:查询emp表中所有员工的姓名以及该员工上级领导的编号,姓名,职位,工资
select e.ename 员工姓名,m.empno,m.ename 领导姓名,m.job,m.sal
from emp e
join emp m
on e.mgr=m.empno;
21. 案例:查询emp表中名字中没有字母'K'的所有员工的编号,姓名,职位以及所在部门的编号,名称,地址
select e.empno,e.ename,e.job,e.deptno,d.dname,d.loc
from emp e
join dept d
on e.deptno=d.deptno
where e.ename not like '%k%';
22. 案例:查询dept表中所有的部门的所有的信息,以及与之关联的emp表中员工的编号,姓名,职位,工资         
select d.*,e.empno,e.ename,e.job,e.sal
from dept d
left join emp e
on d.deptno=e.deptno;
#####关系
1.一对一
2.一对多
3.多对多
####一对一
为了提高数据查询性能,经常将概要信息和详细信息分成两张表,两个表中数据是一对一关系
1.商品表
    create table t_product(
        id int,
        name varchar(30),
        abstract varchar(100),
        price decimal(8,2)
    );
    create table t_product_info(
        id int,
        cpu varchar(20),
        ram varchar(20),
        hdd varchar(20)
    );
2.添加数据
insert into t_product (id,name,abstract,price)
values(1,"P30","Top 1 Mobile",500.00);
insert into t_product_info(id,cpu,ram,hdd)
values(1,"960","6GB RAM","128GB");
3.查询商品概要信息
    select id,name from t_product;
4.查询商品详情信息,两个表连接查询
    select p.id,name,cpu,ram,hdd
    from t_product p
    join t_product_info i
    on p.id=i.id;
###练习
create table t_item(
id int primary key auto increment,
iname varchar(10),
iprice decimal(8,2),
inum int
);
create table t_item_info(
id int primary key auto increment,
time datetime
);
###一对多关系
订单与订单项目构成一对多关系
1.创建表
    create table t_order(
    id int,
    username varchar(50)
);
    create table t_order_item(
    id int,
    oid int,
    product varchar(100),
    price double
);
>oid是外键,关联到t_order 表单的id主键
>一个表中的一个列取值于另外一个表的主键,称为(外键关联关系),逻辑上就是一对多关系
2.插入数据
    insert into t_order(id,username)
    values(1,'范传奇');
    insert into t_order_item(id,oid,product,price)
     values(1,1,'大黄蜂',500);
    insert into t_order_item(id,oid,product,price)
     values(2,1,'擎天柱',1500);
    insert into t_order_item(id,oid,product,price)
     values(3,1,'威震天',2000);
3.查询订单编号为1的完整订单
    select o.id,username,product,price
    from t_order o
    join t_order_item i
    on o.id=i.oid
    where o.id=1;
###练习
    insert into t_order(id,username)
    values(2,'刘国斌');
    insert into t_order_item(id,oid,product,price)
     values(1,2,'纸尿裤',500);
    insert into t_order_item(id,oid,product,price)
     values(2,2,'奶粉',1500);
    insert into t_order_item(id,oid,product,price)
     values(3,2,'婴儿床',2000);
#####多对多关系
1.建表
    create table t_teacher(
    id int,
    name varchar(100)
    );
    create table t_student(
    id int,
    name varchar(100)    
    );
    create table t_teach(
    tid int,
    sid int    
    );
2.插入数据
    insert into t_teacher values(1,'范传奇'),(2,'刘国斌');
    insert into t_student values(1,'莫小贝'),(2,'白展堂'),(3,'吕秀才'),(4,'李大嘴');
    insert into t_teach values(1,1),(1,2),(1,3),(2,2),(2,3),(2,4);
3.查询
>验证多对多的可用性
-范传奇讲授了哪些学生
    select t.id 老师id,t.name teacher,s.name student,s.id 学生id
    from t_teacher t
    join t_teach tt
    on t.id=tt.tid
    join t_student s
    on tt.sid=s.id
    where t.id=1;
>测试任务:添加老师数据 王克晶,教过所有学生,并且查询验证
    insert into t_teacher values(3,'王克晶');
    insert into t_teach values(3,1),(3,2),(3,3),(3,4);
    -- 查询王克晶老师教过的学生
    select t.name 老师,s.name 学生 from t_teacher t join t_teach tt on t.id=tt.tid join t_student s on tt.sid=s.id where t.id=3;
    -- 查询莫小贝的老师有哪些:
    select s.name 学生,t.name 老师 from t_teacher t join t_teach tt on t.id=tt.tid join t_student s on tt.sid=s.id where s.id=1;
>>>学生和课程多对多
   create table t_choose(
    sid int,
    cid int
    );
   create table t_course(
    id int,
    name varchar(10)    
     );
insert into t_course values(1,'Java'),(2,'PHP'),(3,'Python'),(4,'Cpp');
insert into t_choose values(1,1),(1,4),(2,1),(2,3);
select s.name 学生,c.name 课程
from t_student s
join t_choose ch
on s.id=ch.sid
join t_course c
on ch.cid=c.id
where s.id=1;
select c.name 课程,s.name 学生
from t_student s
join t_choose ch
on s.id=ch.sid
join t_course c
on ch.cid=c.id
where c.id=1;
>>>>>>>>>>>>>>建表
create table t_user(id int,name varchar(10));
create table t_user_role(uid int,rid int);
create table t_role(id int,name varchar(10));
create table t_role_function(rid int,fid int);
create table t_function(id int,name varchar(10));
>>>>>>>>>>>>>>添加数据
insert into t_user values(1,'范老'),(2,'王老'),(3,'刘老');
insert into t_user_role values(1,1),(1,2),(2,3);
insert into t_role values(1,'消费者'),(2,'店家'),(3,'店小二'),(4,'管理员');
insert into t_role_function values(1,1),(2,2),(2,3),(3,3),(4,4);
insert into t_function values(1,'购买商品'),(2,'搜索商品'),(3,'上货'),(4,'管理用户');
>>>>>>>>>>>>>>>查询
select u.name user,r.name role,f.name function
from t_user u
join t_user_role ur
on u.id=ur.uid
join t_role r
on ur.rid=r.id
join t_role_function trf
on r.id=trf.rid
join t_function f
on trf.fid=f.id
where u.name='范老';
######view(视图)
利用一个查询语句构建一个虚拟表,如果需要查询就可以通过查询视图获得结果
利用视图可以重用复杂的查询功能,简化二次查询工作
视图不是表,视图中不存储数据,数据是通过内部
1.创建视图
    create view student_course as(
    select s.id student_id,s.name student,c.id course_id,c.name course
    from t_student s
    join t_choose cc
    on s.id=cc.sid
    join t_course c
    on cc.cid=c.id
    );
2.利用视图进行查询
    select student,course from student_course
    where student='莫小贝';
    select student,course from student_course
    where student='白展堂';
3.管理view
-创建create view 视图名 as 查询
-查询全部视图SHOW FULL TABLES WHERE TABLE_TYPE LIKE 'VIEW';
-删除视图 drop view 视图名
-视图可以嵌套使用
####约束
用于限制约定表中的数据完整性
数据库提供了"基础的"完整性,有效性检查.
####主键约束
约束一个列中的值,符合数据库主键规则要求,非空且不能重复(唯一).
如果违反就会报错误!
-primary key
验证主键约束
1.建表
--不添加主键约束
create table t1(id int,name varchar(50));
--添加主键约束
create table t2(id int,name varchar(50),primary key(id));
2.验证
--没有主键的约束时
insert into t1(id,name) values (1,"Tom");
insert into t1(id,name) values(1,"Jerry");
insert into t1(id,name) values(null,"Andy");
--有主键约束的时
insert into t2(id,name) values (1,"Tom");
insert into t2(id,name) values(1,"Jerry");
insert into t2(id,name) values(null,"Andy");
>>>>>主键是字符串
create table t3(id varchar(10),name varchar(10),primary key(id));
insert into t3 values("zhangsan","张三");
insert into t3 values("zhangsan","张叁");
insert into t3 values(null,"张叁");
insert into t3 values("zhangsan","张三"),("zhangsan","张叁"),(null,"张叁");
insert into t3 values("lisi","李四"),(null,"王五");
>>>>验证结果:数据库会检查主键列的规则,主键不能重复,
>>>>有的时候,为提高数据插入性能,故意不设置主键约束,比如日志表(大多数情况下,表都使用主键约束)
######非空约束
验证表中的列值,不能添加空值.
在设计表的时候为列添加非空约束,则在插入更改数据时候,一旦数据为null则报错,禁止添加和修改.
-not null
1.建表
    drop table t3;
    create table t3(
    id int primary key,
    name varchar(50) not null,
    nick varchar(50)
    );
2.测试
    insert into t3(id,name,nick) values(1,'刘国斌',null);
    insert into t3(id,name,nick) values(2,'范传奇','范老师');
-----错误插入
    insert into t3(id,name,nick) values(3,null,"fan");
    insert into t3(id,name,nick) values(4,"李白","诗仙"),(5,null,"诗圣"),(6,null,"书圣");
####唯一约束
限定一个列的值,不能重复,保持唯一.除了主键以外的其他列保持唯一
1.建表    
    drop table t4;
    create table t4(
    id int primary key,
    name varchar(50) not null,
    email varchar(100) unique
    );

2.验证:插入重复的邮箱地址时会出现错误!
insert into t4 values(1,'zhangsan','[email protected]');
insert into t4 values(2,'lisi','[email protected]');
#####默认约束
为列添加默认值
    default'男'
1.建表
    create table t5(
    id int primary key,
    name varchar(50) not null,
    sex varchar(10) default'男'    
    );
2.验证
insert into t5(id,name) values(1,'范传奇');
insert into t5(id,name,sex) values(2,'刘国斌','女');
select * from t5;
#####外键约束
语法:
-FOREIGN KEY(外键列) REFERENCES 主键表(主键列)
1.建表
--主键表
create table user (
id int primary key,
name varchar(50) not null
);
--外键表
create table trad(
id int primary key,
uid int,
money double,
FOREIGN KEY(uid) REFERENCES user(id)
);
>>>>>uid 列的值必须是user id 的值!
insert into user values(1,'张三'),(2,'李四'),(3,'王五');
insert into trad values(1,1,99.99);
insert into trad values(2,4,34.34);
delete from  user where id=1;//删除错误
delete from trad where id=1;
delete from  user where id=1;//可以删除
外键特点:
>>>>添加外键约束
####索引
数据库提供的一种高效查询算法!可以提高数据查询效率!
索引可以大大加快大数据量的查询效率!
语法:
-create index 索引名 on 表名(字段名(?长度));
1.创建索引
    create index idx_user_name on user(name);//在user中

2.使用
    select id,name from user where name='Tom';

数据量常见索引算法:B+树(B plus Tree)(波音公司)
B+树原理:
1.数据库数据是连续存储到磁盘上的数据块,每个对象一个数据块,每个数据块读写需要几个ms.如果是海量数据查询的时候
就需要很多次读写每个数据块,累计时间很长!
2.B+树 建立两层索引数据块,索引中包含数据的范围,只需要读取两层索引块两次,就能确定目标数据的位置,查询到结果.大大减少磁盘IO次数,
提高查询性能!
3.在最终数据块上还有一次IO,一共3次磁盘块IO就可以读取到数据,其性能非常好!
#####事务(交易)
是指保证一个业务过程的最小单位可靠执行,避免出现半截情况,要么都执行,要么都不执行.
业务过程:多个动作合成的一个完整不可再分的过程.
>>>>4个特点:(ACID)
常见的数据库都(自动)支持ACID
1.利用数据库提供的事务指令就可以实现ACID
2.在事务开启时候,执行begin(开始)
3.后续的SQL,都作为一组"原子"业务操作"
4.在事务结束时候,使用commit提交事务,确认事务完成
5.如果业务失败,使用rollback回滚
###JDBC
Java 数据库连接:将Java程序连接到数据库的桥梁.
1.Sun(Java)设计了JDBC,API底层封装了Socket,简化数据库的访问.
2.JDBC为数据库提供了统一访问接口.
使用JDBC
1.利用maven导入数据库驱动
    1)创建Maven项目
    2)找到JDBC驱动程序的坐标
    3)将JDBC坐标添加到pom.xml
2.注册数据库驱动:告诉JDBC如何找到数据库驱动的实现类
    1)最新三数据库驱动,会自动注册.
    2)建议手动注册:
        <1>Class.forName("数据库驱动程序类名")
        <2>Class.forName("com.mysql.jdbc.Driver")
3.建立与数据库之间的连接
    String usr="root";
    String pwd="";
    //          jdbc:mysql://数据库IP:3306/数据库名
    String url="jdbc:mysql://localhost:3306/db6";//3306是mysql固定端口
    Connection conn=DriverManager.getConnection(url,usr,pwd);
4.创建Statement(语句)对象:用于执行SQL(操作数据库)
    1)DDL create drop 等 一般使用execute执行
    2)DML insert delete update 一般使用 executeUpdate 执行
    3)DQL select 一般使用executeQuery
5.关闭连接
    conn.close();    
>>>>MySQL JDBC 连接常用参数,写在连接url上:
1.characterEncoding 字符编码,可以设置为utf8
2.useUnicode 是否使用unicode字符编码,设置为true
3.关闭ss1加密,userSSL 设置为false
    jdbc:mysql://localhost:3306/db6?
    characterEncoding=utf8&useUnicode=true&useSSL=false
 

 

 

 


 

你可能感兴趣的:(数据库)