这是我参与「第五届青训营 」笔记创作活动的第19天
基础
概述
数据库(DB)存储数据的仓库,数据时有组织的进行存储
数据库管理系统(DBMS),操控和管理数据库的大型软件
SQL ->操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准
mysql的启动和关闭
1.win+r 然后输入services.mcs进入界面找到mysql80程序关闭
2.利用命令行
启动 net start mysql80
停止 net stop mysql80
注:mysql是开机自动启动的
mysql的客户端连接
方法一 用mysql提供的客户端
方法二 Windows的命令行 用系统自带的命令行工具执行指令
mysql([-h 1247.0.0.1][-p 3306]这一段可以不要,但是要配置环境变量) -u root -p
mysql的数据模型
关系型数据库(RDBMS)
mysql数据库就是一个关系型数据库,建立在关系模型上,由多张相互连接的二维表组成的数据库
优点:表存储,格式统一便于维护;使用SQL语言操作
SQL
分类
DDL(数据定义语言
定义数据库对象(数据库,表,字段
SHOW DATABASES; 查询所有数据库
SELECT DATABASES();查询当前数据库
CTEATE DATABASE[名字][字符集][排序规则];方括号中的可以省略,存在默认值
DROP DATABASE[]数据库名称
USE 数据库名字 切换到某个数据库中
SHOW TABLES;查询当前数据库中的所有表
DESC 表名; 查询表结构
SHOW CREATE TABEL表名
CREATE TABLE 表名(
字段1 字段1类型[注释];
字段2 字段2类型[注释];
字段3 字段3类型[注释];
)[表注释];
DDL-表修改-操作
ALTER TABLE表名 ADD 字段名 类型(长度)[comment 注释][约束];新增字段
ALTER TABLE表名 MODIFY 字段名 新数据类型(长度
修改字段数据类型
ALTER TABLE表明 CHANGE 旧字段名 新字段名 类型 [注释]
修改字段名称与数据类型
ALTER TABLE表名 DROP 字段
删除字段
ALTER TABLE 表名 RENAME TO 新表名
修改表名
DROP TABLE 表名
删除指定表
TRUNCATE TABLE表名;
删除指定表,并重新创建该表
DML(数据操作语言
对表中数据修改
DQL(数据查询语言
查询表中的记录
DCL(数据控制语言
创建数据库用户,控制数据库访问权限
图像化界面
Datagrip
函数
字符函数
-- 函数演示
-- concat 字符串拼接
select concat('hello' , 'mysql');
-- lower 全部字母小写
select lower('HellO');
-- upper 全部字母大写
select upper('hellO');
-- lpad 填充字符串到指定长度,l填充在前面,r填充在后面
select lpad('01',5,'-');
-- rpad
select lpad('01',5,'-');
-- trim去除空格--->仅仅是前面和后面的空格,中间不去
select trim(' hello MySQL ');
-- substring
select substring('Hello MySQL',1,5);
-- 把员工工号全部变为5位
update emp set workno = lpad(workno,5,0);
数值函数
-- ceil 向上取整
select ceil(1.1);
-- floor 向下取整
-- mod 求模运算
select mod(3,5); -- 3/5余几
-- rand随机数
select rand();
-- round 四舍五入,保留自定义位小数
select round(2.345,2);
-- 通过数据库的函数,生成一个六位的随机生成数
select lpad(round(rand()*1000000,0),6,'0');
日期函数
-- 日期函数
-- curdate()
select curdate();
-- curtime()
select curtime();
-- now()
select now();
-- year,month,day;
select year(now());
select month(now());
select day(now());
-- date_add() 在给定日期的上继续加上指定的天数和日期
select date_add(now(),interval 70 day );
-- datediff 日期天数差异,前面日期减去后面日期
select datediff('2021-12-1','2021-10-01');
-- 查询所有员工入职天数,并根据入职天数倒序排列
select name,datediff(curdate(),entrydate) df from emp order by df desc;
流程函数
-- 流程函数
-- if(value,t,f) -- value为true返回t否则返回f
select if(true ,'ok','Error');
-- ifnull(value1,value2) --value不为空,返回value1否则返回value2
select ifnull('ok','default');
select ifnull(null,'default');
-- case when [val1] then[res1]....else[default] end; value为true返回res1,...否则返回default
-- 需求:查询emp表的员工姓名和工作地址,如果地址为北京上海,---->一线城市,其他为二线城市
select
name,(
case workaddress when '北京' then '一线城市' when '上海' then '一线城市' else '二线城市' end) as '工作地址'
from emp;
-- case [expr] when[val1] then [res1] else [default] end; expr等于val1,返回res1,...否则返回default
create table score(
id int comment 'ID',
name varchar(20) comment '姓名',
math int comment '数学',
english int comment '英语',
chinese int comment '语文'
) comment '学员成绩表';
insert into score(id, name, math, english, chinese) VALUES (1, 'Tom', 67, 88, 95 ), (2, 'Rose' , 23, 66, 90),(3, 'Jack', 56, 98, 76);
-- 查询语句
select * from score;
select
id,
name,
(case when math >= 85 then '优秀' when math >= 60 then '及格' else '不及格' end) '数学',
(case when english >= 85 then '优秀' when english >= 60 then '及格' else '不及格' end)'英语',
(case when chinese >= 85 then '优秀' when english >= 60 then '及格' else '不及格' end)'语文'
from score;
约束
概念
就是作用于表中字段上的规则,用于限制存储在表中的数据
目的
保证数据库中的数据正确,有效性和完整性
外键约束
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id);
-- 删除外键
alter table emp drop foreign key fk_emp_dept_id;
-- 外键约束
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id) on update cascade on delete cascade;
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id) on update set null on delete set null ;
多表查询
多表关系
根据业务需求,分析性并设计表结构,表结构基本为以下三种:
一对多
例如员工和部门,一个员工一个部门,一个部门多个员工。
实现:多的一方建立外键,指向一的一方的主键
多堆多
例如:学生与课程,学生学多门课,一门课也可以拱多个学生选择
实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
一对一
例子:用户与用户详情的拆分
实际上就是单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率
实现:任意一方加入外键,关联另一方的主键,并且设置外键为唯一的(UNIQUE)
多表查询概述
一个非常普通的查询方式,直接查两个表
select * from emp,dept;
得到的结果引入新概念:笛卡尔积
笛卡尔积
数学中,两个集合A集合和B集所有的组合情况,因此,多表查询时,需要消除无效的笛卡尔积
消除笛卡尔积
select * from emp,dept where emp.dept_id = dept.id; -- 加入限定条件即可
连接查询
分为:内连接,外连接,自连接;
内连接
两张表交集部分
隐式内连接
-- 查询每一个员工的姓名,及关联部门的名称
-- 表结构 emp,dept;
-- 连接条件:emp.dept_id = dept.id
select emp.name,dept.name from emp,dept where emp.dept_id = dept.id;
显式内连接
-- 显示内连接的实现 ----- inner join ..... on...
-- 表结构 emp,dept;
-- 连接条件:emp.dept_id = dept.id
select e.name,d.name from emp e inner join dept d on e.dept_id = d.id;
外连接
和内连接的区别就在于,内连接包括的数据只有交集,但是外连接包括了除交集意外的左/右集合
左外连接
包括表1(左表)所有的数据,且包含表1和表2的交集数据
-- 查询 emp 所有数据,且对应部门信息
select e.*,d.name from emp e left outer join dept d on e.dept_id = d.id;
left outer join ... on ...
右外连接
包括表2(右表)所有的数据,且包含表1和表2的交集数据
select d.*,e.* from emp e right outer join dept d on e.dept_id = d.id;
自连接
案例:emp表查询员工及其领导
select a.name,b.name from emp a,emp b where a.managerid = b.id;
联合查询
-union, union all
就是把多次查询的结果合并起来,形成一个新的查询结果集
-- 薪资地狱5000 的员工,年龄大于50的员工,直接拼表
-- union 会去重 union all就是直接合并
select * from emp where salary < 5000
union
select * from emp where age > 50;
子查询
概念:SQL语句中嵌套SELECT语句,又称嵌套查询,又称子查询
标量子查询
-- 标量子查询
-- 返回的结果是单个值,常用操作符:= <> > < ....
-- 1.查询销售部所有的员工信息
select id from dept where name = '销售部';
select *from emp where dept_id = (select id from dept where name = '销售部');
-- 2.查询在房东白入职之后的员工信息
select entrydate from emp where name = '方东白';
select * from emp where entrydate > '2009-02-12';
select * from emp where entrydate > (select entrydate from emp where name = '方东白');
列子查询
-- 列子查询
-- 常用操作符 IN, NOT IN, ANY, SOME, ALL
-- 查询销售部和市场部的所有员工信息
select id from dept where name = '销售部' or name = '市场部';
select * from emp where dept_id in(select id from dept where name = '销售部' or name = '市场部');
-- 财讯比财务部所有人工资都高的员工信息
select id from dept where name = '财务部';
select salary from emp where dept_id = (select id from dept where name = '财务部');
select * from emp where salary > all (select salary from emp where dept_id = (select id from dept where name = '财务部'));
update emp set salary = 48000 where name = '周芷若';
-- 比研发部任意一人工资高的员工信息
select * from emp where salary > some (select salary from emp where dept_id = (select id from dept where dept.name = '研发部'));
行子查询
-- 行子查询
-- 查询与"张无忌"的薪资及直属领导相同的员工信息
-- a.查询张无忌的薪资与直属领导
select salary,managerid from emp where name = "张无忌";
-- b.查询与"张无忌的薪资与直属领导"相同的员工信息
select *from emp where (salary,managerid) = (select salary,managerid from emp where name = "张无忌");
表子查询
-- 表子查询
-- 查询与"鹿杖客","宋远桥"的职位和薪资相同的员工信息
select job, salary from emp where name = '鹿杖客' or name = '宋远桥';
select * from emp where (job,salary) in (select job,salary from emp where name = '鹿杖客' or name = '宋远桥');
-- 查询入职日期是'2006-01-01'之后的员工信息,即部门信息
select * from emp where entrydate >'2006-01-01';
select e.*,d.* from (select * from emp where entrydate >'2006-01-01') e left join dept d on e.dept_id = d.id;
子查询返回的结果是一张表
事物
事物是一组集合,是一个不可分割的工作单位,事物会把所有的操作作为一个整体一起向系统提交或撤销操作请求,这么操作要么同时成功,要么同时失败
例如:转账,张三转1000元给李四,是同一个事物,要么同时成功,要么同时失败
事物操作
- 查看和设置事物提交方式
-
select @@autocommit; -- 查看事物的提交方式是否为手动 set @@autocommit=0;
-
- 提交事物
-
commit
-
- 回滚事物
rollback
- 开始事务
-
start transaction; begin;
-
四大特性(ACID)
- 原子性:事务是不可分割的最小操作单元,要么全部成功,要么全部失败
- 一致性:事务完成时,必须使所有的数据都保持一致状态
- 隔离性:数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境运行
- 持久性:事务一旦提交或者回滚,对数据库中数据的改变就是永久的
并发事务所引发的问题
- 脏读
- 一个事务读取到另外一个事务还没有提交的数据
- 不可重复读
- 一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读
- 幻读
- 一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现幻影
事务隔离级别
隔离级别与安全性成正比,与效率成反比
查看隔离级别 select @@transaction_isolation
设置事务隔离级别* set [session|global] transaction isolation level {read uncommitted | read committed | repeatable read| serializable}