MySQL基础

该文档是:MySQL数据库笔记正式开启...

博客连接:https://www.loveuluo.cn

日期:2020-11-19

1. 数据库概述和初始化

1.1 sql、DB、DMBS分别是什么

image-20201119141106146

1.2 什么是表

image-20201119141921615

1.3 SQL语句的分类

image-20201119142341573

1.4 导入初始数据

导入练习用的演示数据(bjpowernode.sql文件):

image-20201119143623742

image-20201119144552971

1.5 source命令的作用

可以批量执行sql语句,不需要打开该文件。

image-20201119143809907

1.6 删除数据库

删除数据库:drop database bjpowernode(数据库名);

1.7 查看表结构

image-20201119145929111

1.8 查看表中的数据

image-20201119150046316

2. 常用命令(了解即可)

image-20201119150657912

3. 基础SQL语句

3.1 简单的查询语句(DQL)

image-20201119151308017

image-20201119151344793

image-20201119151406360

3.2 条件查询

image-20201119152336395

image-20201119155612492

image-20201119155734139

image-20201119155743613

image-20201119155800941

image-20201119155816842

3.3 条件查询中的模糊查询

image-20201119161446457

image-20201119162327869

3.4 排序

image-20201119163448056

image-20201119164507345

3.5 单行处理函数

特点:进去多少行结果还是多少行。

image-20201119165636169

3.6 分组函数/聚合函数/多行处理函数

特点:最初是多行,结果变成一行。

image-20201119170436397

image-20201119184429402

运用了子查询:

image-20201119185122346

3.7 分组查询

group by 和having:

image-20201119191815973

image-20201119191918291

image-20201119192320317

3.8 总结一个完整的DQL语句怎么写

image-20201119192921115

3.9 查询结果的去重

image-20201121094820527

4. 连接查询

4.1 什么是连接查询

image-20201121095408575

4.2 连接查询的分类

image-20201121100014283

4.3 笛卡尔积现象

image-20201121101956425

image-20201121102008305

4.4 内连接

4.4.1 内连接中的等值连接

最大特点是:条件是等量关系。

image-20201121102659873

image-20201121102713589

4.4.2 内连接中的非等值连接

image-20201121103607516

image-20201121103616764

4.4.3 内连接中的自连接

image-20201121105319133

image-20201121105330997

4.5 外连接

4.5.1 什么是外连接

4.5.2 案例一

image-20201121143616235

image-20201121143642259

4.5.3 案例二

image-20201121145828274

4.6 多表连接

4.6.1 案例一

image-20201121151717273

image-20201121151741048

4.6.2 案例二

image-20201121152525018

5. 子查询

5.1 什么是子查询

image-20201121153402342

5.2 where子句中使用子查询

image-20201121153822635

5.3 from后面嵌套子查询(非常重要)

5.3.1案例一

image-20201121164912697

5.3.2 案例二(不是from后边嵌套子查询,回顾之前的案例)

image-20201121164959381

5.4 在select后面嵌套子查询(了解即可)

image-20201121171346977

6. union

image-20201121185345366

image-20201121185314891

7. limit (超级重点)

7.1 limit语法机制

image-20201121190953010

7.2 执行顺序

image-20201121191015438

7.3 案例:找出工资排名在第4到第9名的员工?

image-20201122094056522

7.4 Java的通用标准分页sql

image-20201122094134729

8. 创建表

8.1 创建表

image-20201122101643809

image-20201122101652683

8.2 向表中插入数据

因为表没有设置默认值是什么,所以默认值默认是null:

image-20201122103537903

创建表 并把sex字段的默认值设为1,如果不给值的话默认就是1:

image-20201122103604438

image-20201122103809164

8.3 表的复制

image-20201122110226275

8.4 将查询结果插入到一张表中

表结构得相同才行:

image-20201122110502888

8.5 修改表中的数据

image-20201122110857393

8.6 删除表中的数据,删除大表(重点)

image-20201122121233685

8.7 修改表结构(了解即可)

对于表结构的修改,这里不讲了,大家使用工具完成即可,因为在实际开发中表一旦
设计好之后,对表结构的修改是很少的,修改表结构就是对之前的设计进行了否定,即使
需要修改表结构,我们也可以直接使用工具操作。修改表结构的语句不会出现在Java代码当中。
出现在java代码当中的sql包括:insert delete update select(这些都是表中的数据操作。)

增删改查有一个术语:CRUD操作
Create(增) Retrieve(检索) Update(修改) Delete(删除)

