Java知识汇总

本文深入探讨了Java数据库中的MySQL与Oracle的区别,详细讲解了MySQL的索引类型、表结构设计、锁机制以及SQL优化,特别是利用`EXPLAIN`进行查询性能分析。同时,对比了Redis的持久化、集群和哨兵模式,分析了不同场景下的数据存储策略。此外,还涵盖了JVM内存管理和垃圾回收机制,包括各种垃圾收集器的工作原理和优化。最后,简述了Java设计模式和Spring全家桶的使用,以及线程池和消息队列在Java应用中的重要性。
摘要由CSDN通过智能技术生成

一、数据库

一、MySQL

1. 索引

1.1 B+Tree

  1. 非叶子节点只存储键值信息。

  2. 所有叶子节点之间都有一个双向链指针。

  3. 数据记录都存放在叶子节点中。

  4. 每一页的结构,大小16kb,结构如下

1.2 索引的分类&使用

1.2.1 primary和normal

主键索引(Primary, pk_)

一张表有且只有一个主键索引,非空自增

普通索引(Normal, idx_)

加快数据的查询效率

常作为查询条件的column常作为索引 根据MySQL引擎(InnoDB或者MyISAM )不同,非主键索引的工作方式不同。

InnoDB是聚集索引,非主键索引存放的是主键索引的值 MyISAM是非聚集索引,非主键索引存放的是数据的地址

唯一索引(Unique, uk_)

主要是为了数据不重复

这么做的好处:一是简化了MySQL对这个索引的管理工作,这个索引也因此而变得更有效率;二是MySQL会在有新记录插入数据表时,自动检查新记录的这个字段的值是否已经在某个记录的这个字段里出现过了;如果是,MySQL将拒绝插入那条新记录。也就是说,唯一索引可以保证数据记录的唯一性。事实上,在许多场合,人们创建唯一索引的目的往往不是为了提高访问速度,而只是为了避免数据出现重复。 比如我想要一个userId对应数据库中的一条记录,那么可以跟userId建立唯一索引

全文索引(FullText)

仅可用于 MyISAM 表, 用于在一篇文章中,检索文本信息的, 针对较大的数据,生成全文索引很耗时好空间。 不过 FULLTEXT 用于搜索很长一篇文章的时候,效果最好。 用在比较短的文本,如果就一两行字的,普通的 INDEX 也可以。 比如有一个字段是备注,可能查找的时候,会把这个备注当做条件,那么可以在这个备注上面做全文索引

空间索引(Spatial)

MySQL包含OpenGIS 类相对应的数据类型,其中一些类型保存单一几何值

GEOMETRY 几何体 POINT 点 LINESTRING 线 POLYGON 多边形 普通索引对于一维数据(key->data)是无往不利,可是面对空间数据(lon,lat -> data)就有些无能为力了,如果查询(116.27636, 40.041285)附近的点: 空间索引通过 四叉树、R 树等数据结构,还有 GeoHash 算法将二维数据转化为一维使用普通B树索引 来实现,它们都能实现对空间范围内的快速搜索。

1.2.2 聚簇索引和非聚簇索引

索引是否和数据保存在一起

  • 聚簇索引:将数据存储和索引放在一起、并且是按照一定的顺序组织的,找到索引也就找到了数据,数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据一定也是相邻的存放在磁盘上的。

  • 非聚簇索引:叶子节点不存储数据,存储的是数据行地址(数据指针),也就是说根据索引查找到数据行的位置再去磁盘查找数据,这就有点类似一本书的目录,比如要找到第三章第一节,那就现在目录里面查找,找到对应的页码后再去对应的页码看文章。

MyISAM索引和数据分离,使用的是非聚集索引

InnoDB数据文件就是索引文件,主键索引就是聚集索引

1.2.3 聚集索引

就是聚簇索引

1.2.4 索引失效

什么时候没用

1.有or必全有索引; 2.复合索引未用左列字段; 3.like以%开头; 4.需要类型转换; 5.where中索引列有运算; 6.where中索引列使用了函数; 7.如果mysql觉得全表扫描更快时(数据少);

什么时候没必要用

1.唯一性差; 2.频繁更新的字段不用(更新索引消耗); 3.where中不用的字段; 4.索引使用<>时,效果一般;

1.2.6 回表

MySQL 要先查询到主键索引,然后再用主键索引回到数据库表查询这条数据。

