mysql数据库详解(四):基础知识

作为一个稀有的Java妹子,所写的所有博客都只是当作自己的笔记,留下证据自己之前是有用心学习的~哈哈哈哈(如果有不对的地方,也请大家指出,不要悄悄咪咪的不告诉我)

一、数据库三大范式

第一范式:每个列都不可以再拆分。
第二范式:在第一范式的基础上,非主键列完全依赖于主键,而不能是依赖于主键的一部分。
第三范式:在第二范式的基础上,非主键列只依赖于主键,不依赖于其他非主键。

二、MySQL存储引擎MyISAM与InnoDB区别

1、常用的存储引擎有以下:

Innodb引擎:Innodb引擎提供了对数据库ACID事务的支持。并且还提供了行级锁和外键的约束。它的设计的目标就是处理大数据容量的数据库系统。
MyIASM引擎(原本Mysql的默认引擎):不提供事务的支持,也不支持行级锁和外键。
MEMORY引擎:所有的数据都在内存中,数据的处理速度快,但是安全性不高。

/MyIASMInnodb
存储结构每张表被存储为三个文件,frm-表格定义、MYD(MYData)-数据文件、MYI(MYIndex)-索引文件存储为一个文件,
文件格式数据和索引是分别存储的,数据.MYD,索引.MY数据和索引是集中存储的,.ibd
记录存储顺序按记录插入顺序保存按主键大小有序插入
外键不支持支持
事务不支持支持
表级锁定行级锁定、表级锁定,锁定力度小并发能力高
select更优
insert,update,delete更优
select count(*)myisam更快,因为myisam内部维护了一个计数器,可以直接调取。
哈希索引不支持支持
全文索引支持不支持
2、MyISAM索引与InnoDB索引的区别

InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引。
InnoDB的主键索引的叶子节点存储着行数据,因此主键索引非常高效。
MyISAM索引的叶子节点存储的是行数据地址,需要再寻址一次才能得到数据。
InnoDB非主键索引的叶子节点存储的是主键和其他带索引的列数据,因此查询时做到覆盖索引会非常高效。

三、事务

1、事务的四大特性(ACID)

A:原子性,事务是不可分隔的,最小单位
C:一致性,一次事务要么全部执行,要么全部不执行
I:隔离性,不同的事务之间是隔离的,一个事务看不到其他事务提交的结果
D:持久性,事务执行完后,数据是永久保存

2、事务的术语

开启事务
结束事务
提交事务
回滚事务:出现异常时,为了保证一致性

3、什么是脏读?幻读?不可重复读?

脏读:一个事务还未提交时,另一个事务读取到还未提交的数据,因为事务可能会回滚,所以在没提交之前的数据都是脏数据,读到这些脏数据就是脏读。
不可重复读:事务之间不隔离导致的,在同一个事务里多次查询一个字段,结果不一样,这是因为在多次查询之间另外的事务提交了更新了该字段。
幻读:事务之间不隔离导致,在同一事务里多次查询表的行数,结果不一样,因为在查询之间另外的事务提交插入或者删除了新的记录。

4、事务的几种隔离级别

读未提交(READ-UNCOMMITTED):最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
读提交(READ-COMMITTED):允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
可重复读(REPEATABLE-READ):对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
串行化(SERIALIZABLE):最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

mysql默认的是可重复读级别。

5、事务实现的原理

参考链接:https://blog.csdn.net/whoamiyang/article/details/51901888
数据库使用MVCC(多版本并发控制)提高并发性能,在不使用锁的情况下,处理读写冲突,也是乐观锁的一种实现。使用的是快照读的方式,保存数据在某个时间点的快照。

数据库的每行记录都有四个隐式字段:
1、创建时间,其实存放的是事务ID
2、更新时间,存放的是更新或删除事务的ID
3、回滚指针,指向上一个版本
4、隐藏主键(表未指定主键时使用)
每个事务ID可以看作是一个版本,事务ID是从1开始递增。

select:查询出创建时间版本<=当前事务ID的数据,或者删除时间版本>当前事务ID的数据
这样就能保证多次查询出来的数据不会因为其他事务的提交而不同

update:将原来数据的更新时间版本设为当前事务ID,然后插入一条数据,创建时间版本是当前事务ID

delete:将数据的更新时间版本设为当前事务ID

6、springboot如何开启事务

有两种,一种是声明式事务,一种是注解式
声明式我用的比较少,一般是用的注解式,只需要在类或者方法上使用@Transactional即可,Spring的aop会自动的在加了该注解的方法里添加事务的开启、提交和回滚。