9. 约束(重点)

9.1 什么是约束

image-20201122123252171

9.2 非空约束

* 注意:not null约束只有列级约束。没有表级约束(只能加在字段后边)。

image-20201122123317307

9.3 唯一性约束

image-20201123100928441

9.4 主键约束

image-20201123101851877

image-20201123103456747

image-20201123103516309

自增主键(重要):

image-20201123104102003

9.5 外键约束

image-20201123142917833

image-20201123142930777

image-20201123143045991

10. 存储引擎(了解即可)

10.1 什么是存储引擎

image-20201123144527614

10.2 完整的建表语句

image-20201123144545444

10.3 查看当前mysql支持的存储引擎

image-20201123144834547

10.4 三个常见的存储引擎

image-20201123150643953

11. 事务(必须掌握)

11.1 事务的概念

image-20201123152742560

image-20201123154702027

11.2 事务的四大特性

image-20201123155156543

11.3 事务的四个隔离级别

image-20201123160406014

11.4 演示事务

image-20201123164744804

需要注意的是,begin 命令并不代表事务的开始,事务开始于 begin 命令之后的第一条语句执行的时候。例如下面示例中,select * from xxx 才是事务的开始,

begin;
select * from xxx; 
commit; -- 或者 rollback;

另外,通过以下语句可以查询当前有多少事务正在运行。

select * from information_schema.innodb_trx;

image-20201123162616657

关闭自动提交机制后(相当于开启事务直到使用回滚或者提交才会结束事物):

image-20201123162737344

11.5 演示4种隔离级别

初始表:

用一张表来做一下验证,表结构简单如下:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT NULL,
  `age` tinyint(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

初始只有一条记录:

mysql> SELECT * FROM user;
+----+-----------------+------+
| id | name            | age  |
+----+-----------------+------+
|  1 | 古时的风筝        |    1 |
+----+-----------------+------+

脏读

脏读指的是读到了其他事务未提交的数据,未提交意味着这些数据可能会回滚,也就是可能最终不会存到数据库中,也就是不存在的数据。读到了并一定最终存在的数据,这就是脏读。

可重复读

可重复读指的是在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据都是一致的。通常针对数据更新(UPDATE)操作。

不可重复读

对比可重复读,不可重复读指的是在同一事务内,不同的时刻读到的同一批数据可能是不一样的,可能会受到其他事务的影响,比如其他事务改了这批数据并提交了。通常针对数据更新(UPDATE)操作。

幻读

幻读是针对数据插入(INSERT)操作来说的。假设事务A对某些行的内容作了更改,但是还未提交,此时事务B插入了与事务A更改前的记录相同的记录行,并且在事务A提交之前先提交了,而这时,在事务A中查询,会发现好像刚刚的更改对于某些数据未起作用,但其实是事务B刚插入进来的,让用户感觉很魔幻,感觉出现了幻觉,这就叫幻读。

11.5.1 第一级别:读未提交

相当于两个窗口都开启事务(关闭自动提交机制),而其中一个插入一条数据但是不commit(提交),另一个窗口也能使用select语句查询到插入的数据。

MySQL 事务隔离其实是依靠锁来实现的,加锁自然会带来性能的损失。而读未提交隔离级别是不加锁的,所以它的性能是最好的,没有加锁、解锁带来的性能开销。但有利就有弊,这基本上就相当于裸奔啊,所以它连脏读的问题都没办法解决。

任何事务对数据的修改都会第一时间暴露给其他事务,即使事务还没有提交。

下面来做个简单实验验证一下,首先设置全局隔离级别为读未提交。

set global transaction isolation level read uncommitted;

设置完成后,只对之后新起的 session 才起作用,对已经启动 session 无效。如果用 shell 客户端那就要重新连接 MySQL,如果用 Navicat 那就要创建新的查询窗口。

启动两个事务,分别为事务A和事务B,在事务A中使用 update 语句,修改 age 的值为10,初始是1 ,在执行完 update 语句之后,在事务B中查询 user 表,会看到 age 的值已经是 10 了,这时候事务A还没有提交,而此时事务B有可能拿着已经修改过的 age=10 去进行其他操作了。在事务B进行操作的过程中,很有可能事务A由于某些原因,进行了事务回滚操作,那其实事务B得到的就是脏数据了,拿着脏数据去进行其他的计算,那结果肯定也是有问题的。

顺着时间轴往表示两事务中操作的执行顺序,重点看图中 age 字段的值。

preview

读未提交,其实就是可以读到其他事务未提交的数据,但没有办法保证你读到的数据最终一定是提交后的数据,如果中间发生回滚,那就会出现脏数据问题,读未提交没办法解决脏数据问题。更别提可重复读和幻读了,想都不要想。

11.5.2 第二级别:读已提交

既然读未提交没办法解决脏数据问题,那么就有了读提交。读提交就是一个事务只能读到其他事务已经提交过的数据,也就是其他事务调用 commit 命令之后的数据。那脏数据问题迎刃而解了。

读提交事务隔离级别是大多数流行数据库的默认事务隔离界别,比如 Oracle,但是不是 MySQL 的默认隔离界别。

我们继续来做一下验证,首先把事务隔离级别改为读提交级别。

set global transaction isolation level read committed;

之后需要重新打开新的 session 窗口,也就是新的 shell 窗口才可以。

同样开启事务A和事务B两个事务,在事务A中使用 update 语句将 id=1 的记录行 age 字段改为 10。此时,在事务B中使用 select 语句进行查询,我们发现在事务A提交之前,事务B中查询到的记录 age 一直是1,直到事务A提交,此时在事务B中 select 查询,发现 age 的值已经是 10 了。

这就出现了一个问题,在同一事务中(本例中的事务B),事务的不同时刻同样的查询条件,查询出来的记录内容是不一样的,事务A的提交影响了事务B的查询结果,这就是不可重复读,也就是读

preview

每个 select 语句都有自己的一份快照,而不是一个事务一份,所以在不同的时刻,查询出来的数据可能是不一致的。

读提交解决了脏读的问题,但是无法做到可重复读,也没办法解决幻读。

11.5.3 第三级别:可重复读

可重复是对比不可重复而言的,上面说不可重复读是指同一事物不同时刻读到的数据值可能不一致。而可重复读是指,事务不会读到其他事务对已有数据的修改,及时其他事务已提交,也就是说,事务开始时读到的已有数据是什么,在事务提交前的任意时刻,这些数据的值都是一样的。但是,对于其他事务新插入的数据是可以读到的,这也就引发了幻读问题。

同样的,需改全局隔离级别为可重复读级别。

set global transaction isolation level repeatable read;

在这个隔离级别下,启动两个事务,两个事务同时开启。

首先看一下可重复读的效果,事务A启动后修改了数据,并且在事务B之前提交,事务B在事务开始和事务A提交之后两个时间节点都读取的数据相同,已经可以看出可重复读的效果。(以下的图片只要事务b没有提交,他读取到的是备份的数据,而不是文件中的数据,因为事务A已经提交并且将硬盘中的文件修改,而事务B显示的结果还是之前的,这就是可重复度

preview

可重复读做到了,这只是针对已有行的更改操作有效,但是对于新插入的行记录,就没这么幸运了,幻读就这么产生了。我们看一下这个过程:

事务A开始后,执行 update 操作,将 age = 1 的记录的 name 改为“风筝2号”;

事务B开始后,在事务执行完 update 后,执行 insert 操作,插入记录 age =1,name = 古时的风筝,这和事务A修改的那条记录值相同,然后提交。

事务B提交后,事务A中执行 select,查询 age=1 的数据,这时,会发现多了一行,并且发现还有一条 name = 古时的风筝,age = 1 的记录,这其实就是事务B刚刚插入的,这就是幻读。

preview

11.5.4 第四级别:串行化

串行化是4种事务隔离级别中隔离效果最好的,解决了脏读、可重复读、幻读的问题,但是效果最差,它将事务的执行变为顺序执行,与其他三个隔离级别相比,它就相当于单线程,后一个事务的执行必须等待前一个事务结束。

12. 索引

12.1 什么是索引

image-20201123193256934

12.2 怎么创建索引

image-20201123193333180

12.3 索引的实现原理

image-20201123193359680

image-20201123193427654

12.4 索引的分类

image-20201123193511730

12.5 索引什么时候失效?

image-20201123193557281

....

13. 视图(了解即可)

image-20201123194310867

14. 数据库数据的导入导出

image-20201123195155888

15. 数据库设计三范式(重点内容)

需要背下来:多对多? 三张表,关系表两个外键 。 一对多?两张表,多的表加外键。

提醒:在实际的开发中,以满足客户的需求为主,有的时候会拿冗余换执行速度。(面试加分项)

image-20201124093311238

16. 一对一设计

image-20201124094051118

最后修改:2021 年 01 月 06 日 10 : 46 AM
如果觉得我的文章对你有用,请随意赞赏