Java基础知识——锁,连接,底层设计,引擎,基础,主从复制,mysql机制

锁:读写锁 行页表锁 乐观锁
连接:内连接 外连接 交叉连接
底层设计:HashB B与二叉
引擎:五大引擎 MYISAM和innoDB的区别
基础知识:删除 优先级 视图 约束(五大约束 完整性 断言 触发器)
主从复制:分布式 种类 策略 过程
mysql机制:server组成 日志

读写锁

共享锁(Share locks简记为S锁):也称读锁,事务A对对象T加s锁,其他事务也只能对T加S,多个事务可以同时读,但不能有写操作,直到A释放S锁。

排它锁(Exclusivelocks简记为X锁):也称写锁,事务A对对象T加X锁以后,其他事务不能对T加任何锁,只有事务A可以读写对象T直到A释放X锁。

更新锁(简记为U锁):用来预定要对此对象施加X锁,它允许其他事务读,但不允许再施加U锁或X锁;当被读取的对象将要被更新时,则升级为X锁,主要是用来防止死锁的。
select * from table(updlock)我的理解还有一种功能是提前占锁,保证先更新

如何防止死锁呢?

参考资料


T1:
begin tran
select * from table (holdlock) (holdlock意思是加共享锁,直到事务结束才释放)
update table set column1=‘hello’

T2:
begin tran
select * from table(holdlock)
update table set column1=‘world’

假设T1和T2同时达到select,T1对table加共享锁,T2也对加共享锁,当
T1的select执行完,准备执行update时,根据锁机制,T1的共享锁需要升级到排他锁才能执行接下来的update.在升级排他锁前,必须等table上的其它共享锁释放,但因为holdlock这样的共享锁只有等事务结束后才释放,
所以因为T2的共享锁不释放而导致T1等(等T2释放共享锁,自己好升级成排他锁),同理,也因为T1的共享锁不释放而导致T2等。死锁产生了。

行页表锁


参考资料

行锁:对索引加锁,对操作属性中包含索引
开销大,加锁慢;会出现死锁;需要具体检索到某一行,当没有释放某一行而去请求另一行则可能导致死锁
锁定粒度小,发生锁冲突的概率低,并发度高
表锁:对非索引加锁,不包含索引
锁定力度大,发生锁冲突概率高,并发度最低
开销小,加锁快;不会出现死锁;一次性获得表所涉及的所有锁,要么全部得到要么全部不得到
页锁:开销和加锁速度介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发度一般
记录锁:行锁的引申。必须是命中索引并且索引是唯一索引,如主键id

乐观锁

乐观锁:
1:版本号/时间戳:在数据库上就是表中增加一个version字段,每次更新把这个字段加1,读取数据的时候把versionA读出来,更新的时候比较version,如果还是开始读取的version就可以更新了,如果现在的version比老的version大,说明有其他事务更新了该数据
2:待更新字段:是否符合期待值CAS

连接

Java基础知识——锁,连接,底层设计,引擎,基础,主从复制,mysql机制

Java基础知识——锁,连接,底层设计,引擎,基础,主从复制,mysql机制
Java基础知识——锁,连接,底层设计,引擎,基础,主从复制,mysql机制

内连接

关注公共部分C

等值连接

select * from A,B where A.Aid=B.Bnameid
Select * from A JOIN B ON A.Aid=B.Bnameid
Java基础知识——锁,连接,底层设计,引擎,基础,主从复制,mysql机制

不等值连接

主要用除了等号之外的操作符,比如:<>、>、<、>=、<=、LIKE、IN、BETWEEN…AND。

自然连接

natural join
特殊的等值连接

  1. 等值连接中不要求属性值完全相同,而自然连接要求两个关系中进行比较的必须是相同的属性组(属性名可以不同),即要求必须有相同的值域。
  2. 自然连接是去掉重复列的等值连接即上图中Aid和Bnameid是属性值相同的列,因为相同所以去掉其中一列

外连接

左连接

A left join B
部分A+部分C
Java基础知识——锁,连接,底层设计,引擎,基础,主从复制,mysql机制

右连接

A right join B
部分B+部分C
Java基础知识——锁,连接,底层设计,引擎,基础,主从复制,mysql机制

全连接

部分A+部分B+部分C

交叉连接

笛卡尔积
9*9=81列,不存在等值关系

底层设计

