####在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