MySQL部分知识梳理回顾

左右内连接

--内连接
select s.StudentNo,StudentName,SubjectNo,StudentResult
from student s
inner join result r
on s.StudentNo = r.StudentNo

--左连接
select s.StudentNo,StudentName,SubjectNo,StudentResult
from student s
left join result r
on s.StudentNo = r.StudentNo

--右连接
select s.StudentNo,StudentName,SubjectNo,StudentResult
from student s
right join result r
on s.StudentNo = r.StudentNo

---查询缺考同学
select s.StudentNo,StudentName,SubjectNo,StudentResult
from student s
left join result r
on s.StudentNo = r.StudentNo
where StudentResult is NULL

--三表连接查询
select s.StudentNo,StudentName,SubjectNo,StudentResult,SubjectName
from student s
right join result r
on r.StudentNo = s.StudentNo
inner join subject sub
on r.SubjectNo = sub.SubjectNo

----from 表 xxx join 连接的表 on 交叉条件

自连接

一张表拆成两张一样的表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5QudLOjY-1618838002780)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210410140910463.png)]

---查询父子信息
select `categoryName` as `父栏目`,`categoryName` as `子栏目`
from `category` as a,`category` as b
where a.`categoryid` = b.`categoryid`

排序

---asc升序   desc降序
order by 字段名 asc/desc    

分页

  • 缓解数据库压力
  • 体验感更好,瀑布流应用

语法:limit(查询起始下标,pagesize)

网页应用:当前,总的页数,页面的大小

【pagesize:页面大小】

【(n-1)*pagesize:起始值】

【n:当前页】

【数据总数/页面大小=总页数】

每页显示五条

第一页: limit 0,5

第二页: limit 5,5

第三页: limit 10,5

---查询java第一学年课程成绩排名前十的学生并且分数要大于80的学生信息
select StudentNo,StudentName,StudentResult,SubjectName
from student s
inner join result r
on s.StudentNo = r.StudentNo
inner join subject sub
on r.SubjectNo = sub.SubjectNo
where SubjectName='Java第一学年' and StudentResult>=80 
order by StudentResult desc
limit 0,10

子查询和嵌套查询

where(这个值是计算出来的)

本质:在where语句中嵌套一个子查询语句

----1、查询数据库结构1的所有考试结果(学号,科目编号,成绩)降序排列
---方式一:使用连接查询
select StudentNo,SubjectResult,r.SubjectNo
from result r
inner join subject sub
on r.SubjectNo = sub.SubjectNo
where SubjectName = '数据库结构1'
order by SubjectResult desc

---方式二:使用子查询
select StudentNo,SubjectResult,SubjectNo
from result
where SubjectNo=(
select SubjectNo 
from subject
where SubjectName='数据库结构1'
)
order by SubjectResult desc

---查询数据库结构1的学生学号
select SubjectNo from subject where SubjectName='数据库结构1'

--分数不小于80分的学生的学号和姓名
select distinct s.StudentNo,StudentName
from student s
inner join result r
on r.StudentNo=s.StudentNo
where StudentResult > 80

--高等数学2编号分数不小于80分的学生的学号和姓名
select distinct s.StudentNo,StudentName
from student s
inner join result r
on r.StudentNo=s.StudentNo
where StudentResult > 80 and SubjectNo=(
   select SubjectNo 
   from subject 
   where SubjectName='高等数学2'
)

---查询课程编号高等数学2 分数不小于80分的学生的学号和姓名
select StudentNo,StudentName
from student 
where StudentNo IN(
    select StudentNo
    from result 
    where StudentResult > 80 AND StudentNo=(
    select SubjectNo 
    from subject 
    where SubjectName='高等数学2'
    )
)

Mysql函数

常用函数

----数学运算
select abs(-8)     ---绝对值
select Ceiling(9,4)    ---向上取整
select floor(9,4)  ---向下取整
select random()   ---返回一个0-1之间随机数
select sign()   ---判断一个数的符号  负数返回-1,正数返回1
----字符串函数
select char_length('天天开心')  ---字符串长度
select concat('w','a','n','m')   ---拼接字符串
select insert('我爱编程',1,2,'超级热爱')  ---查询,从某个长度开始替换某个长度
select lower('WWWW')   ----小写字母
select upper('wwww')    ----大写字母
select instr('qzvz','q')   ---返回第一次出现的字串的索引
select replace('努力就会成功','努力','坚持')    ----tihuan1
select substr('努力一定就会成功',4,5)  ---返回指定的字符串(源字符串,截取位置,截取长度)
select reverse('努力一定就会成功')   ---反转

---时间和日期函数
select current_date()    ---获取当前日期
select current()    ---获取当前日期
select now()   ---获取当前时间
select localtime  ---获取本地时间
select sysdate()  ---系统时间
select system_user()  ---当前系统用户
select version()   ---获取版本

聚合函数(常用)