四、锁

锁是为了协调在高并发情况下,多个线程对同一资源操作的机制,使得竞争的线程可以分先后顺序的来访问修改同一资源。

1.锁的分类

共享锁:其他事务可以读,不能写
排他锁:其他事务不能读不能写

表锁:锁整张表,开销小,加锁快,不会出现死锁
行锁:锁某一行,开销大,加锁慢,会出现死锁

意向共享锁:innodb里的表锁,在加行共享锁时自动加这个锁
意向排他锁:innodb里的表锁,在加行排他锁时自动加这个锁

间隙锁:where后面不是等值时,是范围时就会加这个锁

2.不同引擎的加锁方式

MyISAM:
MyISAM 在执行查询语句(SELECT)前,会自动给涉及的表加读锁,再执行更新操作
(UPDATE、DELETE、INSERT 等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此,用户一般不需要直接用 LOCK TABLE 命令给 MyISAM 表显式加锁。
在自动加锁的情况下,MyISAM 总是一次获得 SQL 语句所需要的全部锁,这也正是 MyISAM 表不会出现死锁(Deadlock Free)的原因。

InnoDB:
InnoDB即支持行锁也支持表锁,为了使这两种锁同时存在,表锁使用意向锁命名
意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的 IS 锁。
意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的 IX 锁。
加锁方式:
1、意向锁是 InnoDB 自动加的, 不需用户干预。
2、对于 UPDATE、 DELETE 和 INSERT 语句, InnoDB会自动给涉及数据集加排他锁(X);
3、对于普通 SELECT 语句,InnoDB 不会加任何锁;事务可以通过以下语句显式给记录集加共享锁或排他锁:
共享锁(S):SELECT * FROM table_name WHERE … LOCK IN SHARE MODE。 其他 session 仍然可以查询记录,并也可以对该记录加 share mode 的共享锁。但是如果当前事务需要对该记录进行更新操作,则很有可能造成死锁。
排他锁(X):SELECT * FROM table_name WHERE … FOR UPDATE。其他 session 可以查询该记录,但是不能对该记录加共享锁或排他锁,而是等待获得锁

select *** for update 的使用场景:为了让自己查到的数据确保是最新数据,并且查到后的数据只允许自己来修改的时候,需要用到 for update 子句。

3.锁是否用到

InnoDB 是通过给索引上的索引项加锁来实现的,所以如果没有使用到索引,则不会加锁,可以通过explain来看执行计划中sql是否有用到索引

4.死锁

1、当事务试图以不同的顺序锁定资源时,就可能产生死锁。多个事务同时锁定同一个资源时也可能会产生死锁

2、发生死锁后,InnoDB 一般都能自动检测到,并使一个事务释放锁并回退,另一个事务获得锁,继续完成事务。有时当发生死锁时,禁用死锁检测(使用innodb_deadlock_detect配置选项)可能会更有效,这时可以依赖innodb_lock_wait_timeout设置进行事务回滚。

5.避免死锁

1、如果有写操作时,可以先使用select for update加排他锁,即使这些行的更改语句是在之后才执行的。
2、通过SELECT … LOCK IN SHARE MODE获取行的读锁后,如果当前事务再需要对该记录进行更新操作,则很有可能造成死锁。

五、慢日志

1.定义

慢日志是mysql可以监控运行时间超过阈值的sql语句,并且记录到文件或者表中。默认是关闭的,因为监控慢查询是比较消耗性能的,阈值是long_query_time这个参数设置的值,默认是10s。

2.相关的参数

slow_query_log :是否开启慢查询日志,1表示开启,0表示关闭。
slow-query-log-file:新版(5.6及以上版本)MySQL数据库慢查询日志存储路径。可以不设置该参数,系统则会默认给一个缺省的文件host_name-slow.log
long_query_time :慢查询阈值,当查询时间多于设定的阈值时,记录日志。
log_queries_not_using_indexes:未使用索引的查询也被记录到慢查询日志中(可选项)。
log_output:日志存储方式。log_output=‘FILE’表示将日志存入文件,默认值是’FILE’。log_output='TABLE’表示将日志存入数据库,这样日志信息就会被写入到mysql.slow_log表中。MySQL数据库支持同时两种日志存储方式,配置的时候以逗号隔开即可,如:log_output=‘FILE,TABLE’。日志记录到系统的专用日志表中,要比记录到文件耗费更多的系统资源,因此对于需要启用慢查询日志,又需要能够获得更高的系统性能,那么建议优先记录到文件。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值