索引主要是基于Hash表和B+树:
1:B+树效率高于Hash表
两个特点导致:索引的值和Hash值不特定关系
索引的值和Hash值无对应关系:

  1. Hash索引仅仅能满足“=”,“IN”,“<=>”查询,不能使用范围查询。
  2. Hash索引无法避免数据的排序操作 (order)
    由于Hash索引中存放Hash值,Hash值的大小关系并不一定和Hash运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算。
  3. 联合索引中,Hash索引不能利用部分索引键查询。
    对于联合索引中的多个列,Hash是要么全部使用,要么全部不使用

Hash值存在冲突
4. Hash索引任何时候都不能避免表扫描
因为存在冲突即不同的值对应相同的Hash,所以还是要通过访问表中的实际数据进行比较,并得到相应的结果。
5. Hash索引遇到大量Hash值相等的情况后性能并不一定会比BTree高

发展历史:二叉树——平衡二叉树——B-树——B+树
B树效率高于二叉树
二叉树比较次数少(内存耗时少)
但是最耗费资源是磁盘IO,并且磁盘读写是按页读
二叉树每次只能读取一个节点,浪费资源
B树树低于二叉树,IO次数少
B+树效率高于B-树
io次数少:b+树中间节点只存索引,不存在实际的数据
性能稳定:b+树数据只存在于叶子节点,查询性能稳定,即每次都到达叶子结点
范围查询简单:b+树不需要中序遍历,遍历链表即可。

存储引擎

种类


参考资料

数据库存储引擎是存储、处理和保护数据的核心服务
存储引擎主要有:

  1. MyIsam , 2. InnoDB, 3. Memory 4:InnoDB 5:TokuDB

ISAM
查询的次数要远大于更新的次数。因此,ISAM执行读取操作的速度很快,而且不占用大量的内存和存储资源。
不支持事务处理,也不能够容错
如果你的硬盘崩溃了,那么数据文件就无法恢复了。如果你正在把ISAM用在关键任务应用程序里,那就必须经常备份你所有的实时数据,通过其复制特性,MYSQL能够支持这样的备份应用程序。

MYISAM
ISAM扩展格式。
提供索引和字段管理,表锁,来优化多个并发的读写操作。
MYISAM还有一些有用的扩展,例如用来修复数据库文件的MYISAMCHK工具和用来恢复浪费空间的MYISAMPACK工具(容错机制)

HEAP(Hash索引,B+树)
HEAP允许只驻留在内存里的临时表格。驻留在内存里让HEAP要比ISAM和MYISAM都快
数据是不稳定的,关机后数据丢失

InnoDB:B+树
TokuDB(分形树)
每一个 child 指针除了需要指向一个 child 节点外,还会带有一个 Message Buffer ,这个 Message Buffer 是一个 FIFO 的队列,用来缓存更新操作。
例如,一次插入操作只需要落在某节点的 Message Buffer 就可以马上返回了,并不需要搜索到叶子节点。这些缓存的更新会在查询时或后台异步合并应用到对应的节点中。

InnoDB和MYISAM的区别

1:InnoDB提供事务支持
2:InnoDB提供行健和外健约束
3:InnoDB没有保存表的行数,当SELECT COUNT(*) FROM TABLE时需要扫描全表。
4:关于索引
对于记录(姓名,ID,成绩)例如(Bob,15,34)
无论是主键索引还是非主键索引,索引结构为B+Tree,其中B+Tree的数据域存储的内容为实际数据的地址,非聚集索引。
可以看到Primary Key是ID构建的B+树,而叶子结点是指向记录的地址

Java基础知识——锁,连接,底层设计,引擎,基础,主从复制,mysql机制

InnoDB的索引结构同样也是B+Tree,但是Innodb的索引文件本身就是数据文件,即B+Tree的数据域存储的就是实际的数据,聚集索引。
可以看到Primary Key是ID构建的B+树,而叶子结点是指向记录本身
Java基础知识——锁,连接,底层设计,引擎,基础,主从复制,mysql机制
并且InnoDB的辅助索引数据域存储的也是相应记录主键的值而不是地址,所以当以辅助索引查找时,会先根据辅助索引找到主键,再根据主键索引找到实际的数据。
所以Innodb不建议使用过长的主键,否则会使辅助索引变得过大。
可以看到Second Key是年龄构建的B+树,而叶子结点是指向的是(年龄,主键(ID)),通过ID再找Primary Key

Java基础知识——锁,连接,底层设计,引擎,基础,主从复制,mysql机制

基本语法

删除

Delete用来删除表的全部或者一部分数据行,执行delete之后,用户需要提交(commmit)或者回滚(rollback)来执行删除或者撤销删除, delete命令会触发这个表上所有的delete触发器;