1.2.6 覆盖索引

首先,这不是一个索引的种类,而是查询时的一个场景

这个场景是:

在B+Tree的叶子节点存储的是索引的指针和这个索引对应字段的值,假设此次查询刚好查询的是索引的值,则就可以直接返回,就相当于索引 "覆盖" 了查询需要的结果,而不需要回表,这个场景就是覆盖索引

2. 集群

3. sql优化

3.1 explain

使用mysql提供的explain命令来查询sql语句的执行计划,查看sql语句有没有使用上索引,有没有全表扫描等。 expain出来的信息有12列,分别是,id,select_type,table,partitions,type,possible_keys,key,key_len,ref,rows,filtered,Extra。

如图:

 

3.1.1 概要描述

id:所泽标识符 select_type:表示查询的类型 table:输出结果集的表 partitions:匹配的分区 type:表示表的连接类型 possible_keys:表示查询时,可能使用的索引 key:表示实际使用的索引 key_len:索引字段的长度 ref:列与索引的比较 rows:扫描出的行数(估算的行数) filtered:按表条件过滤的行百分比 Extra:执行情况的描述和说明

3.1.2 每个字段的详解

3.1.2.1 id

select识别符,这是select的查询序列号。 SQL执行的顺序的标识,SQL从大到小的执行。 1,id相同时,执行顺序由上至下。 2,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行。 3,id如果相同,可以任务是一组,从上往下顺序执行;在所有组中,id值越大,优先级越高,越先执行。

3.1.2.2 select_type

表示查询中每个select子句的类型。 2.2.1 simple (它表示简单的select,没有union和子查询) 2.2.2 primary (最外面的select,在有子查询的语句中,最外面的select查询就是primary) 2.2.3 union (union语句的第二个或者是后面的select语句) 2.2.4 dependent union (union中的第二个或者后面的select语句,取决于外面的查询) 2.2.5 union result (union的结果,union语句中第二个select开始后面所有的select) 还有几个参数这里省略。

3.1.2.3 table

输出的行所用的表。

3.1.2.4 type

连接类型。有多个参数,从最佳类型到最差类型介绍

system

表仅有一行,这是const类型的特例,平时不会出现。

const 表最多有一个匹配行,const用于比较primary key或者unique索引。因为只匹配一行数据,所以很快。若只是使用limit 1 来返回1条数据,type不会是const。如图,

eq_ref 对于每个来自前面的表的行组合,从该表中读取一行。这可能是最好的连接类型,除了const类型。他用在一个索引的所有部分被联接使用并且索引是unique或者primary key。

ref 对于每个来自前面的表的行组合,所有匹配索引值的行将从这张表读取。如果连接只使用键的最左边前缀,或如果键不是unique或者primary key,则使用ref。如果使用的键仅仅匹配少量行,该连接类型也是不错的。 如图中,where匹配了组合索引中的最左前缀。

ref_or_null 该连接类型如同ref,但是添加了mysql可以专门搜索包含NULL值的行。在解决子查询中经常使用该连接类型的优化。

index_merge 该连接类型表示使用索引合并优化方法,在这种情况下,key列包含了使用的索引的清单,key_len包含了使用的索引的最长的关键元素。

unique_subquery

index_subquery

range 给定范围内的检索,使用一个索引来检查行。

index 该连接类型与all相同,除了只有索引树被扫描,这通常比ALL快,因为索引文件通常比数据文件小。(index是从索引中读取,而ALL是从磁盘中读取)

ALL

对于每个来自于先前的表的行组合,进行完整的表扫描。如果表是第一个没有标记const的表,这通常这种情况不好,通常可以怎讲更多的索引而不要使用ALL,是的行能基于前面的表中的常数值或值被检索出。

3.1.2.5 possible_keys

提示使用哪个索引会在该列中找到行,不太重要。

3.1.2.6 keys

mysql使用的索引,简单且重要。

3.1.2.7 key_len

mysql使用的索引长度。

3.1.2.8 ref

ref列显示使用哪列或常数与key一起从表中选择行

3.1.2.9 rows

显示mysql执行查询的行数,简单且重要,数值越大越不好,说明没有用好索引。

3.1.2.10 extra

该列包含了mysql解决查询的详细信息。

Distinct Mysql发现第一个匹配行后,停止为当前的行组合搜索更多的行。

