笔记-JavaWeb学习之旅3
数据库的设计
1.多表之间的关系
-
一对一
一对一关系实现,可以在任意一方添加唯一外键指向另一方的主键
-
一对多
在多的一方建立外键指向一的一方建立主键
-
多对多
多对多关系实现需要借助第三张中间表。中间表至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键
2.数据库设计的范式:不知道写什么,先跳过
数据库的备份与还原
命令行备份语法:mysqldump -u用户名 -p密码 >保存的路径
还原:
- 登录数据库
- 创建数据库
- 使用数据库
- 执行文件 source 文件路径
多表查询
创建两个表
-- constraint 外键名称 foreign key (外键列名称) references 主表名称(注表列名称) -- 外键列可以省略,系统会自动生成 -- 外键约束,删除被约束的数据的时候,要先删除外键,才可以删除主键, -- 外键约束,要添加被约束的数据的时候,要先添加主键数据,才可以添加外键 -- 外键约束,外键关联主键不可以关联不存在的数据 -- 外键约束,主键不可以重复,外键可以重复 select * from dept; select * from emp; drop table dept; drop table emp; # 创建部门表 # 主键表 create table dept( id int primary key auto_increment,-- id为int类型,主键约束并且自动增长 name varchar(20) -- name w为字符串类型 ); insert into dept (name) values ('开发部'),('市场部'),('财务部'); #创建员工表 # 外键表 create table emp( id int primary key auto_increment, name varchar(10), gender char(1), -- 性别 salary double, -- 工资 join_date date, -- 入职日期 dept_id int, foreign key (dept_id) references dept(id) -- 外键,关联部门表(部门表的主键) ); insert into emp(name,gender,salary,join_date,dept_id) values('孙悟空','男',7200,'2013-02-24',1); insert into emp(name,gender,salary,join_date,dept_id) values('猪八戒','男',3600,'2010-12-02',2); insert into emp(name,gender,salary,join_date,dept_id) values('唐僧','男',9000,'2008-08-08',2); insert into emp(name,gender,salary,join_date,dept_id) values('白骨精','女',5000,'2015-10-07',3); insert into emp(name,gender,salary,join_date,dept_id) values('蜘蛛精','女',4500,'2011-03-14',1);
然后执行下面查询语句
select * from emp,dept;
什么?竟然出现了15条数据
这是笛卡尔积:就是有两个集合a,b,取这两个集合的所有组成情况。
多表查询的分类:1.内连接查询2.外连接查询3.子查询
内连接查询分为隐式内连接,显示内连接
用内连接来清楚无用的数据
-- 隐式内连接 -- 去除无用的数据 -- 不加上emp.`dept_id` = dept.`id`;的话会出现15条数据 select * from emp,dept wher不e emp.`dept_id` = dept.`id`; -- 只显示部分需要的数据 select emp.name,emp.gender,dept.name from emp,dept where emp.`dept_id`=dept.`id`; -- 显示内连接 -- 语法 select 字段列表 from 表名1 [inner] join 表名2 on 条件 select * from emp join dept on emp.dept_id = dept.id;
外连接
现在新来了一个员工,小白龙,但是没有给他添加部门
insert into emp(name,gender,salary) values('小白龙','男',3000);
有个需求,要求查询所有员工信息,有部门的,则查询部门名称,没有部门的,不显示部门名称,
可以通过外连接来实现这个需求
-- 左外连接语法:select 字段列表 from 表1 left [outer] join 表2 on 条件; -- 查询的是左表的所有数据以及交集部分 -- 左表就是left左边的那个表就是左表 select emp.*,dept.`name` from emp left join dept on emp.`dept_id` = dept.`id`;
-- 右外连接 select 字段列表 from 表1 right [outer] join 表2 on 条件;
子查询
-
子查询的结果是单行单列的
子查询的结果可以作为条件,使用运算符去判断
-
子查询的结果是多行单列的
子查询的结果可以作为条件,使用in运算符去判断
-
子查询的结果是多行多列的
子查询可以作为虚拟表
-- 自查询的结果是单行单列的 -- 查询结果只有单行单列 select max(salary) from emp;-- 子查询 -- 查询员工信息,并且工资等于9000的 select * from emp where emp.salary =9000; -- 一套sql语句完成操作 select * from emp where emp.`salary` = (select max(salary) from emp); -- 查询员工工资小于平均工资的 select * from emp where emp.salary < (select avg(salary) from emp);
-- 自查询的结果是多行单列的 -- 查询财务部所有员工信息 -- 先把财务部的id显示出来 select id from dept where name ='财务部';-- 子查询 -- 然后通过主键id找到关联的外键 select * from emp where dept_id=3; -- 查询财务部和市场部所有员工信息 select id from dept where name ='财务部' or name='市场部'; select * from emp where dept_id=3 or dept_id=2; -- 查询结果是多行但列的,子查询的结果可以使用in运算符 select * from emp where dept_id in (3,2);
-- 子查询的结果是多行多列的 -- 子查询可以作为虚拟表 -- 查询员工入职日期是2011-11-11之后的员工信息和部门信息 -- 先获取入职日期的子查询 select * from emp where emp.`join_date` > '2011-11-11'; -- 子查询 -- 查询结果是多行多列的, select *from dept t1,(select * from emp where emp.`join_date` > '2011-11-11') t2 where t1.id=t2.dept_id; -- 不加上id相等的限定条件的话,会发生笛卡尔积,会显示6条语句
多表查询练习
献上代码,我自己对着视频手敲的,视频没有给源码,感兴趣的可以拿去练习
create database db3; -- 部门表 create table dept( id int primary key primary key, -- 部门id dname varchar(50), -- 部门名称 loc varchar(50) -- 部门所在地 ); -- 添加4个部门 insert into dept(id,dname,loc) values (10,'教研部','北京'), (20,'学工部','上海'), (30,'销售部','广州'), (40,'财务部','深圳'); -- 职务表,职务名称,职务描述 create table job( id int primary key, jname varchar(20), description varchar(50) ); -- 添加4个职务 insert into job(id,jname,description) values (1,'董事长','管理整个公司,接单'), (2,'经理','管理部员工'), (3,'销售员','向客人推销产品'), (4,'文员','使用办公软件'); -- 员工表 create table emp( id int primary key, -- 员工id ename varchar(50), -- 员工姓名 job_id int, -- 职务id mgr int, -- 上级领导 joindate date, -- 入职日期 salary decimal(7,2), -- 工资 bonus decimal(7,2), -- 奖金 dept_id int, -- 所在部门编号 constraint emp_jobid_ref_job_id_fk foreign key(job_id) references job (id), constraint emp_deptid_ref_dept_id_fk foreign key(dept_id) references dept (id) ); -- 添加员工 insert into emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) values -- 这里不知道什么原因报错,我一次性插入多条数据会报错,我是一条一条插入,然后二条,三条,插入,他才没有报错 -- (1001,'孙悟空',4,1004,'2000-12-17','8000.00',null,20); -- (1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30); -- (1003,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30); -- (1004,'唐僧',2,1009,'2001-04-02','29750.00',null,20); -- (1005,'李逵',4,1006,'2001-09-28','12500.00','14000',30); -- (1006,'宋江',2,1009,'2001-05-01','28500.00',null,30); -- (1007,'刘备',2,1009,'2001-09-01','24500.00',null,10); -- (1008,'猪八戒',4,1004,'2007-04-01','30000.00',null,20), -- (1009,'罗贯中',1,null,'2001-11-19','50000.00',null,10); -- (10010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30), -- (10011,'沙僧',4,1004,'2007-05-23','11000.00',null,30); (10012,'李逵',4,1006,'2001-12-03','9500.00',null,20), (10013,'小白龙',4,1004,'2001-12-03','30000.00',null,20), (10014,'关羽',4,1007,'2002-01-23','13000.00',null,10); -- 工资等级表 create table salarygrade( grade int primary key, -- 级别 losalary int, -- 最低工资 hisalary int -- 最高工资 ); -- 添加五个工资等级 insert into salarygrade(grade,losalary,hisalary) values (1,7000,12000), (2,12010,14000), (3,14010,20000), (4,20010,30000), (5,30010,99990);
第一个练习
select * from emp; select * from job; -- 查询所有员工信息,查询员工编号,姓名工资和职务名称,职务描述 -- 难度在于去除重复数据,若不加这条语句t1.job_id = t2.id;会有56条语句产生 -- 原因在于一个表有14行数据,一个表有4行数据,他们会全部一一匹配 select t1.id, t1.ename, t1.salary, t2.jname, t2.description from emp t1,job t2 where t1.job_id = t2.id;
第二个练习
-- 查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置 -- t1 表跟t2 ,t3表都有主键约束 -- 只是比上一个列子多了一个表,还是一样的办法 select t1.id, t1.ename, t1.salary, t2.jname, t2.description, t3.dname, t3.loc from emp t1, job t2 ,dept t3 where t1.job_id = t2.id and t1.dept_id = t3.id;
第三个练习
-- 查询员工姓名,工资,工资等级 select t1.ename, t1.salary, t2.* from emp t1 ,salarygrade t2 where t1.salary between t2.losalary and t2.hisalary;
第四个练习
-- 查询员工姓名,工资(来自emp表),职务名称,职务描述(来自job表),部门名称,部门位置(来自dept表),工资等级(来自salarygrae表) select t1.ename, t1.salary, t2.jname, t2.description, t3.dname, t3.loc, t4.grade from emp t1,job t2,dept t3,salarygrade t4 where t1.job_id=t2.id -- 员工与职务 and t1.dept_id = t3.id -- 员工与部门 and t1.salary between t4.losalary and t4.hisalary;
第五个练习
-- 查询出部门编号,部门名称,部门位置,部门人数 -- 部门编号,部门名称,部门位置,这三个可以通过dept表查到,部门如数需要把他当成一个整体分组查询,把部门当做字段查询 select t1.id,t1.dname,t1.loc,t2.total from dept t1, (select dept_id,count(id) total from emp group by dept_id) t2 -- 获得每一个部门的人数,涉及到了聚合函数和分组查询 where t1.id = t2.dept_id;
第六个练习
-- 查询所有员工的姓名及其直接上级的姓名,没有领导员工也要查询 select t1.ename, t1.mgr, t2.id, t2.ename from emp t1 left join emp t2 on t1.mgr=t2.id;
事务
-
事务的基本介绍
操作:
- 开启事务: start transaction;
- 回滚:rollback;
- 提交:commit;
mysql数据库中事务的默认自动提交
事务提交有两种方式:
自动提交:mysql是自动提交的,一条dml(增删改)语句就会自动提交一次事务
手动提交:oracle数据库是默认提交事务的
需要先开启事务,在提交
-
事务的四大特征
- 原子性:是不看分割的最小操作单位,要么同事成功,要么同事失败
- 持久性:当事务提交或回滚后,数据库会持久化保存数据
- 隔离性:多个事务之间,相互独立
- 一致性:事务操作前后,数据总量不变
事务的隔离级别
dcl:管理用户,授权
管理用户:
添加用语法:create user '用户名'@'主机名' identified by '密码';
删除用户语法:drop user '用户名'@'主机名';
-
修改用户密码:
update user set password = password('新密码') where user = '用户名';或 set password for '用户名'@'主机名' = password(新密码);
-
查询用户:切换到mysql数据库(use mysql);然后查询数据表(select*from user);
通配符 : % 表示可以在任意主机使用用户登录数据库
权限管理
- 查询权限:show grants for '用户名'@'主机名';
- 授予权限:grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';
- 撤销权限:revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';
推荐阅读
-
C学习笔记(3)---作用域,数组, (少量指针入门)
-
pygame学习笔记(3):运动速率、时间、事件、文字
-
HTML5学习笔记简明版(3):新元素之hgroup,header,footer,address,nav
-
vue.js 学习笔记3——TypeScript
-
Orleans[NET Core 3.1] 学习笔记(三)( 3 )服务端配置
-
荐 opencv进阶学习笔记3:像素运算和图像亮度对比度调节
-
MVC使用Spring.Net应用IOC(依赖倒置)学习笔记3
-
Python学习笔记整理3之输入输出、python eval函数
-
Flutter学习笔记(3)--Dart变量与基本数据类型
-
libtorch学习笔记(3)- 一些基本概念