Truncate删除表中的所有数据,这个操作不能回滚,也不会触发这个表上的触发器,TRUNCATE比delete更快,占用的空间更小;

Drop命令从数据库中删除表,所有的数据行,索引和权限也会被删除,所有的DML触发器也不会被触发,这个命令也不能回滚。

因此,在不再需要一张表的时候,用drop;在想删除部分数据行时候,用delete;在保留表而删除所有数据的时候用truncate。

视图

是从一个或多个表导出的虚拟的表,其内容由查询定义。具有普通表的结构,但是不实现数据存储。

例子:create view v_student as select * from student;

①简化了操作,把经常使用的数据定义为视图。
我们在使用查询时,在很多时候我们要使用聚合函数,同时还要显示其它字段的信息,可能还会需要关联到其它表,这时写的语句可能会很长,如果这个动作频繁发生的话,我们可以创建视图,这以后,我们只需要select * from view就可以啦,这样很方便。

②安全性,用户只能查询和修改能看到的数据。
因为视图是虚拟的,物理上是不存在的,只是存储了数据的集合,我们可以将基表中重要的字段信息,可以不通过视图给用户

③逻辑上的独立性,屏蔽了真实表的结构带来的影响。
视图可以使应用程序和数据库表在一定程度上独立。如果没有视图,应用一定是建立在表上的。有了视图之后,程序可以建立在视图之上,从而程序与数据库表被视图分割开来。

关键字的优先级:

select * from 表名 limit 4,3;
说明:对查询出来的结果进行过滤,只显示起始行为第5行,一共查询3行记录。
where>group by>having>order by>limit

约束

五大约束 数据完整性 断言 触发器

参考资料

主键约束
非空约束
唯一约束
默认约束
外键约束

ON DELETE(其他操作类似)
restrict(约束):
当在父表(即外键的来源表)中删除对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除。
no action:
意思同restrict.即如果存在从数据,不允许删除主数据

cascade(级联):
当在父表(即外键的来源表)中删除对应记录时,首先检查该记录是否有对应外键,如果有则也删除外键在子表(即包含外键的表)中的记录。

set null:
当在父表(即外键的来源表)中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(不过这就要求该外键允许取null)

数据完整性:
实体完整性:Primary Key
自动进行检查。包括:1)、检查主码值是否唯一,如果不唯一则拒绝插入或修改;2)、检查主码的各个属性是否为空,只要有一个为空则拒绝插入或修改。这样就保证了实体完整性。

检查记录中主码值是否唯一的一种方法是全盘扫描,依次判断表中每一条记录的主码值与将插入记录的主码值(或者修改的新主码值)是否相同,但这种扫描是十分耗时的。为了避免对基本表进行全表扫描,关系数据库管理系统一般都在主码上自动建立一个索引,如 B+ 树索引 ,通过索引查找基本表中是否已经存在新的主码值时不需要查看全部值,而是看特定的几个结点即可,大大提高查找效率。

参照的完整性:外键约束
用户定义的完整性
某一具体应用的数据必须满足的语义要求
可以根据应用要求定义属性上的约束条件,即属性值限制,包括:列值非空 ( not null )、列值唯一 ( unique )、检查列值是否满足条件表达式 ( check 短语)

域完整性:
域是一组具有相同数据类型的值的集合可以理解为类的思想,也就是对于不同表的性别属性,都会check(男,女),重复定义过于麻烦,所以单独定义域,则表的性别属性引用这个域即可
create domain GenderDomain char(2)
check (value in (‘男’,‘女’));

断言:更具一般性的约束,但是很影响效率
任何对断言中所涉及关系的操作都会触发关系数据库管理系统对断言的检查,任何使断言不为真值的操作都会被拒绝执行。Java基础知识——锁,连接,底层设计,引擎,基础,主从复制,mysql机制

触发器:思想类似于面向AOP编程Java基础知识——锁,连接,底层设计,引擎,基础,主从复制,mysql机制
行级触发器for each row 和语句级触发器for each statement:
有 100 行
语句级触发器,那么执行完 update 语句后触发动作体执行一次
行级触发器,触发动作体将执行 100 次。

触发顺序:先before后after,(多个before)谁先创建谁先执行

主从复制

参考资料

分布式架构