函数名称描述
COUNT()计数
SUM()求和
AVG()平均值
MAX()最大值
MIN()最小值

having跟在group by后面

数据库级别的MD5加密

什么是MD5?

主要增强算法复杂度和不可逆性

MD5不可逆,具体的md5值也是一样

md5破解网站的原理,背后有一个字典,md5加密后的值,md5加密前的值

create table `testmd5`(
    `id` int(4) not null,
    `name` varchar(20) not null,
    `pwd` varchar(50) not null
    primary key(`id`)

)engine=innodb default charcet=utf8

---明文密码
insert into testmd5 values(1,'zhangsan','123456'),(1,'lisi','123456'),(1,'wangwu','123456')

---加密
update testmd5 set pwd=md5(pwd) where id=1    ---加密一行
update testmd5 set pwd=md5(pwd) ---加密全部密码

---插入时候加密
insert into testmd5 values(4,'zhangsan',md5('123456'))

如何校验,将用户传过来的密码,进行MD5加密,然后比对加密后的值

select * fromtestmd5 where name='xiaoming' and pwd=md5('123456')

事务

要么都成功,要么都失败

将一组sql放在一个批次中去执行

事务原则:ACID 原子性,一致性,隔离性,持久性 (脏读,幻读……)

**原子性:**针对一个事物

**一致性:**最终一致性,过程一致性,针对一个事务操作前后状态一致

**隔离性:**多个用户同时操作,主要是排除其他事务对本次事务的影响(互不干扰)

**持久性:**表示事务的结束状态不会随着外界原因导致数据丢失(事务未提交,恢复到原状,如果提交,持久化到数据库),事务一旦提交不可逆

隔离产生的问题

**脏读:**一个事务读取了另一个事务未提交的数据

**不可重复读:**在一个事务读取表中某一行数据时,多次读取结果不同

**幻读:**指在一个事务内读取了别人新插入的事务,导致前后读取不一致

执行事务

mysql默认开启事务,自动提交

set autocommit=0  关闭

set autocommit=1 开启
---事务开启
start transation   标记一个事务的开始,从这个之后的sql都在同一个事务内
insert  xx
insert  xx
---提交:持久化  (成功!)
commit
---回滚:回滚到原来样子(失败!)
rollback
---事务结束
set autocommit=1 开启自动提交
savepoint 保存点名   ---设置一个事物的保存点
rollback to savepoint 保存点名 ---回滚到保存点
release savepoint 保存点名   ---撤销保存点

模拟场景

---转账
create datebase shop character  set utf8 collate utf8_general_ci
use shop
create table account(
    `id` int(3) not null auto_increment,
    `name` varchar(10) not null,
    `money`  decimal(9,2) not null,
    primary key (`id`)
)engine=innerdb default charset=uf8

insert into account(`name`,`money`)
values('A',2000.00),('B',1000.00)

---模拟转账,开启事务
set autocommit=0;   ---关闭自动提交
start transactton   ---开启一个事务(一组事务)
update account set money=money-500 where `name`='A'  ---A减500
update account set money=money+500 where `name`='B'   ---B加500

commit;  ---提交事务,就被持久化
rollback;  ---回滚

set autocommit=1;    ---恢复默认值

索引介绍以及索引分类

MySQL官方对索引的定义为:索引是帮助MySql高效获取数据结构,提取句子主干,就可以得到索引的本质,索引是数据结构。

索引的分类

  • 主键索引 PRIMARY KEY :唯一标识,不可重复,只能有一个列作为主键
  • 唯一索引 UNIQUE KEY :避免重复的列出现,可以重复,多个列都可以是唯一索引
  • 常规索引 KEY/INDEX :默认的,index,key关键字设置
  • 全文索引 FULLTEXT :在特定的数据库引擎下才有,MYISAM,快速定位数据
---索引的使用
---1、在创建表的时候给字段增加索引
---2、创建完毕后,增加索引

---显示所有索引信息
show index from student
---增加一个索引(索引名) 列名
alter table school.student add fulltext  index `studentName`(`studentName`);

---EXPLAIN 分析sql执行的状况
explain select * from student ;   ---常规索引,非全文索引

select * from student where matce(studentName) against('刘')
  

测试索引

CREATE TABLE `app_user` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) DEFAULT'' COMMENT'用户昵称',
`email` VARCHAR(50) NOT NULL COMMENT'用户邮箱',
`phone` VARCHAR(20) DEFAULT'' COMMENT'手机号',
`gender` TINYINT(4) UNSIGNED DEFAULT '0'COMMENT '性别(0:男;1:女)',
`password` VARCHAR(100) NOT NULL COMMENT '密码',
`age` TINYINT(4) DEFAULT'0'  COMMENT '年龄',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT = 'app用户表'