Not exists

range checked for each record 没有找到合适的索引

using filesort 当extra中出现using filesort时说明语句性能不好,需要优化。 using filesort是一种速度很慢的外部排序。 即使order by后的字段加了索引,也有可能出现using filesort,因为有可能索引定义不当,mysql没用到索引。 如下图中,UPPER_ID是单索引,DUTY_ID是组合索引的最左列。

using index(using index condition) 只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的信息。

using temporary 为了解决查询,mysql需要创建一个临时表来容纳结果,典型情况如查询包含客户以按不同情况列出列的group by和order by子句时,出现using temporary就说明语句需要优化。

using where where子句用于限制哪一个行匹配下一个表或发送到客户。除非你专门从表中索取或检查所有行。如果extra值不为using where并且表示联接类型为ALL或index,查询可能会有一些错误。

using sort_union(), using union(...), using intersect(...) 这些函数说明如何为index_merge联接类型合并索引扫描。

using index for group-by 类似于访问表的using index方式,using index for group-by表示mysql发现了一个索引,可以用查询group by或distinct查询的所有列,而不要额外搜索硬盘访问实际的表。并且,按最有效的方式使用索引,以便于对每个组,只读取少量索引条目。

4. 表结构设计

5. 锁机制

5.1 分类

乐观锁
​
悲观锁
​
    行级锁:排它锁(读锁),共享锁(写锁),更新锁,意向锁
​
    页级锁
​
    表级锁:排它锁(读锁),共享锁(写锁),意向锁

5.2 原理

优劣和场景

乐观锁是通过版本号进行控制,当前version!=预期version的时候回滚,相等时提交;悲观锁是在访问时加锁,只应许一个线程的一次访问。
两者的区别是,悲观锁在访问的时候就进行限制,而乐观锁在提交的时候进行校验;
适用场景因为原理也有所不同,乐观锁适合冲突较少的情况下使用,可以提高系统的吞吐量,而处理较多冲突的业务场景,会到时系统频繁retry(重试),反而降低性能(白跑业务代码逻辑,浪费资源);悲观锁刚好相反,所以不同业务场景适用不同的锁。

排它锁(写锁)

排他,如果事务T对数据对象A加上写锁,那么只允许事务T读取和修改对象A,其他事务都不能在对A加任何类型的锁,直到事务T释放当前写锁

意义:

保证了绝对的安全,别的线程无法操作,但是相对效率低。事务T在释放在数据对象A的锁前其他事务无法读取和修改数据对象A

共享锁(读锁)

如果事务T对数据对象A加上读锁,那么其他事务只能再对数据对象A加读锁,而不能加写锁,知道事务T释放在A上的读锁

意义: 保证了其他事务可以读取数据对象A,但是在释放锁之前不能对A进行任何修改

相容性:读读不加锁,写写加锁,读写加锁

更新锁

在更新的时候可读
 加锁与解锁:当一个事务执行update语句时,数据库系统会先为事务分配一把更新锁。当读取数据完毕,执行更新操作时,会把更新锁升级为独占锁。
 兼容性:更新锁与共享锁是兼容的,也就是说,一个资源可以同时放置更新锁和共享锁,但是最多放置一把更新锁。这样,当多个事务更新相同的数据时,只有一个事务能获得更新锁,然后再把更新锁升级为独占锁,其他事务必须等到前一个事务结束后,才能获取得更新锁,这就避免了死锁。 
 并发性能:允许多个事务同时读锁定的资源,但不允许其他事务修改它。

意向锁

(意向共享,意向更新) 在判断每一行是否已经被行锁锁定效率比较低下,因此使用意向锁,当发现表上有意向共享锁,说明表中有些行被共享行锁锁住了,因此,事务B申请表的写锁会被阻塞。

二、Oracle

和MySQL的区别

sql语法

Oracle严格遵守sql语法,select必须带有from

当查询一些常量的时候,使用"伪表"进行sql语句编写

伪表dual

select length('abcd') from dual;

这里不带from会报错,伪表是一张一行一列的数据库表

1.索引

特殊用法,反向建索引,通过 十进制 -> 二进制 -> 反向 -> 十进制 的方式,将一个连续变大的十进制排列整数调整成一个均匀散列的随机十进制排列数 中心思想:打散

sql写法,最后加上reverse


                
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值