单点服务:当主库宕机后,集群会自动将一个从库升级为主库,继续对外提供服务
读写分离:写操作走主库,读操作走从库
此时若写操作超过主库负荷?
分库:将业务相关性比较大的表放在同一个数据库中,例如之前数据库有A,B,C,D四张表,A表和B表关系比较大,而C表和D表关系比较大,这样我们把C表和D表分离出去成为一个单独的数据库
将原有的单点写变成双点写或多点些,从而降低原有主库的写负载。

策略

同步策略:Master要等待所有Slave应答之后才会commit
半同步策略:Master等待至少一个Slave应答就可以commit。
异步策略:Master不需要等待Slave应答就可以提交。
延迟策略:Slave要至少落后Master指定的时间。
全新MGR(MySQL Group Replication):必须经过组内(N / 2 + 1)结点通过才能commit
Paxos协议

类型

基于语句的复制,即Statement Based Replication(SBR):记录每一条更改数据的sql
优点:binlog文件较小,节约I/O,性能较高。
缺点:不是所有的数据更改都会写入binlog文件中,尤其是使用MySQL中的一些特殊函数(如LOAD_FILE()、UUID()等)和一些不确定的语句操作,从而导致主从数据无法复制的问题。

基于行的复制,即Row Based Replication(RBR):不记录sql,只记录每行数据的更改细节即数据本身
优点:详细的记录了每一行数据的更改细节,这也意味着不会由于使用一些特殊函数或其他情况导致不能复制的问题。
缺点:由于row格式记录了每一行数据的更改细节,会产生大量的binlog日志内容,性能不佳,并且会增大主从同步延迟出现的几率。

混合复制(Mixed)
一般的语句使用SBR。若遇到特殊函数则用RBR

实现过程

mysql主从复制需要三个线程,master(binlog dump thread)、slave(I/O thread 、SQL thread)。
master
binlog dump线程:当
1:主库将更新的事件类型写入到主库的binlog文件中
2:创建log dump线程通知slave有数据更新,当I/O线程请求日志内容时,会将此时的binlog名称和当前更新的位置同时传给slave的I/O线程。
slave
I/O线程:该线程会连接到master,向log dump线程请求一份指定binlog文件位置的副本,并将请求回来的binlog存到本地的relay log中
SQL线程:该线程检测到relay log有更新后,会读取并在本地做redo操作,将发生在主库的事件在本地重新执行一遍,来保证主从数据同步。

Java基础知识——锁,连接,底层设计,引擎,基础,主从复制,mysql机制

mysql执行过程

Server层
引擎层:插拔式

连接器:用户登录数据库,进行用户的身份认证
查询缓存:执行查询语句的时候,会先查询缓存,Mysql会先校验这个sql是否执行过,以Key-Value的形式缓存在内存中
Mysql 查询不建议使用缓存,因为对于经常更新的数据来说,缓存的有效时间太短了
分析器:词法分析,一条SQL语句有多个字符串组成,首先要提取关键字语法分析,主要就是判断你输入的sql是否正确,是否符合mysql的语法。
优化器:优化器的作用就是它认为的最优的执行方案去执行(虽然有时候也不是最优),比如多个索引的时候该如何选择索引,多表查询的时候如何选择关联顺序等
执行器:首先执行前会校验该用户有没有权限,如果没有权限,就会返回错误信息,如果有权限,就会去调用引擎的接口,返回接口执行的结果
binlog归档日志:主要用于主从复制
InnoDB自带日志模块redo log:主要用于事务(重新提交或者回滚事务)

执行有两种情况:查询语句和更新语句
查询语句按照上述流程(没有binlog和redo log环节)
更新语句:
执行完上述操作后进行日志更新。
1:将操作记录于redo log,redo log进入prepare状态
2:记录binlog
3:提交,redo log 为提交状态。

这里我们可以知道,仅仅有binlog日志是没法支持日志的,而必须有redo log,且顺序必须是
redo log准备——binlog——redo log commit

1:先写redo log 直接提交,然后写 binlog:写完redo log 后,机器挂了,binlog日志没有被写入。机器重启后,这台机器会通过redo log恢复数据,但是这个时候bingog并没有记录该数据,后续进行机器备份的时候,就会丢失这一条数据,同时主从同步也会丢失这一条数据。
2:先写binlog,然后写redo log:假设写完了binlog,机器异常重启了,由于没有redo log,本机是无法恢复这一条记录的,但是binlog又有记录,那么和上面同样的道理,就会产生数据不一致的情况。
3:如果按正常顺序,机器在redo log准备——binlog阶段宕机
binlog不完整,回滚事务
4:binlog——redo log commit宕机
Java基础知识——锁,连接,底层设计,引擎,基础,主从复制,mysql机制