导入 数据库:source 直接吧sql文件拖入mysql
MySQL默认端口号:3306 使用版本 5.1
###数据库
之前通过流去操作文件保存数据的弊端:
####什么是DB
####SQL
###数据库的分类(了解)
###开源和闭源
开源:开放源代码 免费试用,通过卖服务盈利,社会上会有一些大牛程序员会无偿的维护和升级
闭源:不开放源代码 收费,通过卖产品+服务盈利 ,有大牛会攻击破坏,但是人家养了一群人维护升级
###打开客户端连接MySQL
在终端中执行: mysql -uroot -p 回车 如果有密码写密码 回车 如果没有密码则直接回车
###和数据库相关的SQL
####查询所有数据库
show databases;
####创建数据库
create database db1;
db1数据库名
####查看数据库详情
show create database db1;
db1数据库名
####创建数据库指定字符集
create database db2 character set gbk/utf8;
db2数据库名
####删除数据库
-drop database 数据库名;
drop database db2;
#####练习: 创建db2 db3 db4 db5 里面3,4,5字符集为gbk 最后删除每一个
####使用数据库
use db1;
查询所有: show databases
创建 : create database db1;
查询单个 show create database db1;
指定字符集 create database db1 character set gbk/utf8;
删除 drop database db1;
使用 use db1;
###和表相关的SQL
####查询所有表
####表的引擎
###SQL格式:
回顾:
数据库
查询所有 show databases;
创建 create database db1;
查询详情 show create database db1;
指定字符集 create database db1 character set gbk/utf8;
删除 drop database db1;
使用 use db1;
表相关
查询所有 show tables;
创建 create table t1(name varchar(10),age int);
查询详情 show create table t1;
指定引擎和字符集: create table t1(name varchar(10),age int) engine=myisam/innodb charset=gbk/utf8;
####查看表字段
-查看表字段:desc 表名;
-表详情: show create table 表名;
-查询所有:show tables;
####删除表
-drop table 表名;
####修改表相关
1.修改表名
rename table 原名 to 新名;
rename table student to stu;
2.修改表的引擎和字符集
-alter table 表名 engine=myisam/innodb charset = utf8/gbk;
alter table stu engine = myisam charset = gbk;
3.添加表字段
-最后面:alter table 表名 add 字段名 字段类型;
-最前面:alter table 表名 add 字段名 字段类型 first;
-xxx的后面:alter table 表名 add 字段名 字段类型 after xxx;
创建表格 create table hero(name varchar(10));
添最后面 alter table hero add age int;
添最前面 alter table hero add id int first;
添name后面 alter table hero add sal int after name;
4.删除表字段
-alter table 表名 drop 字段名;
alter table hero drop sal;
5.修改表字段的名字和类型
-alter table 表名 change 原字段名 新字段名 新字段类型;
alter table hero change name heroname varchar(5);
6.修改表字段的类型和位置
-alter table 表名 modify 字段名 类型 位置;
alter table hero modify age int first/(after xxx);
###练习:
1.创建数据库newdb并使用,里面创建员工表t_emp只有name字段 引擎为myisam 字符集为gbk;
create database newdb ;
查看数据库: show create database newdb;
create table t_emp(name varchar(10)) engine=myisam charset=gbk;
2.修改表名为emp;
rename table t_emp to emp;
3.修改引擎为innodb 字符集为utf8;
alter table emp engine=innodb charset=utf8;
4.添加部门编号字段deptno 在最后面
alter table emp add deptno int ;
5.添加员工编号 empno在最前面
alter table emp add empno int first;
6.添加salary字段在name的后面
alter table emp add salary int after name;
7.修改salary字段名为sal,吧sal放在empno后面
alter table emp change salary sal int;
alter table emp modify sal int after empno;
8.删除sal字段
alter table emp drop sal;
9.删除表
drop table emp;
10.删除数据库
drop database newdb;
###数据相关
####插入数据
create table emp(id int,name varchar(10),age int,sal int);
emp 表格名
-全表插入数据:
-insert into emp values(1,‘Tom’,18,3000);
emp 表格名
-指定字段插入数据:
-insert into emp(name,age) values(‘Jerry’,19);
-insert into emp(name) values(‘李白’);
emp 表格名
-批量插入数据:
-insert into emp values(3,‘刘备’,28,6000),(4,‘张飞’,20,5000),(5,‘关羽’,25,9000);
-insert into emp (name,age) values(‘悟空’,500),(‘八戒’,400),(‘沙僧’,200);
emp 表格名
####查询数据
###中文字符问题
###练习:
1.创建hero表如果存在则先删除再创建,id 姓名name 类型type 金币money
删除表:drop table hero;
create table hero(id int,name varchar(10),type varchar(10),money int);
2.插入以下数据 1诸葛亮 法师18888 ,2 孙悟空 打野 18888,3 小乔 法师 6888,4黄总 射手 8888,5 刘备 战士 6888
insert into hero values(1,‘诸葛亮’,‘法师’,18888),(2,‘孙悟空’,‘打野’,18888),(3,‘小乔’,‘法师’,6888),(4,‘黄忠’,‘射手’,8888),(5,‘刘备’,‘战士’,6888);
3.修改所有18888的为28888
update hero set money=28888 where money=18888;
4.修改所有打野为刺客
update hero set type=‘刺客’ where type=‘打野’;
5.删除价格为6888的英雄
delete from hero where money=6888;
6.修改孙悟空为猪八戒
update hero set name=‘猪八戒’ where name=‘孙悟空’;
7.删除id为1,2,3的英雄
delete from hero where id<4;
8.修改所有的英雄类型为已阵亡
update hero set type=‘已阵亡’;
9.删除所有数据
delete from hero;
10. 删除表
drop table hero;
###练习2;
1.创建数据库db2指定字符集为utf8 并使用 在数据库中,创建emp表里由id,name age,salary,部门名称(dept)
create database db2 character set utf8;
create table emp(id int,name varchar(10),age int,salary int,dept varchar(10));
2.往上面表格中插入 刘关张三人 和取经4人 工资在3000-8000随意设置,年龄随意,id为1-7,刘关张属于三国部,剩下4人属于取经部
insert into emp values(1,‘刘备’,34,1000,‘三国部’),(2,‘关羽’,45,2211,‘三国部’),(3,‘张飞’,24,2500,‘三国部’),(4,‘唐 僧’,19,6000,‘取经部’),(5,‘孙悟空’,1118,5000,‘取经部’),(6,‘猪八戒’,23,4000,‘取经部’),(7,‘沙悟净’,19,3000,‘取经部’);
3.给表格添加一个性别字段在年龄的后面
alter table emp add sex varchar(10) after age;
4.修改所有的性别字段值为男
update emp set sex=‘男’ where sex is null;
5.添加一个貂蝉,性别女,年龄随意,工资为7000,部门为三国部
insert into emp values(8,‘貂蝉’,18,7000,‘三国部’,‘女’);
6.修改年龄小于30岁的员工工资为200
update emp set salary=200 where age<30;
7.修改取经部的所有人性别为未知
update emp set sex=‘未知’ where dept=‘取经部’;
8.查询三国部的员工姓名和工资
select name,salary from emp where dept=‘三国部’;
9.删除所有女员工
delete from emp where sex=‘女’;
10.删除部门中工资低于5000的员工
delete from emp where salary<5000;
———————————————————————————————————
###课程回顾
####数据库相关SQL
###主键约束
-主键:用于表示数据唯一性的字段称为主键
-约束:事给表字段添加的限制条件
-主键约束:限制主键字段值不能重复并且非空(唯一并且非空)
//创表:create table t1(id int primary key,name varchar(10));
//添数据:insert into t1 values(1,‘Tom’);
insert into t1 values(1,‘Jerry’);//失败 id重复了
insert into t1 values(null,‘abc’);//失败 不能为null
-自增: autp_increment
create table t2(id int primary key auto_increment,name varchar(10));
insert into t2 values(null,‘aaa’);
insert into t2 values(2,‘bbb’);
insert into t2 values(10,‘ccc’);
insert into t2 values(null,‘2222’);
1.当字段值为null的时候值会自动增长
2.自增字段值也可以手动赋值
3.增长的规则: 从曾杰出现的最大值基础上+1;
4.自增数值只增不减(delete清空表 自增数值并不清零);
###注释 comment
-创建表声明字段的时候给字段添加的介绍
create table t3(id int primary key auto_increment comment ‘这是一个主键’,name varchar(10) comment ‘这是员工姓名’);
查看表详情:show create table 表名;
### `和` (1左边的符号)
- `:用于修饰表名和字段名 可以省略
create table `t4`(`id` int,`name` varchar(10));
- ': 用于修饰字符串
###数据冗余
###练习:
-设计表保存一下数据:
1.集团总部下面的市场部下的市场a部的员工 刘备,工资8000,性别男,年龄25
2.教学部下 Java教师部的员工苍老师,工资100000,性别男,年龄18;
-创建员工表
create table emp(id int primary key auto_increment,name varchar(10),salary int,gender varchar(5),age int,daptid int);
-创建部门表
create table dept(id int primary key auto_increment,name varchar(10),parentid int);
-插入数据
先插入部门表 再插入 员工表
insert into dept values(null,‘集团总部’,null);
insert into dept values(null,‘市场部’,1);
insert into dept values(null,‘市场部a’,2);
insert into emp values(null,‘刘备’,8000,‘男’,25,3);
insert into dept values(null,‘教学部’,4);
insert into emp values(null,‘苍老师’,100000,‘男’,18,5);
-设计表保存以下数据2:
1.保存男装分类(category)下西服分类下的商品皮尔卡丹西服,价格9800,库存98件。
2.保存家用电器分类下,电视机分类下的小米电视,价格2500,库存108件
-创建电器分类表
create table item(id int primary key auto_increment,name varchar(15),price int, num int,categoryid int);
-创建部门分类表
create table category(id int primary key autoo_increment,name varchar(10),parentid int);
-插入数据
intsert into category values(null,‘男装’,null),(null,‘西服’,1),(null,‘家用电器’,null),(null,‘电视机’,3);
insert into item values(null,‘皮尔卡丹’,9800,98,2),(null,‘小米电视’,2500,108,4);
###事物
-什么是事物: 事物是数据库中执行SQL语句的最小工作单元,可以保证事物内的多条SQL语句要么全部成功,要么全部失败。
-查看数据库自动提交的状态:
show variables like ‘%autocommit%’;
显示内容: on开 off关
±--------------±------+
| Variable_name | Value |
±--------------±------+
| autocommit | ON |
±--------------±------+
-关掉自动提交: 0关闭 1 开启
set autocommit=0;
-手动提交:commit; (关闭状态下写完需要手动提交)
-测试转装:
create table person(id int,name varchar(10),money int);
insert into person values(1,‘超人’,500);
insert into person values(2,‘钢铁侠’,10000);
-关掉自动提交:set autocommit=0;
1.先让超人+2000;
update person set money=2500 where id=1;
2.开启另一个终端 验证,此时文件中的数据并没改掉:
usb 使用的数据库名; usb newdb;
person 表名:select * from person;
3.再让钢铁侠-2000;
update person set money=8000 where id=2;
4.执行提交:
commit;
-回滚: rollback;(将内存中的修改回滚到上次提交的点)
update person set money=100 where id=1;
###SQL的分类
-数据定义语言,包括 create,alter,deop,truncate,不支持事物
打开客户端连接MySQL: mysql -uroot -p
####DML Date Manipulation Language
-数据操作语言, 包括 insert,delete,update,select(DQL);
####DQL Date Query Language
-数据查询语言,只包括select,和事物没有关系因为并没有修改数据
####TCL Transaction Control Language
-数据控制语言,用于处理分配用户权限相关的操作
###truncate
-truncate table 表名;
-删除表示并且创建一个新表
-truncate,drop和delete的区别
-delete用于删除数据,使用delete清空表时自增数值不清零 执行效率最低
-drop 用于删除表 执行效率最高
-truncate 用于删除表并创建新的空表,执行效率比delete要高,而且则增数值会清零
###数据库的数据类型
####整数
-常用整数有 int(m) 和bigint(m); m代表显示长度
age int(10)
赋值28; 则自动补零为:0000000028;
创建表:create table t_int(num int(10) zerofill);
赋值:insert into t_int values(123);
查询:select * from t_int;
结果:
±-----------+
| num |
±-----------+
| 0000000123 |
±-----------+
####浮点数
###is null 和 is not null (为空和不为空)
1.查询emp表中没有上级领导mgr的员工编号empno,姓名ename,工资sal
select empno,ename,sal from emp where mgr is null;
2.查询emp表中没有奖金的员工姓名,工资,奖金
select ename,sal,comm from emp where comm is null;
3.查询有奖金的所有员工信息
select * from emp where comm is not null;
####别名
1.将查询到的员工姓名ename改成’姓名’
查询select ename from emp;
方法一:select ename as ‘姓名’ from emp;
方法二:select ename ‘姓名’ from emp;
方法三:select ename 姓名 from emp;
连续更改多个内容:select ename 姓名,sal 工资 from emp;
###去重 distinct
7.查询有图片image的得力商品信息
8.查询和得力无关的商品信息(title不包含得力)
9.查询价格在50到100意外的商品信息
###排序 order by 关键字 (根据什么来排序)
###分页查询 limit
###concat() 命名 函数
-把concat内部的参数拼接到一起
1.查询员工姓名和工资,要求工资单位是元
select ename,concat(sal,‘元’) 工资 from emp;
###数值计算 + - * / (mod(7,2)等效 7%2);
###和字符串相关函数
1.获取字符串的长度 char_length(str);
-获取所有员工的姓名和姓名的字符长度
select ename,char_length(ename) from emp;
2.获取字符串在另外一个字符串中出现的位置 inset(str,substr);
select instr(‘abcdefg’,‘d’);//d出现在abcdefg中第四个
3.插入字符串 insert(str,start,length,new);
select insert(‘abcdefg’,3,2,‘m’); //从第三个开始 后面2个替换为m
4.转大写upper(’’); 转小写lower('’);
select upper(‘abc’), lower(‘NBA’);
5.左边截取left('’,int)和右边截取right('’,int);
select left(‘abcdefg’,2),right(‘abcdefg’,2);
6.去两端空白 trim(’ * * );
select trim(’ a b ‘);
7.截取字符串 substring(’***’,开始int,数量int);
select substring(‘abcdefg’,3,2);// cd
8.重复 repeat(str,count);
select repeat(‘ab’,2);//abab
9.替换 replace(str,old,new);
select replace('This is mysql,‘my’,‘your’); //my替换为your
10.反转 reverse(str);
select reverse(‘abc’);//cba
###作业:
1.案例:查询没有上级领导的员工的编号,姓名,工资
select empno,ename,sal from emp where mgr is null;
2.案例:查询emp表中没有奖金的员工的姓名,职位,工资,以及奖金
select ename,job,sal,comm from emp where comm is null or comm=0;
3.案例:查询emp表中含有奖金的员工的编号,姓名,职位,以及奖金
select empno,ename,job,comm from emp where comm!=0 and comm is not null; //0不大于0,所以必须and
4.案例:查询含有上级领导的员工的姓名,工资以及上级领导的编号
select ename,sal,mgr from emp where mgr is not null;
5.案例:查询emp表中名字以‘S’开头的所有员工的姓名
select ename from emp where ename like ‘s%’;
6.案例:查询emp表中名字的最后一个字符是’S’的员工的姓名
select ename from emp where ename like ‘%s’;
7.案例:查询倒数的第2个字符是‘E’的员工的姓名
select ename from emp where ename like ‘%e_’;
8.案例:查询emp表中员工的倒数第3个字符是‘N’的员工姓名
select ename from emp where ename like ‘%n__’;
9.案例:查询emp表中员工的名字中包含‘A’的员工的姓名
select ename from emp where ename like ‘%a%’;
10.案例:查询emp表中名字不是以’K’开头的员工的所有信息
select * from emp where ename not like ‘k%’;
11.案例:查询emp表中名字中不包含‘A’的所有员工的信息
select * from emp where ename not like ‘%a%’;
12.案例:做文员的员工人数(job 中 含有 CLERK 的)
select count() from emp where job=‘clerk’;
13.案例:销售人员 job: SALESMAN 的最高薪水
select max(sal) from emp where job=‘salesman’;
14.案例:最早和最晚入职时间
select max(hiredate) 最晚入职,min(hiredate) 最早入职 from emp;
15.案例:查询类别 163的商品总库存量
select sum(num) from t_item where category_id=163;
16.案例:查询 类别 163 的商品
select * from t_item where category_id=163;
17.案例:查询商品价格不大于100的商品名称列表
select title from t_item where price<=100;
18.案例:查询品牌是联想,且价格在40000以上的商品名称和价格
select title,price from t_item where title like ‘%联想%’ and price>40000;
19.案例:查询品牌是三木,或价格在50以下的商品名称和价格
select title,price from t_item where title like ‘%三木%’ or price<50;
20.案例:查询品牌是三木、广博、齐心的商品名称和价格
select title ,price from t_item where title like ‘%三木%’ or title like ‘%广播%’ or title like ‘%齐心%’;
21.案例:查询品牌不是联想、戴尔的商品名称和价格
select title price,title from t_item where title not like ‘%联想%’ and title not like ‘%戴尔%’;
22.案例:查找品牌是联想且价格大于10000的电脑名称
select title from t_item where title like ‘%联想%’ and price>10000;
23.案例:查询联想或戴尔的电脑名称列表
select title from t_item where title like ‘%联想%’ or title like ‘%戴尔%’ ;
24.案例:查询联想、戴尔、三木的商品名称列表
select title from t_item where title like ‘%联想%’ or title like ‘%戴尔%’ or title like ‘%三木%’;
25.案例:查询不是戴尔的电脑名称列表
select title from t_item where title not like ‘%戴尔%’;
26.案例:查询所有是记事本的商品品牌、名称和价格
select item_type 名称,title 品牌 ,price 价格 from t_item where title like ‘%记事本%’;
27.案例:查询品牌是末尾字符是’力’的商品的品牌、名称和价格
select title 品牌,item_type 名称,price 价格 from t_item where title like ‘%力’;
28.案例:名称中有联想字样的商品名称
select title from t_item where title like ‘%联想%’;
29.案例:查询卖点含有’赠’产品名称
select title from t_item where sell_point like ‘%赠%’;
30.案例:查询emp表中员工的编号,姓名,职位,工资,并且工资在1000~2000之间。
select empno,ename,job,sal from emp where sal>1000 and sal<2000;
select empno,ename,job,sal from emp where sal beteeen 1000 and 2000;
31.案例:查询emp表中员工在10号部门,并且含有上级领导的员工的姓名,职位,上级领导编号以及所属部门的编号
select ename,job,mgr,deptno from emp where deptno=10 and mgr is not null;
32.案例:查询emp表中名字中包含’E’,并且职位不是MANAGER的员工的编号,姓名,职位,以及工资。
select empno,ename,job,sal from emp where ename like ‘%e%’ and job!=‘manager’;
33.案例:查询emp表中10号部门或者20号部门中员工的编号,姓名,所属部门的编号
select empno,ename,deptno from emp where deptno=10 or deptno=20;
select empno,ename,deptno from emp where deptno in(10,20);
34.案例:查询emp表中没有奖金或者名字的倒数第2个字母不是T的员工的编号,姓名,职位以及奖金
select empno,ename,job,comm from emp where comm!=0 or ename not like ‘%t_’;
35.案例:查询工资高于3000或者部门编号是30的员工的姓名,职位,工资,入职时间以及所属部门的编号
select ename,job,sal,hiredate deptno from emp where sal>3000 or deptno=30;
36.案例:查询不是30号部门的员工的所有信息
select * from emp where deptno!=30;
37.案例:查询奖金不为空的员工的所有信息
select * from emp where comm!=0 or is not null;
38.案例:查询emp表中所有员工的编号,姓名,职位,根据员工的编号进行降序排列
select empno,ename,job from emp order by empno desc;
39.案例:查询emp表中部门编号是10号或者30号中,所有员工姓名,职务,工资,根据工资进行升序排列
select ename,job,sal from emp where deptno=10 or deptno=30 order by sal;
40.案例:查询emp表中所有的数据,然后根据部门的编号进行升序排列,如果部门编号一致,根据员工的编号进行降序排列
select * from emp order by deptno, empno desc;
41.案例:查询emp表中工资高于1000或者没有上级领导的员工的编号,姓名,工资,所属部门的编号,以及上级领导的编号,根据部门编号进行降序排列,如果部门编号一致根据工资进行升序排列。
select empno,ename,sal,deptno,mgr from emp where sal>1000 or mgr is null order by deptno desc,sal;
42.案例:查询emp表中名字中不包含S的员工的编号,姓名,工资,奖金,根据工资进行升序排列,如果工资一致,根据编号进行降序排列
select empno,ename,sal,comm from emp where ename not like ‘%s%’ order by sal,empno desc;
43.案例:统计emp表中员工的总数量
select count(ename) from emp;
select count() from emp;
44.案例:统计emp表中获得奖金的员工的数量
select count(ename) from emp where comm!=0;
45.案例:求出emp表中所有的工资累加之和
select sum(sal) from emp;
46.案例:求出emp表中所有的奖金累加之和
select sum(comm) from emp;
47.案例:求出emp表中员工的平均工资
select avg(sal) from emp;
48.案例:求出emp表中员工的平均奖金
select avg(comm) from emp;
49.案例:求出emp表中员工的最高工资
select max(sal) from emp;
50.案例:求出emp表中员工编号的最大值
select max(empno) from emp;
51.案例:查询emp表中员工的最低工资。
select min(sal) from emp;
52.案例:查询emp表中员工的人数,工资的总和,平均工资,奖金的最大值,奖金的最小值,并且对返回的列起别名。
select count(ename) 员工人数,sum(sal) 工资总和,avg(sal) 平均工资,max(comm) 最多奖金,min(comm) 最少奖金 from emp;
53.案例:查询emp表中每个部门的编号,人数,工资总和,最后根据人数进行升序排列,如果人数一致,根据工资总和降序排列。
select deptno 编号总数,count(ename) 总人数,sum(sal) 工资总和 from emp group by deptno order by count(ename),sum(sal) desc;
方法二 用别名:
select deptno 编号总数,count(ename) 总人数,sum(sal) 工资总和 from emp group by 编号总数 order by 总人数,工资总和 desc;
54.案例:查询工资在1000~3000之间的员工信息,每个部门的编号,平均工资,最低工资,最高工资,根据平均工资进行升序排列。
select deptno,avg(sal),min(sal),max(sal) from emp where sal>1000 and sal<3000 group by deptno order by avg(sal);
55.案例:查询含有上级领导的员工,每个职业的人数,工资的总和,平均工资,最低工资,最后根据人数进行降序排列,如果人数一致,根据平均工资进行升序排列
select count(ename) 人数,job,sum(sal),avg(sal) 平均工资,min(sal) from emp where mgr is not null group by job order by 人数 desc,平均工资;//用别名命名
56.案例:查询工资在1000~3000之间每一个员工的编号,姓名,职位,工资
select empno,ename,job,sal from emp where sal>1000 and sal<3000 group by sal;
57.案例:查询emp表中奖金在500~2000之间所有员工的编号,姓名,工资以及奖金
select empno,ename,sal,comm from emp where comm>500 and comm<2000;
58.案例:查询员工的编号是7369,7521,
select * from emp where empno=7396 or empno=7521;
59.案例:查询emp表中,职位是ANALYST,
select * from emp where job=‘analyst’;
60.案例:查询emp表中职位不是ANALYST,
select * from emp where job!=‘analyst’;
———————————————————————————————————
###数学相关函数
1.向下取整 floor(num)
select floor(3.84)
2.四舍五入 round(num);
select round(3.84);
-round(num,m) m 代表小数数位
select round(4.431623,3);//4.432
3.非四舍五入 truncate(num,m);
select truncate(3.84567,3);//3.845
4.随机数 rand() 0-1 5-10 0-5
select floor(rand()*6) + 5;
3-8 0-5 select floor(rand()*7) +3;
###分组查询
-如果需要使用多个字段进行分组 直接在group by 后面多写个字段名通过逗号分隔
1.查询每个部门下每个领导的手下人数
select deptno,mgr,count(*) from emp where mgr is not null group by deptno,mgr;
###having 不能单独使用 套 group by 使用
-where 后面只能写普通字段的条件不能写聚合函数
-having后面可以写普通字段页可以写聚合函数,但是推荐在having后面只写聚合函数
###作业:
每个部门的人数,根据人数排序
select deptno,count(*) from emp group by deptno;
每个部门中,每个主管的手下人数
select deptno,mgr,count(*) from emp where mgr is not null group by deptno,mgr;
查询两张表:select d.deptno,e.mgr,count(e.ename)
右外查询: from emp e right join dept d
内链接: on e. deptno=d.deptno
where e.mgr is not null
group by d.deptno,e.mgr;
每种工作的平均工资
select job 工作名,avg(sal) 平均工资 from emp group by job ;
每年的入职人数
select extract(year from hiredate) y,count(*) 入职人数 from emp group by y;
少于等于3个人的部门信息
两张表:
select d.*,count(ename) c
from emp e right join dept d
on e.deptno=d.deptno
group by d.deptno
having c<=3;
拿最低工资的员工信息
select * from emp where sal=(select min(sal) from emp);
只有一个下属的主管信息
查询上级id信息方法:select * from emp where mgr is not null group by mgr having count()=1;
正确答案:select mgr from emp where mgr is not null group by mgr having count()=1;
select * from emp where empno in(select mgr from emp where mgr is not null group by mgr having count(*)=1);
平均工资最高的部门编号
-得到每个部门的平均工资
select deptno,avg(sal) from emp group by deptno;
-得到最高的平均工资
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(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 count() from emp group by mgr order by count() desc limit 0,1;
select * from emp group by mgr having count()=(select count() from emp group by mgr order by count(*) desc limit 0,1);
得到最多的下属人数;select count() c from emp group by mgr order by count() 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); ps:查询条件不能同时由2个 select mgr,count() 报错。
通过领导编号得到个人信息
select * from emp where empno in(select mgr from emp group by mgr having count()=(select count(*) c from emp group by mgr order by c desc limit 0,1));
——————————————————————————————-
###表设计之关联关系
###一对一
-什么是一对一关系: 有ab两张表,其中a表的一条数据对应b表的一条数据,同时b表的一条数据页对应a表中的一条数据
-应用场景: 用户表和用户信息拓展表
如:用户名 密码 昵称 头像 性别 手机号 地址 邮箱。。。。。
-外键:表中用于建立关系的字段称为外键,一张表可能有多个外键,但只会有一个主键
-如何建立关系:在从表中添加外键指向主表的主键
-练习: 创建表保存一下数据:表名 user 和 userinfo
user中:id 用户名wukong 密码:abcd userinfo中:昵称:悟空 性别 男 地址:大唐
null wzt admin 武则天 女 大陆
null superman 132465 超人 男 铁岭
create table user(id int primary key auto_increment,username varchar(10),password varchar(10));
create table userinfo(userid int,nickname varchar(10),sex varchar(10),address varchar(10));
insert into user values(null,‘wk’,‘abcd’),(null,‘wzt’,‘admin’),(null,‘Superman’,‘123456’);
insert into userinfo values(1,‘悟空’,‘男’,‘花果山’),(2,‘武则天’,‘女’,‘大陆’),(3,‘超人’,‘男’,‘铁岭’);
1.查询每个用户名对应的昵称
select u.username,ui.nickname
from user u join userinfo ui
on u.id=ui.userid;
2.查询超人的用户名
select u.username
from user u join userinfo ui
on u.id=ui.userid
where ui.nickname=‘超人’;
3.查询性别是男的用户名和密码
select u.username,u.password
from user u join userinfo ui
on u.id=ui.userid where ui.sex=‘男’;
4.查询是否存在 用户名: wukong 密码: abd的用户名 (查询符合条件的数据条数)
select count(*) from user where username=‘wukong’ and password=‘adb’;
###一对多
-什么是一对多: 有ab两张表,a表中的一条数据对应b表中的多条数据,同时b表中的一条数据对应a表中的一条
-应用场景: 用户表和部门表,商品表和分类表
-如何建立关系:在多的一端添加外键指向另外一张表的主键
create table emp(id int primary key auto_increment,name varchar(10),deptid int);
create table dept(id int primary key auto_increment,name varchar(10));
insert into emp values(null,‘猪八戒’,1),(null,‘白骨精’,2),(null,‘蜘蛛精’,2);
insert into dept values(null,‘神仙’),(null,‘妖怪’);
1.查询每个员工的姓名和对应的部门名称
select e.name,d.name
from emp e join dept d
on e.deptid=d.id;
2.查询妖怪部的员工姓名
select e.name
from emp e join dept d
on e.deptid=d.id where d.name=‘妖怪’;
###多对多
-什么是一对多: 有ab两张表,a表中的一条数据对应b表中的多条数据,同时b表中的一条数据对应a表中的多条
-应用场景:老师表和学生表
-如何建立关系: 通过第三张关系表保存两张主表的关系
-练习:
创建老师表,学生表和关系表
create table teacher(id int primary key auto_increment,name varchar(10));
create table student(id int primary key auto_increment,name varchar(10));
create table t_s(tid int,sid int);
insert into teacher values(null,‘苍老师’),(null,‘传奇老师’);
insert into student values(null,‘小王’),(null,‘小刘’),(null,‘小张’);
1.往以上表中保存苍老师的学生小刘和小丽,传奇老师的学生小刘,小王和小丽
insert into teacher values(null,‘苍老师’),(null,‘传奇老师’);
insert into student values(null,‘小王’),(null,‘小刘’),(null,‘小张’);
insert into t_s values(1,1),(1,3),(2,1),(2,2),(2,3);
2.查询每个学生姓名和对应的老师姓名
select s.name,t.name
from student s join t_s ts
on s.id=ts.sid
join teacher t
on t.id=ts.tid;
3.查询苍老师的学生都有谁
select s.name
from student s join t_s ts
on s.id=ts.sid
join teacher t
on t.id =ts.tid where t.name=‘苍老师’;
4.查询小刘的老师是谁
select t.name
from student s join t_s ts
on s.id=ts.sid
join teacher t
on t.id =ts.tid where s.name=‘小刘’;
###自关联
-在当前表中添加外键 外键的值指向当前表的主键,这种关联方式称为自关联
create table person(id int primary key auto_increment,name varchar(10),mgr int);
保存一下数据:如来→唐僧→悟空→猴崽子
insert into person values(null,‘如来’,null),(null,‘唐僧’,1),(null,‘悟空’,2),(null,‘猴崽子’,3);
1.查询每个人的名字和上级的名字
//左边表有个最上级如来,所以用左外连接让如来显示出来
select p.name,m.name 上级
from person p left join person m
on p.mgr=m.id;
###表设计案例:权限管理
-实现权限管理功能需要准备三种主表和两种关系表
-创建表:
create table user(id int,name varchar(10));
create table role(id int,name varchar(10));
create table module(id int,name varchar(10));
create table u_r (uid int,rid int);
create table r_m (rid int,mid int);
-插入数据:
insert into user values(1,‘刘德华’),(2,‘凤姐’);
insert into role values(1,‘刘德华’),(2,‘男会员’),(3,‘女游客’),(4,‘女管理员’);
insert into module values(1,‘男浏览’),(2,‘男发帖’),(3,‘女浏览’),(4,‘女发帖’),(5,‘女发帖’),(6,‘女删帖’);
-保存校色和权限的关系:
insert into r_m values(1,1),(2,1),(2,2),(3,3),(4,3),(4,4),(4,5);
-保存用户和角色的关系:刘德华男会员和女游客 凤姐: 女管理员和男游客
insert into u_r values(1,2),(1,3),(2,1),(2,4);
1.查询每个用户的权限有哪些
select u.name,m.name
from user u join u_r ur
on u.id = ur.uid
join r_m rm
on rm.rid=ur.rid
join module m
on m.id=rm.mid;
2.查询凤姐的权限
select u.name,m.name
from user u join u_r ur
on u.id=ur.uid
join r_m rm
on rm.rid=ur.rid
join module m
on m.id=rm.mid where u.name=‘凤姐’;
3.查询拥有男浏览权限的用户有谁
select u.name,m.name
from user u join u_r ur
on u.id=ur.uid
join r_m rm
on rm.rid=ur.rid
join module m
on m.id=rm.mid where m.name=‘男浏览’;
———————————————————————————————————
###视图
-数据库中包含多种对象,表和试图都是数据库中的对象,视图可以理解成一张虚拟表,试图本质就是取代了一段sql查询语句
-为什么使用视图:因为有些数据的查询需要写大量的SQL语句,每次书写比较麻烦,通过使用视图相当于把当了的SQL查询语句进行保存,下次从视图中查询就不用再次写大量SQL语句,从而提高开发效率;
-试图格式: create view 视图名 as(子查询);
create view 视图名 as(子查询);
创建:-create view v_emp_10 as (select * from emp where deptno=10);
插入:delete from emp where sal=1300;
查询:select * from v_emp_10;
1.创建一个没有工资的视图
create view v_emp_nosal as (select empno,ename,comm,mgr from emp);
select * from v_emp_nosal;
2.创建视图,视图中显示每个部门的工资总和,平均工资,最高工资,最低工资;
create view v_emp_xxx as (select deptno,sum(sal),avg(sal),max(sal),min(sal) from emp group by deptno);
select * from v_emp_xx;
-视图的分类:
1.简单的视图:创建视图的时候不包含:去重,分组,函数,关联查询的视图称为简单视图,可以对视图中的数据进行增删改查
2.复杂视图: 和简单视图相反,只能进行查询操作
-简单视图的增删改操作 操作方式和操作table一样
-插入数据:
查视图:show tables;
insert into v_emp_10 (empno,ename,deptno) values (10011,‘悟空’,10);
insert into v_emp_10 (empno,ename,deptno) values (10012,‘八戒’,20);(数据污染,只能在总表中查出来,v_emp_10中查不到)
-数据污染:往三视图中插入一条在视图中不显示但是在原表中显示的数据,称为数据污染
-通过 with check option 关键字解决数据污染问题
create view e_emp_20 as (select * from emp where deptno=20) with check option;
-测试:
insert into e_emp_20 (empno,ename,deptno) values (10013,‘刘备’,20);//成功
insert into e_emp_20 (empno,ename,deptno) values (10014,‘张飞’,30);//失败 deptno!=20;
-删除和修改: 只能操作视图中存在的数据
-别名:如果创建视图时使用别名 则 操作视图时只能使用别名;
create view v_emp_30 as (select ename name from emp where deptno=30);
select * from v_emp_30 where ename=‘james’;
###视图总结:
1.视图是数据库中的对象,可以理解成一张虚拟的表,本质就是一段SQL语句
2.作用:重用SQL,隐藏敏感字段
3.分类:简单视图(不包含去重 分组 函数 关联查询,可以增删改查)和复杂视图(反之,查询)
4.通过with check option 解决数据污染
5.删除和修改时, 只能操作视图中存在的数据
6.起了别名 只能用别名
####唯一约束 unique
-字段的值不能重复
create table t2(id int,age int unique);
insert into t2 values(1,19);//成功
insert into t2 values(2,19);//失败
####主键约束
-字段的值唯一且非空
-创建表时添加主键约束: create table t3(id int primary key,age int);
-创建表之后添加主键约束:
create table t3(id int,name varchar(10));
alter table t3 add primary key(id);
-删除主键约束
alter table t3 drop primary key;
####自增
-数值只增不减
-从历史最大值的基础上+1
-字段赋值为null的时候自动+1
-使用delete 删除全表数据 自增数值不变
-使用truncate 自增清零
###默认约束 default
-给字段添加默认值 当插入数据不给该字段赋值时,默认值生效
create table t4(id int,age int default 10);
insert into t4 alues(1,20);
insert into t4 values(2,null);
insert into t4 (id) values(3);//默认值生效
####检查约束 check
-语法支持但是没有效果
caeate table t5 (id int,age check(age>10);
insert into t5 values(1,5);
####外键约束
-外键约束作用:为了保证两个表直之间的关系正确建立
1.插入数据时外键值可以为null,可以重复,但是不能是另外一张表不存在的数据
2.被依赖的表不能被先删除
3.被依赖的数据不能先删除
-如何使用外键:
1.创建部门表
create table dept(id int primary key auto_increment,name varchar(10));
2.创建员工表
create table emp(id int primary key auto_increment,name varchar(10),deptid int, constraint fk_dept foreign key(deptid) references dept(id));
-介绍:
constraint 约束名称 foreign key(外键字段名)references 表名(字段名);
-测试:
insert into dept values(null,‘神仙’),(null,‘妖怪’);
insert into emp values(null,‘悟空’,1);//成功
insert into emp values(null,‘八戒’,1);//成功
insert into emp values(null,‘超人’,3)//失败 没有3
drop from dept where id=2;//成功
delete from dept where id=1;//失败
###索引
-什么是索引:索引是数据库中提高查询效率的技术,类似于字典的目录
-为什么使用索引:如果不适用索引数据会零散的保存在每一个磁盘块当中,查询数据时需要挨个的遍历每一个磁盘块找数据,如果数据量超级大,遍历每一个磁盘块是件非常耗时的事情,添加索引后,会将磁盘块以树状结构进行保存,查询数据时会有目的性的访问部分磁盘块,因为访问的磁盘块数量降低 所以能够起到提高查询效率的作用。
-索引是越多越好吗?
不是,因为索引会占磁盘空间,通过某个字段创建的索引可能永远用不上,则这个索引完全没有存在的意义,只需要对查询时频繁使用的字段创建索引
-有索引就一定好吗?
不一定 如果数据量小使用索引反而会降低查询效率
-索引的分类
1.聚集索引(聚簇(cu)索引):通过主键创建的索引为聚集索引,添加了主键约束的表会自动添加聚集索引,聚集索引的树状结构中保存了数据
2.非聚集索引:通过非主键字段创建的索引叫做非聚集索引,树状结构中只保存了数据所在磁盘块的地址并没有数据。
-导入数据:
-windows电脑 把文件放到任意盘下: 以d盘为例
source d:/item)backup.sql
-Linux系统 /home/soft01/桌面/item_backup.sql;
-测试:
1.show tables; 看是否有item2这张表
2.select count(*) from item2;看是否有172万条数据
3.select * from item2 where title=‘100’; //看一下耗时 1.56秒
-创建索引的格式:
create index 索引名 on 表明(字段名[(字符长度)]);
create index i_item_title on item2(title);
-创建完后继续执行
select * from item2 where title=‘100’;//看一下耗时 2.66s
-查看索引:
show index from item2;
-删除索引
drop index 索引名 on 表名;
drop index i_item_title on item2;
-复合索引
通过多个字段创建的索引称为复合索引
-格式:create index 索引名 on 表名(字段1,字段2);
频繁使用多个字段进行数据查询时为了提高查询效率可以创建复合索引
select * from item2 where title=‘100’ and price<100;
create index i_item2_title_price on item2(title,price);
-总结:
1.索引是用于提高查询效率的技术,类似目录
2.索引会占用磁盘空间不是越多越好
3.如果数据量小的话 添加索引会降低查询效率
4.尽量不要在频繁改动的表上改动索引
####事物
-数据库中执行SQL语句的最小工作单元,保证事物中的多条SQL全部成功或全部失败
-事物的ACID特性:
1.Atomicity: 原子性,最小不可拆分 保证全部成功或全部失败
2.Consistency:一致性,从一个一致状态到另外一个一致状态
3.Isolation:隔离性,多个事物间互相隔离互不影响
4.Durability:持久性,事物执提交后 数据持久保存到数据库文件中
-事物相关指令:
-查看自动提交状态: show variables like ‘%ayticinnut%’;
-提交:commit;
-回滚:rollback;
-保存回滚点:savepoint s1;
-回滚到指定回滚点: rollback to s1;
###group_concat(条件名) 分组连接函数
1.查询员工表中 每个部门的所有员工工资
select deptno,group_concat(sal) from emp group by deptno;
2.查询员工表中每个部门的员工姓名和对应的工资 要求显示到一条数据中
select deptno,group_concat(ename,’:’,sal) from emp group by deptno;
###面试题:
有个学生表student (id,name,subject,socre)
保存一下数据 :
张三 语文 66 , 张三 数学 77 , 张三 英语 55 , 张三 体育 77
李四 语文 59 , 李四 数学 88 , 李四 英语 78 ,李四 体育 95
王五 语文 75 , 王五 数学 54 , 王五 英语 98 , 王五 体育 88
create table student(id int primary key auto_increment,name varchar(10),subject varchar(10),socre int);
insert into student values(null,‘张三’,‘语文’,66),(null,‘张三’,‘数学’,77),(null,‘张三’,‘英语’,55),(null,‘张三’,‘体育’,77);
insert into student values(null,‘李四’,‘语文’,59),(null,‘李四’,‘数学’,54),(null,‘李四’,‘英语’,78),(null,‘李四’,‘体育’,95);
insert into student values(null,‘王五’,‘语文’,75),(null,‘王五’,‘数学’,54),(null,‘王五’,‘英语’,98),(null,‘王五’,‘体育’,88);
1.查询每个人的平均分 从大到小 排序
select name,avg(socre) from student group by name order by avg(socre) desc ;
2.每个人的姓名 科目 成绩 一行显示出来
select name,group_concat(subject,’:’,socre) from student group by name;
3.查询每个人的最高分和最低分
select name,max(socre),min(socre) from student group by name;
4.查询每个人不及格的科目以及分数和不及格的科目数量
select name,subject,group_concat(socre),count(subject) from student where socre<60 group by name;
——————————————————————————————————
JDBC
—— ——————————— ————
| 页面 | | webServer Java业务逻辑 | | 数据存储 |
—— ——————————— ————
数据库连接需要在pom.xml后面粘贴这一串代码
mysql
mysql-connector-java
5.1.6
###JDBC
-JDBC:Java DataBase Connectivity, java数据库连接 实际上jdbc是Java中的一套和和数据库进行叫苦的api(application program interface 应用程序编程接口)
-为什么使用JDBC:因为Java程序员需要连接多种数据库 为了避免每一种数据库都学习一套新的api,Sun公司提出了JDBC的接口,各个数据库的厂商根据此接口写实现类(驱动) ,这样 Java程序员只需要掌握JDBC接口的调用即可访问任何数据库。
###如何使用JDBC连接MySQL数据库
1.创建Maven工程
2.登陆maven私服的网站maven.tedu.cn 外网 maven.aliyun.com
首页搜索MySQL 找到 5.1.6版本 把坐标复制到pom.xml中
3.创建Demo01.java类中
public static void main(String[] args) throws ClassNotFoundException, SQLException{
//.注册驱动
/寻找地址: maven Dependencies -奶瓶下 第一个 com.mysql.jdbc-Driver.class-
* 找到com.mysql.jdbc.Driver复制-粘贴到Class.forName(“com.mysql.jdbc.Driver”);/
Class.forName(“com.mysql.jdbc.Driver”);
//2.获取连接对象
Connection conn = DriverManager.getConnection(“jdbc:mysql://localhost:3306/db3”,“root”, “mother”);
//3创建SQL执行对象
Statement stat = conn.createStatement();
//4.执行 SQL
String sql = “create table if not exists jdbc”+"(id int,name varchar(10))";//加上if not exists 重复创建不会报错
stat.execute(sql);
System.out.println(“创建完成”);
//5.关闭资源
stat.close();
conn.close();
}
###JUnit Test 单元测试
-在无参无返回值的方法上面添加@Test注解,通过右键 run as 执行 绿色代表执行成功,红色执行失败
###执行SQL的方法
###自定义模块
//执行查询 得到的结果封装在了resultset中
ResultSet rs = stat.executeQuery(sql);
//遍历结果集
while(rs.next()) {
int empno = rs.getInt(“empno”);
String name = rs.getString(“ename”);
double sal = rs.getDouble(“sal”);
System.out.println(empno+name+sal);
}
###自定义模板代码
window->preferense->java->editor->templates->new
———————————————————————————————————
###数据库连接池 DBCP
-为什么要用连接池:如果没有连接池,一万次请求会对应一万次和数据库服务器的连接和断开连接,使用连接池之后可以将连接池中的连接复用,从而提高执行效率
###PerparedStatement预加载的SQL执行对象
-好处:
1.代码更直观,简介
2.可以避免SQL注入,因为在预编译时已经把sql逻辑固定锁死,不会被之后替换进去的值改变原有逻辑
###批量操作 batch
因为每次sql的执行都需要和数据库服务器进行数据传输,如果执行的sql太多每次和数据库进行交互浪费资源执行效率低,使用批量操作可以把多条SQL语句合并到一次交互中,这样可以提高执行效率。
//请输入用户名 libai
//请输入密码 admin
//登陆成功/登陆失败
数据库创建:
create table user(id int primary key auto_increment,username varchar(10),password varchar(10));
insert into user values(null,‘libai’,‘admin’),(null,‘liubei’,‘123456’);
eclipse:
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
System.out.println(“请输入用户名”);
String username = scanner.nextLine();
System.out.println(“请输入密码”);
String password = scanner.nextLine();
boolean b = login(username,password);
if(b){
System.out.println(“登陆成功”);
}else{
System.out.println(“登陆失败”);
}
}
private static boolean login(String username, String password) {
String sql = "select count(*) from user " + “where username=? and password=?”;
System.out.println(sql);
Connection conn = null;
PreparedStatement stat = null;
ResultSet rs = null;
try {
conn = DBUtils.getConn();
stat = conn.prepareStatement(sql);
stat.setString(1, username);
stat.setString(2, password);
rs = stat.executeQuery();
while(rs.next()){
//得到查询的数量
int count = rs.getInt(1);
if(count>0){//登陆成功
return true;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
DBUtils.close(conn, stat, rs);
}
return false;
}
}
###事物
1.关闭自动提交
conn.setAutoCommit(false/true);
2.提交
conn.commit();
3.回滚
conn.rollback();
-案例
public static void main(String[] args){
// create table person (id int,name varchar(10),money int);
// insert into person values(1,‘超人’,500),(2,‘钢铁侠’,5000);
String sql1 = “update person set money=money+2000 where id=1”;
String sql2 = “update person set money=money-2000 where id=2”;
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
conn = DBUtils.getConn();
stat = conn.createStatement();
//关闭自动提交
conn.setAutoCommit(false);
//让超人+2000
stat.executeUpdate(sql1);
//让钢铁侠-2000
stat.executeUpdate(sql2);
//查询钢铁侠生于的钱是否>=0;
rs = stat.executeQuery(“select money from person where id=2”);
while(rs.next()){
int money = rs.getInt(“money”);
if(money>=0){
//提交
conn.commit();
System.out.println(“转账成功”);
}else{
conn.rollback();//回转
System.out.println(“钢铁侠余额不足”);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
DBUtils.close(conn, stat, rs);
}
}
——————————————————————————————————
整理大概: