当前位置:网站首页>Mysql从0到1的完全深入学习--阶段二---基础篇

Mysql从0到1的完全深入学习--阶段二---基础篇

2022-06-11 18:19:00 C_x_330

Hi,我是Cx_330

基础篇

DDL

🥯数据库

  • create database if not exists tb_1;

  • create database tb_1 default charset utf8mb4;

    不建议设置为utf8,因为utf8存储的长度就是三个字节,(也就是说一个汉字就三个字节),但是在数据库当中有一些字符占四个字节的,所以推荐使用utf8mb4,他是支持4个字节的

  • drop database if exists tb_1;

  • use tb_1;

  • select database();

🥫表结构

  • 先进入一个数据库 show tables;

  • 查询某个表结构 des user;

    • 在这里插入图片描述
  • 查询表结构 desc tb_1;

  • 查询指定表的建表语句 show create table tb_1

  • 添加字段 alter table tb_1 add math double(4.1) comment ‘数学成绩’;

  • 修改某个字段的类型 alter table tb_1 modify math varchar(5);

  • 修改某个字段类型和字段名 alter table tb_1 change math English double(5,2);

  • 删除字段 alter table tb_1 drop math;

  • 修改表名 alter table 表名 rename to 新表明

  • 删除表 drop table tb_1;

  • 删除表中所有数据内容并重新创建该表 truncate table tb_1;

数据类型

在这里插入图片描述


  • 字符类型

    • char(10) 定长
    • varchar(10) 变长
  • 日期类型

    • DATE 3 YYYY-MM-DD
    • TIME 3 HH:MM:SS
    • DATETIME 8 YYYY-MM-DD HH:MM:SS
  • 123.45

    • 标度(小数位数) 2
    • 精度(整个长度) 5
  • age tinyint unsigned;

  • score double(4,1)

    • 4 代表这个小数总长度为 4
    • 1 代表这个小数的小数点后有 1位
//小练
create table tb_employee(
     id int,
     wordId char(10),
     name varchar(10),
     gender char(1),
     age int unsigned,
     InCard char(18),
     workTime date
     );

DML

  • 插入数据时,字符串和日期类型应该包含在引号中

insert into tb_1 values(…)

update tb_1 set 字段名=值1,字段名2=值2… where …

不带where表示修改全部

delete from tb_1 where…;

不带where表示是删除这个表中的所有数据


DQL

  • 去除重复记录 select distinct 字段列表 from 表名

  • 判断是否为空 where is (not) null

  • 不等于 != <>

  • between A and B  包含A和B  
    select age from cx_330_01 where age between 11 and  22;
    
  • select * from tb_1 where age in(1,2,3,4);

  • 查询姓名两个字的信息 select * from tb where name like ‘__’;[这个是两个下划线]

  • 查询最后一个名字是杰的信息 select * from tb where name like ‘%杰’


聚合函数

  • 作用于某一纵列
  • select 聚合函数(字段值) from tb;
  • 所有的null值不参与聚合函数的运算
  • avg max min count sum

分组查询

  1. select addr,count(*) addr_count from tb where age <45 group by addr having addr_count >3
  • 执行顺序 where >group by >having
  1. where 与 having 区别
  • 执行时机 where分组前 having分组后
  • 判断条件 where不能对聚合函数判断 having 可以
  1. 为什么where不能对聚合函数判断?

​ 因为where是在分组前判断的,而聚合函数是在分组的时候在执行的

  1. 排序

    select * from tb order by age (asc) ,entrydate desc;

  2. 分页查询

    查询第二页员工数,每页显示10条

    select * from limit 10 10;

    • 第一个参数10 (页码数-1)*查询数
    • 第二个参数是 要查询的数目
  3. DQL编写顺序

    select
    	字段列表
    from 
    	表明列表
    where 
    	条件列表
    group by
    	分组字段列表
    having 
    	分组后条件列表
    order by
    	排序字段列表
    limit
    	分页参数
    
  4. DQL执行顺序

    from 
    	表明列表
    where 
    	条件列表
    group by
    	分组字段列表
    having 
    	分组后条件列表
    select
    	字段列表
    order by
    	排序字段列表
    limit
    	分页参数
    
  5. 练手

    查询性别为男,年龄在20-40岁(含)以内的前五个员工的信息,年龄升序,年龄相同按入职降序

    select *from user where gender='男'and age between 20 and 40 order by age,entrydate desc  limit 5 
    

DCL

用户操作

  • 查询用户

    use mysql;

    select * from user;

  • 创建用户

    create user ‘用户名’@‘主机名’ identified by ‘密码’

    create user 'lianjie'@'%'
     identified by '123456'; 
     --在任意的主机都可以访问这个数据库
    
  • 修改用户密码

    alter user ‘用户名’@‘主机名’ identified with mysql_native_password by ‘新密码’;

  • 删除用户

    drop user ‘用户名’@‘主机名’

权限操作

所有权限查询数据插入数据修改数据删除数据修改表删除数据库/表/视图创建数据库/表
Allselectinsertupdatedeletealterdropcreate
  • 多个权限之间,使用 , 分开
  • 授权时 数据库名和表名 可以用 * 代替
  1. 查询权限

    show grants for ‘用户名’@‘主机名’

  2. 授予权限

    grant 权限列表 on 数据库名.表名 to ‘用户名’@‘主机名’

  3. 撤销权限

    revoke 权限列表 on 数据库名.表名 from ‘用户名’@‘主机名’


函数

字符串函数

select 函数(参数)

  • concat(s1,s2,s3…)

    将s1,s2,s3…这些字符串拼接为一个字符串

  • lower(s)

    将s字符串中所有字符转为小写

  • upper(s)

    将s字符串中所有字符转为大写

  • lpad(str,n,pad)

    在str左边添加pad直到长度为n

  • rpad(str,n,pad)

  • trim(s)

    去掉字符串s头部尾部的空格

  • substring(str,start,len);

    返回从str第start位置起len个长度的字符串

小案例

update user set id=lpad(id,5,0);


数值函数

  • ceil(x)

    向上取整

  • floor(x)

    向下取整

  • mod(x,y)

    返回x%y的模

  • rand()

    返回0~1内的随机数

  • round(x,y)

    返回参数x四舍五入后的值,保留y位小数

通过数据库函数生成一个六位数的随机数

lpad(round(rand()*1000000,0),6,0);

日期函数

  • curdate()

    当前的 年-月-日

  • curtime()

    当前时间 h: m: s

  • now()

    当前的 年- 月- 日 时:分:秒

  • year(now())

  • month(now())

  • day(now())

    分别单独的获取当前的 年 月 日

  • date_add(now(),interval,数值,类型)

    在当时间往后推 数值个时间单位

  • datediff(时间1,时间2)

    求取两个时间相差的天数 时间1-时间2 可能为负

  • 小练手

    查询所有员工的入职天数,并且按倒叙排

    select name,datediff(curdate(),entrydate) as 'workedTima' from user order by workedTima desc
    

流程函数

  • if(flag,v1,v2)

    flag为true返回v1 为假返回v2

  • ifnull(v1,v2)

    只有当v1为 null 才返回v2否则返回v1 🧈注意:‘’ 空字符串不为 null

  • case when then else end

    • 🥮小案例

      查询员工姓名和工作地址,若是北京,上海的话显示一线城市,其他城市都显示二线城市

      select 
      	name,
      	(case cityaddr when '北京' then '一线城市' when '上海' then '一线城市' else '二线城市' 		end) as ciryLevel 
      from
      	user;
      
  • 🥮小案例

    统计各班成绩(语文 数学 英语),>=85 优秀 >=60及格 否则 不及格

    -- 解析1
    select 
    	name
    	(case score when score>=85 then '优秀' when score between 60 and 84 then '及格'
    	else then '不及格' end) as grade; 
    from
    	student;
    
    
    -- 解析2
    select 
    	name
    	(case score when score>=85 then '优秀' when score >=60 then '及格'else then '不及格' end) 		as grade; 
    from
    	student;
    

    有的小伙伴可能看到了,我这两个有略微的差异,解法1的那个优点费劲,解法2相对更清爽。

    其实这个when then when then 当多个when then 连用的时候 就相当于java中的 if()else if ()else()

  • 🥮小案例

    如何快速计算入职天数

    select 
    	name,
    	(datediff(curdate(),entryDate))as workedDays
    from
    	user;
    

约束

  • 约束可以在建表修改表时添加

    约束描述关键字
    非空不为nullnot null
    唯一每个数据不重复unique
    主键非空 唯一 唯一标识primary key
    默认默认值default
    检查保证字段值满足某限制条件check
    外键使两表联系 数据一致 完整foreign key

    age int check(age>0&&age<120)

  • 自动增长

    auto_increment


外键约束

创建外键语法

--创表时
constraint 外键名称 foreign key 外键字段名 references 主表 主表列名

--创表后
alter table 表名 add constraint 外键名称 foreign key 外键字段名 references 主表 主表列名 

外键删除更新行为

  • cascade 父表中主键值删除/更新时,子表中外键也对应自动的删除/更新
  • set null 父表中删除主键对应记录时 子表中外键自动设为null(子表这个外键要关闭 not null的性质)
--cascade 的设置
alter table 表名 add constraint 外键名称 foreign key 外键字段名
references 主表 主表列名 on update cascade on delete cascade

--set null的设置
alter table 表名 add constraint 外键名称 foreign key 外键字段名
references 主表 主表列名 on update set null on delete set null

多表查询

  • 消除无效的笛卡尔积

连接查询

内连接
  • A B交集

  • 隐式内连接

    select
    	tb1.name
    	tb2.age
    from
    	tb1,
    	tb2
    where 
    	tb1.id=tb2.id
    	
    	
    -- 注意
    select
    	t1.name
    	t2.age
    from
        --起别名
    	tb1 t1,
    	tb2 t2
    where 
    	--起完别名后就不能用之前的名字来查找字段 必须用别名 否则会报错 
    	--原因是DQL的执行顺序 from 先于 where from进行完后别名已经生效了
    	t1.id=t2.id
    	
    
  • 显式内连接

    select
    	tb1.name
    	tb2.age
    from
    	tb1 join tb2 
    on 
    	tb1.id=tb2.id
    
外连接
  • 左外连接

    查询左表所有数据以及交集部分

  • 右外连接

    查询右表所有数据以及交集部分

    select
    	tb1.name,tb2.name
    from
    	tb1 left
    join tb2
    on
    	tb1.id=tb2.id;	
    
自连接
  • 当前表与自身的连接查询 自连接必须使用表别名

  • 小案例

    查询员工的姓名及其对应领导的姓名

    在这里插入图片描述

    --内连接
    select 
    	a.name ,
    	b.name
    from
    	tb a,
    	tb b
    where
    	a.id=b.managerid
    

    查询所有员工姓名及其领导姓名 没有领导也要查询出来

    --外连接
    select
    	a.name,
    	b.name
    from 
    	emp a left
    join emp b
    on
    	a.managerid=b.id		
    

联合查询

union、union all

select * from tb1 
union  
select * from tb2 	
  • select 后面的 列数必须保持一致 字段类型也必须保持一致

  • union 保诚没有重复

  • union all 查询出来的可能有重复

子查询

sql语句中嵌套select语句 嵌套查询 子查询

子查询外部的语句可以是 select insert update delete 任何一个

子查询的位置

  • where后
  • from后
  • select后

子查询的结果

  • 单个值标量子查询

    • 小测试

      查询入职日期晚于小明的员工

      select *from user where entrydate>(select entrydate from user where name='小明')
      
  • 一行

    常用操作符 = <> in not in

    • 小练手

      查询与小明的薪资及所属领导相同的员工信息

      select *from emp
      where (name,managerid) = (select name,managerid from emp where name ='小明')
      
  • 一列

    常用的操作符 in not in

    any 子查询返回列表中 有任意一个满足即可

    some 与any等同

    all 子查询返回的结果中所有的值都必须满足

    • 小练手

    查询比财务部所有人员工资都高的员工信息

    --方案一 max()
    select * from emp
    where salary >
    (select max(salary) from emp
    where id =
    select id from dept
    where name='财务部')
    
    --方案二 all()
    select * from emp
    where salary >
    all(
    (select salary from emp
    where id =
    select id from dept
    where name='财务部')
      );
    
  • 多行多列

    常用操作符 in

    有时会将子查询结果(表)作为from的对象

    • 小案例

      查询入职日期在‘2016-3-3’之后的员工信息,及其部分信息

      select e.* d.name from
      (select entrydate from emp where entrydate > '2016-3-3') e dept d
      where e.id =d.id
      
综合案例
  • demo1

    查询拥有员工的部门id和名称

    默认细节:去除重复

    select distinct d.id,d.name from dept d emp e 
    where d.id=e.id
    
  • demo2

    查询所有年龄大于40的员工信息,并且展示所属部分,若没有部分也要显示员工信息

    select e.* , d.name from emp e left join dept d
    on e.id=d.id where e.age>40
    
  • demo3

    查询研发部所有员工信息及工资等级

    select e.*, s.grade from emp e 
    join dept d on e.id=d.id where d.name='研发部'
    join sace s on e.salary between s.low and s.high 
    
  • demo4

    查询研发部的平均工资

    select avg(e.salary) 
    from 
    	emp e,dept d where e.id=d.id and d.name='研发部'
    
  • demo5

    查询低于本部分平均工资的员工信息

    --查询1号部分平均工资
    select avg(e.salary) from emp e where e.deptid=1
     
    select e1.*from emp e1 where e1.salary< 
    (select avg(e2.salary) from emp e2 where e2.deptid=e1.deptid)
    
  • demo6

    查询所有部分信息,并统计部门人数

    --统计1号部门的人数
    select count(*) from emp where emp.deptid=1
    
    select d.name, (select count(*) from emp e where e.deptid=d.id) '人数' from dept d;
    

🧊事务

一组操作的集合。同成功或同失败

  • Mysql中事务默认提交 每执行完一条sql语句 mysql就将修改后的数据自动提交

  • Select @@autocommit

    查询事务提交方式

    • 0 手动提交
    • 1 自动提交
  • Set autocommit=0

    设置事务提交方式

  • 提交事务

    commit

  • 事务回滚

    rollback

  • begin/start transaction

🧊事务四大特性—ACAD

  • 原子性 事务是不可分割的最小操作单元,同成功 同失败
  • 一致性 事务完成时,必须使所有的数据都保持一致状态
  • 隔离性 数据库系统提供的隔离机制,保证事务在不受外部并发影响的独立环境中运行
  • 持久性 事务一旦提交或回滚,对数据库中的数据改变是永久的

🧊并发事务

  • 脏读 A读到B还没提交(commit)的数据
  • 不可重复读A事务提交之前,A先后读取同一条记录 但读取的数据不同
  • 幻读 A查询数据库时没查到但**插入(insert)**时又插不进去 发现又存在了

🧊事务的隔离级别

  • Mysql默认的事务隔离级别:Repeatable Read(默认)

    SeriaLizable:可以规避所有的并发问题,但是性能是最差的

    事物的隔离级别越高,数据越安全,但是性能越低

    在这里插入图片描述

  • 查看、设置事务隔离级别

    select @@transaction_isolation;
    
    set session(当前会话)/global  transaction isolation level 隔离级别种类
    

    在这里插入图片描述
    觉得有帮助的话,就支持一波吧!
    今日名言:每天都要坚持学习,默默的付出,一点点的前进,跌倒了在趴起来,一日又一日,一年又一年,为了大长梦,奋斗,拼搏,坚持!

原网站

版权声明
本文为[C_x_330]所创,转载请带上原文链接,感谢
https://blog.csdn.net/C_x_330/article/details/125201558