1.查询所有
show databases
2.创建数据库
create 创造,造成 database db1
3.创建数据库指定字符集
create database db1 character 品质,字符 set utf8/gbk;
4.查询数据库详情
show create database db1
5.删除数据库
drop 下降,降低 database db1
6.使用数据库
use db1
表相关SQL
1.创建表(执行表相关sql切记已经使用了数据库)
create table 表名(字段名1 字段1类型,字段2 字段2类型…);
create table person(name varchar(5),age int);
2.查看所有表
show tables;
3.查看标详情
show create table 表名;
表引擎:
(一)innodb(默认):支持数据库的高级操作(外键,事务等)
(二)myisam:不支持数据的高级操作,只支持基本的数据增删改查操作
4.创建表时指定引擎和字符集
create table ti(name varchar(10),age int)engine=myisam charset=gbk;
show create table t1;
5.查看表字段
desc 表名
6.删除表
drop table 表名;
修改表相关操作
1.修改表名
rename 重新命名 table 原名 to 新名
2.修改表引擎和字符集
alter 改变 table 表名 engine=innodb/myisam charset=utf8/gbk;
3.给表添加字段
添加到最后:alter table 表名 add 字段名 字段类型;
前面添加:alter table 表名 add 字段名 字段类型 first;
xxx的后面:alter table 表名 add 字段名 字段类型 after xxx;
4.删除表字段;
alter table emp drop gender;
5.改变字段名和类型
alter table 表名 change 原名 新名 新类型;
6.修改字段类型和位置
alter table 表名 modify 修改,改变字段名 新类型 first /after xxx;
数据相关sql
1.添加数据
-全表添加数据:insert 插入 into 到…里 表名 values(值1,值2);values里面的值的数量和顺序一定要和表字段一致;
-指定字段插入格式:insert into 表名 (字段名1,字段名2) values(值1,值2);
values里面的值得到数量和顺序 和values前面指定的要一致;
-批量插入
insert into emp values(‘刘备’,18,2000),(‘张飞’,18,2000),(‘关羽’,18,2000);
insert into emp (name) values(‘悟空’),('八戒),(‘沙僧’);
2.查询数据
格式:select 选择,挑选 字段信息 from 表名 where 哪里条件;
select name from emp;
select name,age from emp where age>18;
select * from emp;
3.修改数据
update 更新表名 set 字段名=值 where 条件
update emp set age=50 where name=‘tom’;
4.删除数据
delete from 表名 where 条件;
delete from emp where age>20;
主键约束
约束:创建表时会给表字段添加的限制条件
主键:表示数据唯一性的字段称为主键
主键约束保证字段的值唯一并且非空
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,‘aaa’)
主键+自增
让主键值自己增长
自增数值只增不减,从历史最大值基础上+1
create table t2(id int primary key auto_increment 增加,name varchar(10));
注释
给表字段添加注释
create table t2(id int primary key auto_increment comment 注释’这是个主键’,name varchar(10)comment’这是名字呵呵’);
`符号的作用
用于修饰表名和字段名,可以省略,但不要和单引号搞混
create table t4
(name
varchar(10));
数据冗余
由于表设计不够合理导致的大量重复数据 称为数据冗余,可以通过拆分表的形式降低或避免冗余的出现
parent_id
事物
事物是数据库中执行同一业务多条sql语句的工作单元,可以保证这多条sql语句全部执行成功或全部执行失败,不会出现部分成功部分失败的情况
1.开启事物
begin;开始,着手
2.回滚事物:把内存中的错误操作修改回去
rollback;反转,回落
3.提交事务
commit;委托
4.保存回滚点 savepoint xxx;save保存,节省 point点
5.回滚到指定回滚点 rollback to xxx;
SQL分类
1.DDL Data Definition Language:数据定义语言
包括:create,drop,alter,truncate,不支持事物
2.DML Data Manipulation Language:数据操作语言
包括:insert,update,delete,select,(DQL),支持事物
3.
truncate 切去头端,缩短
truncate table 表名
删除表或创建新表 自增数值清零
create table t5(id int primary key auto_increment,name varchar(10));
insert into t5 values(null,‘aaa’),(null,‘bbb’);
truncate table t5;
insert into t5 values(null,‘aaa’),(null,‘bbb’);
数据类型
1.整数类型
int(m) bigint(m)中m表示显示长度,需要结合zerofill 把前面的0显示出来 关键字使用
create table t_int(id int,age int(10) zerofill);
insert into t_int values(1,18);
2.浮点数
常用:double(m,d)m代表长度,d代表小数 78.532 m=5 d=3
decimal(m,d)超高精度浮点数, 当超高精度运算时使用
3.字符串
常用:char(m)不可变长度,最大255,varchar(m)可变长度,节省资源,最大长度为65535
长度超过255建议使用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-3-20’,‘16:33:30’,‘2019-3-21 16:34-10’,null);
is null和is not null
1.查询没有奖金comm的员工信息
select * from emp where comm is null;
3.查询没有领导的员工姓名ename;
select ename from emp where mgr is null;
3.查询有领导的员工姓名和领导编号
select ename,mgr from emp where mgr is not null;
别名
select ename 姓名,sal 工资 from emp;
去重 distinct不同
去掉重复的数据
1.查询所有员工从事的工作job有哪些
select distinct job from emp;
2.查询所有员工所属部门编号deptno有哪些
select distinct deptno from emp;
and和or
1.查询20号部门工资大于2000的员工姓名与工资
select ename,sal from emp where deptno=20 and sal>2000;
2.查询10号部门有上级领导的员工姓名与工资和领导编号
select ename,sal,mgr from emp where deptno=10 and mgr is not null;
3.查询20号部门或者工资大于2000的员工姓名与工资和领导编号
select ename,sal,mgr from emp where deptno=20 or sal>2000;
比较运算符 > < >= <= = !=和<>
1.查询职位是manager的所有员工和职位
select ename,job from emp where job=‘manager’;
select empno,ename,sal from emp where sal<=1600;
select empno,ename,deptno from emp where deptno!=10 and sal<3000;
select job,ename,deptno from emp where deptno=30 or mgr=7698;
模糊查询 like相似,喜欢
%代表0个或者多个未知字符
_:代表1个未知字符
举例:
以a开头:a%
以b结尾:%b
第三个字符是m:_m%
包含x:%x%
第二个字符是x,倒数第三个字符是y:x%y
查询名字中包含a的员工姓名
select ename from emp where ename like ‘%a%’;
select ename,sal from emp where ename like ‘_l%’;
select ename,sak,job from emp where job like ‘%an%’ and sal>1500;
select * from t_item where sell_point like ‘%赠%’ and title like ‘dell’;
查询在两者之间 between之间 x and y 包含x,y
select ename,sal from emp where sal<3000 and sal>2000;
select ename,sal from emp where sal between 2000 and 3000;
select title,price from t_item where price between 50 and 100;
select ename,sal from emp where sal not between 50 and 100;
in
select * from emp where sal=800 or sal=1300 or sal=1500 or sal=5000;
select * from emp where sal in(800,1500,1300,5000);
select * from emp where sal not in(800,1500,1300,5000);
排序
order顺序 by 字段名 asc/desc
查询员工姓名和工资,按照工资升序排序
select ename,sal from emp order by;
select ename,sal,deptno from emp order by deptno desc,sal;
分页查询
- 格式:limit 跳过的条数,请求的条数 limit(页数-1)*条数,条数
- 请求第三页的10条数据 limit 20,10
- 请求第五页的8条数据 limit(5-1)*8,8
select * from emp order by sal desc limit 0,5;
select * from t_item order by price limit7,7;
数值计算 + - * / % 7%2和 mod(7,2)
select ename,sal,sal5 年终奖 from emp;
select num,price,numprice 总金额 from t_item;
select ename,sal,sal+5 涨薪 from emp;
日期相关函数
- SQL的helloworld
select “helloworld”;
1.获取当前系统时间
select now();
2.获取当前的年月日, current(当前)
select curdate();
3.获取当前的时分秒
select curtime();
4.从年月日时分秒钟提取年月日和提取时分秒
select time(now());
select date(now());
查询商品表中每个商品上传年月日
select date(created_time) from t_item;
4.提取时间分量 extract提取
select extract(year from now());
select extract(mouth 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);
5.日期格式化 - 格式:date_format(时间,格式)
- %Y 四位年 2019
- %y 两位年 19
- %m 两位月 03
- %c 一位月 3
- %d 日
- %H 24小时
- %h 12小时
- %i 分钟
- %s 秒
把now()转换成2019年03月21日 15点34分00秒
select date_format(now(),’%Y年%m月%d号 %H点%i分%s秒’);
6.把非标准时间格式转成标准时间格式 str_to_date(非标准字符串时间,格式)
select str_to_date(“21.03.2019 15:42:30”,"%d.%m.%Y %H:%i:%s");
ifnull()函数
- age = ifnull(x,y)如果x值为null,则age=y 不为null age=x
update emp set comm=ifnull(comm,1);
聚合函数
- 对多条数据进行统计查询 平均值 最大值 最小值 求和 统计数量
1.平均值 avg(字段名)
select avg(sal) from emp where deptno=10;
select avg(comm) from emp ;
2.最大值 max(字段名)
3.最小值min(字段名)
4.求和sum(字段名)
5.统计数量count(字段名)
select count(*) from emp where deptno=20;
字符串相关函数
1.字符串拼接 concat(s1,s2)
select ename,concat(sal,‘元’) from emp;
2.获取字符串的长度 char_length(str)
select ename.char_length(ename) from emp;
3.获取字符串在另外一个字符串中出现的位置
select instr(‘abcdefgd’,‘d’);
select locate(‘d’,‘abcdefgd’);
4。转大写,转小写
selcet upper(‘nba’),lower(‘abC’);
5.截取字符串
- 左边截取: left(str,count);
- select left(‘abcdefg’,2);
- 右边截取:right(str,count);
- 自由截取:substring(str,start,length);
- select substring(‘abcdefg’,2);
- select substring(‘abcdefg’,2,3);
- 6.去空白:trim(str)
- select trim(" a b ")
- 7.重复 repeat(str,count);
- select repeat(“恩恩恩恩”,20);
- 8.替换 replace(str,old,new)
- select replace(‘abc abc’,‘c’,‘m’);
- 9.反转 reverse(str)
- select reverse(‘abc’);
作业
案例:查询没有上级领导的员工的编号,姓名,工资
select empno,ename,sal from emp where mgr is null;
案例:查询emp表中没有奖金的员工的姓名,职位,工资,以及奖金
select job,ename,sal,comm from emp where comm is null or comm=0;;
案例:查询emp表中含有奖金的员工的编号,姓名,职位,以及奖金
select empno,ename,job,comm from emp where comm>0;
案例:查询含有上级领导的员工的姓名,工资以及上级领导的编号
select ename,sal,mgr from emp where mgr is not null;
案例:查询emp表中名字以‘S’开头的所有员工的姓名
select ename from emp where ename like ‘s%’;
案例:查询emp表中名字的最后一个字符是’S’的员工的姓名
select ename from emp where ename like ‘%s’;
案例:查询倒数的第2个字符是‘E’的员工的姓名
select ename from emp where ename like ‘%e_’;
案例:查询emp表中员工的倒数第3个字符是‘N’的员工姓名
select ename from emp where ename like ‘%n__’;
案例:查询emp表中员工的名字中包含‘A’的员工的姓名
select ename from emp where ename like ‘%a%’;
案例:查询emp表中名字不是以’K’开头的员工的所有信息
select * from emp where ename not like ‘k%’;
案例:查询emp表中名字中不包含‘A’的所有员工的信息
select * from emp where ename not like ‘%a%’;
案例:做文员的员工人数(job 中 含有 CLERK 的) select count(*) from emp where job like ‘%clerk%’;
案例:销售人员 job: SALESMAN 的最高薪水
select max(sal) from emp where job like ‘SALESMAN’;
案例:最早和最晚入职时间
select max(hiredate),min(hiredate) from emp;
案例:查询类别 163的商品总库存量
select sum(num) from t_item where category_id=163;
案例:查询 类别 163 的商品
select * from t_item where category_id=163;
案例:查询商品价格不大于100的商品名称列表
select title from t_item where price<=100;
案例:查询品牌是联想,且价格在40000以上的商品名称和价格
select title,price from t_item where title like ‘%联想%’ and price>40000;
案例:查询品牌是三木,或价格在50以下的商品名称和价格
select title,price from t_item where title like ‘%三木%’ or price<50;
案例:查询品牌是三木、广博、齐心的商品名称和价格
select title,price from t_item where title like ‘%三木%’ or title like ‘%广博%’ or title like ‘%齐心%’;
案例:查询品牌不是联想、戴尔的商品名称和价格
select title,price from t_item where title not like ‘%联想%’ and title not like ‘%戴尔%’;
案例:查找品牌是联想且价格大于10000的名称
select title from t_item where title like ‘%联想%’ and price>10000;
案例:查询联想或戴尔的电脑名称列表
select title from t_item where title like ‘%联想%’ or title like ‘%戴尔%’;
案例:查询卖点含有’赠’产品名称
select title from t_item where sell_point like ‘%赠%’;
案例:查询emp表中员工的编号,姓名,职位,工资,并且工资在1000~2000之间。
select empno,ename,job,sal from emp where sal between 1000 and 2000;
案例:查询emp表中员工在10号部门,并且含有上级领导的员工的姓名,职位,上级领导编号以及所属部门的编号
select deptno,ename,job,mgr from emp where deptno=10 and mgr is not null;
案例:查询emp表中名字中包含’E’,并且职位不是MANAGER的员工的编号,姓名,职位,以及工资。
select empno,ename,job,sal from emp where ename like ‘%e%’ and job not like ‘%MANAGER%’;
案例:查询emp表中10号部门或者20号部门中员工的编号,姓名,所属部门的编号
select empno,ename,deptno from emp where deptno=10 or deptno=20;
案例:查询emp表中没有奖金或者名字的倒数第2个字母不是T的员工的编号,姓名,职位以及奖金
select empno,ename,job,sal from emp where comm is null or ename not like ‘%t_’;
案例:查询工资高于3000或者部门编号是30的员工的姓名,职位,工资,入职时间以及所属部门的编号
select hiredate,ename,job,sal,deptno from emp where sal>3000 or deptno=30;
案例:查询不是30号部门的员工的所有信息
select * from emp where deptno !=30;
案例:查询奖金不为空的员工的所有信息
select * from emp where comm is not null;
案例:查询emp表中所有员工的编号,姓名,职位,根据员工的编号进行降序排列
select * from emp order by empno desc;
案例:查询emp表中部门编号是10号或者30号中,所有员工姓名,职务,工资,根据工资进行升序排列
select ename,job,sal from emp where deptno=10 or deptno=30 order by sal;
案例:查询emp表中所有的数据,然后根据部门的编号进行升序排列,如果部门编号一致,根据员工的编号进行降序排列
select * from emp order by deptno,empno desc;
案例:查询emp表中工资高于1000或者没有上级领导的员工的编号,姓名,工资,所属部门的编号,
以及上级领导的编号,根据部门编号进行降序排列,如果部门编号一致根据工资进行升序排列。
select ename,empno,sal,deptno,mgr from emp where sal>1000 or mgr is null order by deptno desc,sal;
案例:查询emp表中名字中不包含S的员工的编号,姓名,工资,奖金,根据工资进行升序排列,如果工资一致,根据编号进行降序排列
select ename,empno,sal,comm from emp where ename not like ‘%s%’ order by sal,empno desc;
案例:统计emp表中员工的总数量
select count() from emp;
案例:统计emp表中获得奖金的员工的数量
select count() from emp where comm>0;
案例:求出emp表中所有的工资累加之和
select sum(sal)from emp;
案例:求出emp表中所有的奖金累加之和
select sum(comm)from emp;
案例:求出emp表中员工的平均工资
select avg(sal) from emp;
案例:求出emp表中员工的平均奖金
select avg(comm) from emp;
案例:求出emp表中员工的最高工资
select max(sal) from emp;
案例:求出emp表中员工编号的最大值
select max(deptno) from emp;
案例:查询emp表中员工的最低工资。
select min(sal) from emp;
案例:查询emp表中员工的人数,工资的总和,平均工资,奖金的最大值,奖金的最小值,并且对返回的列起别名。
select count(*) 员工人数,sum(sal) 工资总和,avg(sal) 平均工资,max(comm) 奖金最大值,min(comm) 奖金最小值 from emp;
数字相关函数
1.向下取整floor(num)
select floor(3.8);
2.四舍五入 round(num)
select round(23.8);
3.四舍五入round(num,m)
select round(23.879,2);
4.非四舍五入 truncate(num,m) m代表小数位数
select truncate(23.879,2);
5.随机数 rand()
select floor(rand()*3+3);’/
分组查询 group by
1.查询每个部门的平均工资
select deptno,avg(sal) from emp group by deptno;
select deptno,count() from emp group by deptno;
select max(sal) from emp where sal>1000 group by deptno;
select count() from emp where mgr is not null group by mgr;
select avg(sal) from emp group by deptno,job;
salect deptno,count(),sum(sal) from emp group by deptno order by count(),sum(sal) desc;
select deotno,avg(sal),min(sal),max(sal) from emp where sal between 1000 and 3000 group by deptno order by avg(sal);
select count(),sum(sal),avg(sal) from emp where mgr is not null group by job order by count() desc,avg(sal);
having
-
where后面只能写普通字段的条件,不能写聚合函数的条件
-
吧聚合函数的条件写在having后面
-
各个关键字的顺序
-
select … from … where … group by … having … order by … limit…;
-
select avg(price) from t_item group by category_id having avg(price)<100;
-
select avg(price) from t_item where category_id in(238,917) group by category_id;
-
select count(*),extract(year from hiredate) from emp group by dept;
-
select avg(sal) from emp group by deptno order by avg(sal) desc limit 0,1;
-
select max(sal) from emp;
-
select * from emp where sal>(select avg(sal) from emp);
-
select * from emp where sal>(select max(sal) from emp where deptno=20);
-
select * from emp where job=(select job from emp where ename=‘jones’) and ename!=‘jones’;
-
select * from emp where deptno=(select deptno from emp where sal=(select min(sal) from emp)) and ename!=(select ename from emp where sal=(select min(sal) from emp));
-
select * from emp where deptno=(select deptno from emp having max(sal)) and sal!=(select min(sal) from emp);
-
select * from emp having min(hiredate);
-
select * from emp where hiredate=(select max(hiredate) from emp);
-
select deptno from emp where ename=‘king’;
-
select dname from dept where deptno=(select deptno from emp where ename=‘king’);
-
select deptno from emp;
-
select * from dept where deptno in(select deptno from emp);
-
select avg(sal) from emp group by deptno order by avg(sal) desc limit 0,1;
-
select deptno from emp group by deptno having avg(sal)=(select avg(sal) from emp group by deptno order by avg(sal) desc limit 0,1);
-
select * from dept where deptno=(select deptno from emp group by deptno having avg(sal)=(select avg(sal) from emp group by deptno order by avg(sal) desc limit 0,1));
子查询总结
可以嵌套无数层
子查询可写的位置:
1.把子查询写在where或者hvaing后面,当成查询条件的值
2.写在创建表的时候
create table emp_20 sa(select *from emp where deptno=20);
3.写在from后面,当成一张虚拟的表 必须有别名
select ename from (select * from emp where deptno=20) newtable;
关联查询
- 同时查询多张表的数据的查询方式称为关联查询
1.查询每一个员工的员工姓名和对应的部门名称
select e.ename.d.ename
from emp e,dept d
where e.depeno=d.deptno;
等值连接和内连接
1.等值连接:select * from A,B where A.x=B.x and A.age=18;
2.内连接:select * from A join B on A.x=B.x where A.age=18;
select e.ename,d.dname
from emp e join dept d
on e.deptno=d.deptno;
外连接
- 外连接查询到的是一张表的全部数据和另外一张表的交集数据;
select * from A left/reght [outer] join B on A.x=B.x where A.age=18;
select e.ename,d.dname
from emp e right join dept d
on e.deptno=d.deptno;
关联查询总结
1.查询方式有三种:等值连接,内连接,外连接;
2.如果查询的数据是两张表的交际数据使用等值数据或内连接(推荐)
3.如果查询的数据是
每个部门的人数,根据人数降序排序
select count() from emp group by deptno order by count() desc;
每个部门中,每个主管的手下人数
select count(),deptno from emp group by deptno,mgr;
每种工作的平均工资
select job,avg(sal) from emp group by job;
每年的入职人数
select count() from emp group by extract(year from hiredate);
少于等于3个人的部门信息
select e.ename,d.* from emp e right join dept d on e.deptno=d.deptno group by deptno having count()<=3;
拿最低工资的员工信息
select * from emp where sal=(select min(sal) from emp);
只有一个下属的主管信息
select * from emp where empno in(select mgr from emp where mgr is not null group by mgr having count(mgr)=1);
每月发工资最多的部门信息
select * from dept where deptno=(select deptno from emp group by deptno order by sum(sal) desc limit 0,1);
select * from dept where deptno in(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 emp where empno=(select mgr from emp group by mgr order by count(mgr) desc limit 0,1);
select count() from emp group by mgr order by count(mgr) desc limit 0,1;
select mgr from emp group by mgr having count()=(select count() from emp group by mgr order by count(mgr) desc limit 0,1);
select * from emp where empno in(select mgr from emp group by mgr having count()=(select count() from emp group by mgr order by count(mgr) desc limit 0,1));
拿最高工资员工的同事信息
select deptno 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 sal!=(select max(sal) from emp);
和最后入职的员工在同一部门的员工信息 实现流程和第十题一样
select deptno 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 hiredate!=(select max(hiredate) from emp);
查询平均工资高于20号平均工资的部门信息
select * from dept where deptno in(select deptno from emp group by deptno having avg(sal)>(select avg(sal) from emp where deptno=20));
查询员工信息和员工对应的部门名称
select e.,d.dname from emp e join dept d on e.deptno=d.deptno;
查询员工信息,部门名称,所在城市
select e.,d.dname,loc from emp e join dept d on e.deptno=d.deptno;
查询Dallas市所有的员工信息
select * from emp where deptno=(select deptno from dept where loc=‘Dallas’);
计算每个城市的员工数量
select d.loc,count(e.ename) from dept d left join emp e on d.deptno=e.deptno group by d.loc;
查询员工信息和他的主管姓名
select e1.,e2.ename from emp e1 join emp e2 on e1.mgr=e2.empno;
员工信息,员工主管名字,部门名
select e1.,e2.ename,d.dname from emp e1 join emp e2 join dept d on e1.mgr=e2.empno and e1.deptno=d.deptno;
员工名和他所在部门名
select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno;
案例:查询emp表中所有员工的姓名以及该员工上级领导的编号,姓名,职位,工资
select e1.,e2.ename,e2.empno,e2.job,e2.sal from emp e1 left join emp e2 on e1.mgr=e2.empno;
案例:查询emp表中名字中没有字母’K’的所有员工的编号,姓名,职位以及所在部门的编号,名称,地址
select e.deptno,e.ename,e.job,e.empno,dname,d.loc from emp e join dept d on e.deptno=d.deptno where e.ename not like ‘%k%’;
案例:查询dept表中所有的部门的所有的信息,以及与之关联的emp表中员工的编号,姓名,职位,工资
select d.,e.empno,e.ename,e.job,e.sal from dept d left join emp e on d.deptno=e.deptno;
表设计值关联关系
一对一
- 什么是一对一:有AD两张表,A表中一条数据对应B表一条数据,同时B表一条也对应A表的一条数据,这种关系成为一对一
- 应用场景:用户表和用户信息拓展表;
- 如何建立关系:在从表中添加建立关系的字段(外键)指向主表的主键
- 联系:
1.创建用户表
create table user(id int primary key auto_increment,username varchar(10),password varchar(10));
create table userinfo(user_id int,nick varchar(10),mobile varchar(15));
2.插入一下数据
insert into user values(null,‘liubei’,‘admin’),(null,‘libai’,‘123456’),(null,‘张飞’,‘abcd’);
insert into userinfo values(1,‘刘备’,‘13838383388’),(2,‘李白’,‘13535355533’),(3,‘张飞’,‘13333333333’);
一对多
- 什么是一对多:有AB两张表,A表中一条数据对应B表中的多条数据,同时B表中的一条数据对应A表的一条数据,称为一对多。
- 场景:员工表和部门表,商品表和商品分类
- 如何建立关系:在多的表中添加外键指向另一张表的主键
- 练习:
1.创建员工表和部门表
create table t_emp(id int primary key auto_increment,name varchar(10),dept_id int);
create table t_dept(id int primary key auto_increment,name varchar(10));
2.插入数据
insert into t_dept values(null,‘神仙’),(null,‘妖怪’);
insert into t_emp values(null,‘悟空’,1),(null,‘八戒’,1),(null,‘蜘蛛精’,2),(null,‘白骨精’,2);
select e.name,d.name from t_emp e join t_dept d on e.dept_id=d.id;
select e.name from t_emp e join t_dept d on e.dept_id=d.id;
多对多
- 什么是多对多:有AB两张表,A表中一条数据对应B表中的多条数据,同时B表中的一条数据也对应A表中的多条数据,称为多对多
- 场景:老师表和学生表
- 如何建立关系,通过单独的关系表保存两张表的主键
- 练习:
1.创建表
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,did int);
2.插入数据
insert into teacher values(null,‘苍老师’),(null,‘传奇哥’);
insert into student values(null,‘小明’),(null,‘小红’),(null,‘小绿’),(null,‘小黄’);
insert into t_s values(1,1),(1,2),(1,3),(2,1),(2,4);
select s.name,t.name
from teacher t join t_s ts
on t.id=ts.tid
join student s
on ts.did=s.id;
select s.name
from teacher t join t_s ts
on t.id=ts.tid
join student s
on ts.did=s.id where t.name=‘苍老师’;
select t.name
from teacher t join t_s ts
on t.id=ts.tid
join student s
on ts.did=s.id where s.name=‘小明’;
###表设计案例:权限管理 - 总共有三张主表:用户表,角色表,权限表 关系表:用户-角色,角色-权限
- 创建表
- create table user(id int primary key auto_increment,name varchar(10));
- create table role(id int primary key auto_increment,name varchar(10));
- create table module(id int primary key auto_increment,name varchar(10));
- create table u_r(uid int,rid int);
- create table r_m(rid int,mid int);
- insert into user values(null,‘刘德华’),(null,‘罗玉凤’);
- insert into role values(null,‘男游客’),(null,‘男管理员’),(null,‘女会员’),(null,‘女管理员’);
- insert into module (name) values(‘男浏览’),(‘男发帖’),(‘男删帖’),(‘女浏览’),(‘女发帖’),(‘女删帖’);
- insert into u_r values(1,2),(2,4),(2,1);
- insert into r_m values(1,1),(2,1),(2,2),(2,3),(3,4),(3,5),(4,4),(4,5),(4,6);
- select u.name,r.name from user u join u_r ur join role r on u.id=ur.uid and r.id=ur.rid;
- select u.name,m.name from user u join u_r ur join role r join r_m rm join module m on u.id=ur.uid and r.id=ur.rid and r.id=rm.rid and m.id=rm.mid;
- select m.name from user u join u_r ur join role r join r_m rm join module m on u.id=ur.uid and r.id=ur.rid and r.id=rm.rid and m.id=rm.mid where u.name=‘刘德华’;
- select u.name from user u join u_r ur join role r join r_m rm join module m on u.id=ur.uid and r.id=ur.rid and r.id=rm.rid and m.id=rm.mid where m.name=‘男浏览’;
create table Trade(ID int primary key auto_increment,Time date,money int,name varchar(10),type varchar(10),pid int);
create table person(ID int primary key auto_increment,name varchar(10),gender varchar(10),rel varchar(5));
视图view
- 什么是是图标:数据库中表和视图都是其内部的对象,视图可以理解成一张虚拟的表,数据来自原表,视图本质其实就是取代了一段sql查询语句
- 为什么使用视图:视图可以起到sql重用的效果,提高开发效率,可以隐藏敏感信息
- 格式:
create view 视图名 sa (子查询);
create view emp_10 as (select * from emp where deptno=10);
create view emp_20 as (select * from emp where deptno=10);
create view emp_nosal as (select empno,ename,job,mgr,comm from emp);
create view emp_info as (select deptno,avg(sal),max(sal),min(sal),sum(sal),count(*) from emp group by deptno);
视图分类
1.简单视图:创建视图的子查询不包括:去重,函数,分组,关联查询 的视图称为简单视图,可以对视图中的数据进行增删改查操作
2.复杂视图:和简单视图相反,只能对复杂视图的数据进行查询操作
对简单视图进行增删改操作
1.插入数据
create view emp_10 as (select * from emp where deptno=10);
insert into emp_10 (empno,ename,deptno) values(10010,‘Tom’,10);
insert into emp_10 (empno,ename,deptno) values(10011,‘Jerry’,20);
- 数据污染:往视图中插入一条视图中不可见,但是在原表中可见的数据称为数据污染
- 如果不希望出现数据污染可以使用with check option解决
create view v_emp_30 as (select * from emp where deptno=30) with check option;
insert into v_emp_30 (empno,ename,deptno) values(10012,‘Lily’,30);
insert into v_emp_30 (empno,ename,deptno) values(10013,‘Lucy’,10);
2.删除和修改
只能对视图中存在的诗句进行操作
delete from v_emp_30 where deptno=10;
delete from v_emp_30 where ename=‘Lily’;
update emp_10 set ename=‘abc’ where empno=10010;
update emp_10 set ename=‘abc’ where empno=10011;
修改视图
格式:create or reolacr view 视图名 as (子查询);
create or replace view v_emp_30 as (select * from emp where deptno=30 and comm>0);
删除视图
- 格式:drop view 视图名;
视图别名
- 如果创建视图的子查询中使用了别名那么对视图进行操作时只能使用别名
create view v_emp_30 as (select ename name,deptno from emp where deptno=20);
delete from v_emp_30 where ename=‘xxx’;
约束
- 什么是越是:约束就是给表字段添加限制条件
非空约束 not null
create table t1(id int,age int not null);
- 测试:
insert into t1 values(1,20);
insert into t1 (id) values(1);
唯一约束 unique
create table t2(id int,age int unique);
- 测试:
insert into t2 values(1,20);
insert into t2 (id) values(1);
默认约束 default
主键约束:primary key唯一且非空
- 外键约束:值可以为null,可以重复,但不能是关系表中不存在的数据,如果建立好关系后,被依赖的数据不能先删除,被依赖的表不能先删除
- 如何使用:
1.创建部门表
create table mydept(id int primary key auto_increment,name varchar(10));
2.创建员工表
create table myemp(id int primary key auto_increment,name varchar(10),dept_id int,constraint fk_dept foreign key (dept_id) references mydept(id)); - 格式介绍:
- constraint 约束名 foreign key(外键字段名)references被依赖的表名
- 插入数据
- insert into mydept values(null,‘神仙’),(null,‘妖怪’);
- 测试
insert into myemp values(null,‘悟空’,1);
insert into myemp values(null,‘赛亚人’,3);
delete from mydept;
drop table mydept;
drop table myemp;
drop table mydept; - 外键约束工作中除非特定场景经,一般使用外键的机会较少,因为添加外键后影响测试效率
索引
- 什么是索引:索引是数据库中提高查询效率的技术,类似字典中的目录
- 为什么使用索引:如果不使用索引查询数据时会挨个遍历每一个磁盘块查询数据,使用索引后,磁盘块会以树状结构保存,查询数据时能够大大的降低磁盘块的访问量,从而提高查询效率
有索引一定好吗? 不是,如果数据量小,使用索引反而会降低查询效率
如何使用索引:
准备数据 导入测试数据 source d:/item_backup.sql
测试没有索引的情况下 查询速度 select * from item2 where title=‘100’; //耗费1.06秒
创建索引格式: create index 索引名 on 表名(字段(字段长度));
通过title字段创建索引 create index iitemtitle on item2(title);
再次测试查询速度 select * from item2 where title=‘100’; //耗费0.02秒
索引是越多越好吗? 不是,因为索引会占用存储空间,只针对常用的查询字段创建索引
如何查看索引 show index from item2;
索引分类:(了解) 聚集索引: 给表添加主键约束后自动创建的索引,索引的树桩结构中保存着数据 非聚集索引:通过非主键字段创建的索引,索引的树桩结构中没有数据保存的是主键值,通过非聚集索引找到主键值后还需要去聚集索引中查询具体数据
删除索引 drop index 索引名 on 表名; drop index iitemtitle on item2;
复合索引 通过多个字段创建的索引 create index iitemtitle_price on item2(title,price);
索引总结
索引是用来提高查询效率的技术,类似目录
因为索引会占用磁盘空间索引不是越多越好,只针对常用的查询字段创建索引
如果数据量小添加索引会降低查询效率,所以不是有索引就一定好
事务
- 数据库中执行同一业务多条SQL语句的工作单元,可以保证多条SQL全部执行成功或全部执行失败
- 事务的ACID特性
- ACID特性是保证事务正确执行的四大基本要素
- Atomicity:原子性, 最小不可拆分,保证全部成功或全部失败
- Consistency:一致性,从一个一致状态到另外一个一致状态
- Isolation:隔离性,多个事务之间互不影响
- Durability:持久性,当事务提交后持久保存到磁盘中
事务的相关指令
- 开启事务 begin
- 提交事务 commit
- 回滚事务 rollback
- 保存回滚点 savepoint xxx;
- 回滚到某个回滚点 rollback to xxx;
group_concat()组连接
查询每个部门的员工姓名和对应的工资,要求部门信息显示到一行
10 张三:3000 李四:4000
select deptno,group_concat(ename,’-’,sal) from emp group by deptno;
create table student(id int primary key auto_increment,name varchar(10),subject varchar(10),score int);
insert into student (name,subject,score) values(‘张三’,‘语文’,66),(‘张三’,‘数学’,77),(‘张三’,‘英语’,55),(‘张三’,‘体育’,77),(‘李四’,‘语文’,59),(‘李四’,‘数学’,88),(‘李四’,‘英语’,78),(‘李四’,‘体育’,95),(‘王五’,‘语文’,75),(‘王五’,‘数学’,54),(‘王五’,‘英语’,98),(‘王五’,‘体育’,88);
select name,avg(score) from student group by name order by avg(score) desc;
select name,group_concat(subject,’-’,score) from student group by name;
select name,max(score),min(score) from student group by name;
select name,count(score),concat(subject,’-’,score) from student where score<60 group by name;