---插入100万条数据
DELIMITER $$
CREATE FUNCTION mock_data()
RETURNS INT
DETERMINISTIC
BEGIN
 DECLARE num INT DEFAULT 1000000;
 DECLARE i INT DEFAULT 0;
 WHILE i < num DO
  INSERT INTO app_user(`name`,`email`,`phone`,`gender`,`password`,`age`)VALUES(CONCAT('用户',i),'24736743@qq.com',CONCAT('18',FLOOR(RAND()*(999999999-100000000)+100000000)),FLOOR(RAND()*2),UUID(),FLOOR(RAND()*100));
  SET i = i + 1;
 END WHILE;
 RETURN i;
END $$
SELECT mock_data() -- 执行此函数 生成一百万条数据

select * from app_user where name='用户99999';
 
 ---id_表名_字段名
 ---create index 索引名 on 表(字段)
create index id_app_user_name on app_user(`name`);
select * from app_user where name='用户99999';

索引在小数据的时候,用处不大,但是大数据的时候,非常明显

索引原则

  • 索引不是越多越好
  • 不要对进程变动数据加索引
  • 小数据量的表不需要加索引
  • 索引一般在常用来查询的字段上

索引的数据结构

Hash 类型的索引

Btree:InnoDB的默认数据结构

用户管理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3v4es1WP-1618837941097)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210413144443425.png)]

SQL命令

用户表:mysql.user
本质:对这张表进行增删改查
---创建用户   create user 用户名 identified by 密码
create user zhangsan identified by '123456'


--修改密码(修改当前用户)
set password=password('111111')


--修改密码(修改指定用户)
set password for 用户 =password('密码')

---给用户重命名  rename user 原名 to 新名字
rename user zhangsan to lisi

---用户授权  grant all privileges授予全部权限  库.表
---grant all privileges授予全部权限 除了给别人授权不能做
grant all privileges on *.* to lisi

---查看权限
show grant for lisi    ---查看指定用户权限
show grant for root@localhost

---撤销权限
revoke all privileges on *.* from 用户


---删除用户
drop user 用户名

数据库备份

  • 保证重要数据不丢失
  • 做数据转移

MySQL数据库备份的方式

  • 直接拷贝物理文件

  • 在可视化工具sqlyog中手动导出

    在想要导出的表或者库中,右键选择备份或者导出

    选中sql转储

  • 使用命令行导出 mysqldump 命令行使用

# mysqldump -h主机 -u用户 -p密码  数据库 表名  ->物理磁盘位置/文件名
mysqldump -hlocalhost -uroot -p123456 school student   ->D:/a.sql
# mysqldump -h主机 -u用户 -p密码  数据库 表1 表2 表3  ->物理磁盘位置/文件名
mysqldump -hlocalhost -uroot -p123456 school student teacher result  ->D:/b.sql
# mysqldump -h主机 -u用户 -p密码  数据库->物理磁盘位置/文件名
mysqldump -hlocalhost -uroot -p123456 school ->D:/c.sql


---导入
先登录数据库
use 数据库
source 备份文件
source d:/a.sql

规范数据库设计

当数据库表比较复杂时候,就需要设计了

糟糕的数据库设计:

  • 数据冗余,浪费空间
  • 数据插入删除都会麻烦,异常【屏蔽使用物理外键】
  • 程序的性能差

良好的数据库设计:

  • 节省内存空间
  • 保证数据完整性
  • 方便我们开发系统

软件开发中,关于数据库的设计

  • 分析需求:分析业务需要处理的数据库的需求
  • 概要设计:设计关系统E-R图

设计数据库步骤(个人博客)

  • 收集信息,分析需求

    ​ 用户表(用户登录注销,用户的个人信息,写博客,创建分类)

    ​ 分类表(文章分类,谁创建的)

    ​ 文章表(文章的信息)

    ​ 评论表

    ​ 友链表(友链信息)

    ​ 自定义表(系统信息,某个关键的字或者主字段) key:value

  • 标识实体(把需求落地到每个字段)

    写博客 user—>blog

    创建分类 user—>categoy

    关注 user—>user

    友链

    评论 user—>user blog

三大范式

  • 信息重复

  • 更新异常

  • 插入异常

    无法正常显示信息

  • 删除异常

    丢失有效的信息

三大范式

第一范式(1NF):

原子性,保证每一列不能再分

第二范式(1NF):

满足第一范式前提下,每张表只描述一件事情

第三范式(1NF):

满足第一范式和第二范式,第三范式需要确保表中的每一列数据和主见直接相关,而不是间接相关。

(规范数据库设计)

规范性和性能的问题

关联查询的表不得超过三张表

  • 考虑商业化的需求和目标(成本,用户体验)数据库的性能更加重要
  • 在规范性能的问题的时候,需要适当的考虑一下规范性
  • 故意给某些表增加一些冗余的字段(从夺标查询中变为单表查询)
  • 故意增加一些计算列(从大数据量降低为小数据量的查询;增加索引)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值