jdbc:用于Java程序访问数据库的API;
原理:包含数据库驱动,连接数据库,创建操作对象,执行SQL语句,处理查询结果,释放查询资源等(使用socket连接数据库,获取statement实例执行sql语句)
执行过程中,每个步骤都会生成一个虚拟表,这个虚拟表将作为下一个执行步骤的输入,最后产生的虚拟币将作为输出结果。
什么是关系型数据库的三范式?(设计数据库时应该考虑)
一范式遵循原子性,表中字段的数据不可以再进行拆分;
二范式遵循唯一性,一张表只能描述一件事;
三范式消除传递依赖,在任意主键都可以确定所有非主键字段的情况下,不能存在非主键字段A可以获取非主键字段B的情况;
索引
聚簇索引 索引结构 和数据一起存放的索引,就是按照每张表的主键 构造一颗B+树,没有主键会默认第一个为NOT NULL,且UNIQUE的列作为索引,表数据和主键一起存储;InnoDB支持聚簇索引,不需要进行回表查询
非聚簇索引(二级索引/辅助索引) 索引结构和数据分开存放的索引,如果查询语句的全部字段都命中了索引,那么可以不用进行回表查询(覆盖索引)
回表查询:先通过二级索引查询到聚簇索引的地址,在根据地址查找到完整的数据
联合索引 就是多个字段一起建立的一个索引 ,命中索引必须按照建立索引时的字段顺序
覆盖索引(不是索引,一种索引的优化方式)一个索引包含所有需要查询的字段列,需要查询的字段正好是索引的字段/从辅助索引中就可以查询到所需的数据,无需回表
InnoDB索引采用B+树实现索引结构
MYSQL中的索引主要分为Hash索引和B+树索引,
Hash索引无法避免数据的排序操作,不能利用部分索引键查询,等值查询更快,无法范围查询;
自适应哈希(热点数据)
B+树索引磁盘IO开销大,支持范围查询,查询效率比较稳定,所有的查询都是从根节点到叶子节点;
索引
创建命令:alter table 表名 add index 索引名(列名)
删除命令:alter table 表名 drop index 索引名
高性能索引创建策略:
索引列的类型尽量小;
索引的选择性/离散性:不重复的索引值和数据表的记录总数
前缀索引:针对很长的varchar字段,mysql不支持索引全部长度,只取前面几个
只为搜索,排序(order by)或分组的列创建索引
多列索引或复杂索引如何判断创建的索引是最好的?
三星索引:
1星:创建后的索引查询到B+树的数据(B+叶子节点)在一个范围内,而不是分散开的(要求数据分布窄)(约24%)
2星:索引数据顺序和从B+树中查询出的顺序一致(约26%)一二星占比约25%
3星: 索引的列包含了所有要查询需要的列,不用回表。也就是可以做到覆盖索引(占比50%)
高性能索引使用策略:
不在索引列进行任何操作;尽量全值匹配(使用到联合索引的所有索引列);
最左前缀索引;范围查询放在最后,一般的话有多个只会走最左边那一个;
尽量使用覆盖索引,其他情况:
mysql数据库不走索引的情况
索引列参与了计算;使用了函数;使用了Like %XXX或Like %XXX%;
尽量避免OR操作,只要有一个字段没有索引,该字段就不走索引
where语句使用<>或!=或not in(主键会走索引,对字段表达式操作
索引失效有哪些?(与不走索引一个意思)
对索引使用左或者左右模糊匹配,就是like %xx 或者 like %xx% (尽量全值匹配)
对索引使用函数或进行表达式计算(不在索引列做任何操作)
对索引隐式类型转换,联合索引非最左匹配(左前缀原则)---从具有的最高优先级的索引开始查
最左匹配原则原理(联合索引):图如下(3个字段a,b,c)
上图为形如(a,b,c)的b+树,非叶子节点存储第一个关键字a的索引,叶子节点存储3个索引的值,最左边a有序的情况下,b,c无序;只在a相同时b才有序..,范围查询时就无序,不能走索引
存储引擎
InnoDB存储引擎支持事务,外键,行锁设计,内存使用少,适用于需要事务,数据更新较为频繁的场合
MyISAM存储引擎支持全文索引,不支持外键,不支持事务,对整张表加锁。读写互相阻塞
适用于读数据较多的场合;不需要事务支持的场合
不建议在数据库层面使用外键,会对数据的一致性产生问题。
缓存虽然可以提升查询性能但也会产生额外的开销,查询数据之后需要缓存数据,销毁数据也要销毁缓存。
InnoDB引擎底层(三大特性) 双写机制 Buffer Pool 自适应哈希索引
双写:防止丢失数据
页的写入数据文件之前,往特定区域(系统表空间2个区:连续区域)写入,只有都完成双写,数据才能写入到合适的位置。
写2次磁盘,第1次写到双写缓冲区 ,第2次写到真正的数据文件中,若有极端情况导致某个页数据丢失,可以从双写缓冲区恢复数据
Buffer Pool :服务器启动时申请的一块内存。
自适应哈希索引: 自适应哈希索引仅对那些频繁访问的键值创建,提高热点数据的查询性能
事务
事务的基本特性:ACID 原子性(由 undo log日志保证),一致性,隔离性,持久性(redo log日志保证)
持久性:
redo log日志:(Mysql永远不宕机,不需要redolog)影响mysql的性能
事务执行过程中对数据库的所有修改都记录下来,记录一个事务中没有写入到磁盘的命令
实际有2个文件交替使用
如:
原子性:
undo log日志:(记录插入,删除,修改)
undo日志:一次变动做一次记录 ,insert,update,delete,roll_ptr(MVCC-版本链)指向undo日志
事务执行过程中遇到断电,服务器本身的错误或者手动输入rollback结束事务
隔离性:
事务的隔离级别?
读未提交:可能读取到其他未提交的数据,会导致脏读的问题
读已提交:两次读取的结果不一致
可重复读:默认级别,每次读取的结果都是相同的,可能导致幻读
串行化:给每一行读取的数据加锁
由上往下隔离级别依次增加
并发事务造成的问题:
脏读:一个事务读取到另一个事务尚未提交的数据;可用版本链解决
不可重复读:一个事务中两次读取的数据不一致
幻读:一个事务中两次读取的数据量不一致,发生于一个事务读取了几行数据,另一个并发事务插入了一些数据
什么是MVCC?
通过版本链来控制并发事务访问同一个记录的行为就叫做MVCC;
多版本并发控制,只在InnoDB下存在,允许多个版本同时存在并发执行,不依赖锁机制,只在读已提交和可重复读隔离级别下工作。可以实现对数据库的并发访问,由读写冲突时能做到不加锁非阻塞并发读;需要时通过undo日志构造出历史版本
解决脏读问题:每条select语句执行时生成一个独立的ReadView:
事务80:ReadView中m_ids有一个范围【80,120】,最新的版本2trx_id在这个范围内也就是还是活跃的,也就是这个版本活跃的无法访问
解决不可重复读:在第一次select时生成一个ReadView;
幻读:
RR隔离级别下,第一次ReadView是null,第二次(有版本链的更新)ReadView出现指定情况下的幻读。如图:
解决幻读问题:ReadView无法完全解决,间隙锁
如何避免死锁?
在两个事务相互等待时,当一个事务的等待时间超过设置的某一阈值,就对这个事务进行回滚,另一个事务可继续执行
使用Redis及Zookeeper来代替数据库实现幂等性校验,允许效率更好
1.类似的业务逻辑以固定的顺序访问表和行
2.大事务拆小,大事务更倾向于死锁
3.在同一事务中,尽可能做到一次锁定所需要的所有资源,减少死锁概率
4.为表添加合理的索引
并发事务的控制方式:
MYSQL的锁:
分为共享锁(S/读锁)和排他锁(X/写锁)
共享锁允许多个事务同时获取,排他锁在事务进行数据修改时获取,不能多个事务同时获取
行锁: Innodb包括三类行锁定方式:记录锁,间隙锁,临键锁
Innodb默认隔离级别下,行锁默认使用临键锁(Next-Key Lock),如果操作的是 唯一索引或主键,InnoDB会对临键锁 降级为记录锁,锁住索引本身,非范围。
InnoDB和MyISAM之间的锁机制有何区别?
InnoDB可以更好地支持多个事务同时访问和修改数据,而MyISAM只能以表为单位进行锁定
InnoDB锁自动处理,一个事务需要修改或读取某一行时,仅锁定该行,减少了锁的竞争和冲突,但是MyISAM进行写操作时会锁定整张表,写入时会产生冲突;
InnoDB通过MVCC实现行级锁,允许读取操作不被写操作所阻塞,但MyIsAM会在读写冲突时发生冲突
InnoDB支持外键约束,而MyISAM不支持,外键约束需要对相关的行进行加锁,以确保数据的完整性
如何优化MySQL的锁性能?
尽量使用行级锁;减少事务持有锁的时间;合理使用索引;适当使用事务级别;使用锁粒度更细的操作
MYSQL的主从原理:
从库生成两个线程,一个SQL线程,一个i/o线程,i/o线程去请求主库的binlog,并将binlog日志写入从库中的relay log中;
主库会有一个log dump线程帮助向从库传输binlog;
binlog记录所有改变数据的操作
SQL线程读取从库的relay log,解析实现主从的操作一致
为啥要做主从同步?
读写分离,使数据库支撑更大的并发;
在主服务器上生成数据,在从服务器上分析数据,提高主服务器的性能;
数据备份,保证数据库的安全
分库分表策略:先垂直分再水平分 数据量大就分表并发高就分库
垂直分表:按照列拆分成多个表,每个表只包含某些列,可以将不常用或字段较大的字段拆分出去到扩展表中
水平分表:按照行拆分,用于处理数据量大的表;
垂直分库:按功能或按照表的关系分库
水平分库:按照数据范围分库或者按照哈希算法分库
分库分表组合:库内分表和分库分表,根据表内数据的逻辑关系,按照不同的条件分散到多个数据库或表中
执行计划:
explain/desc
format = tree树形格式/json格式
执行引擎:
Using index不读取数据,只从索引文件中获取数据
Using filesort
Using index & Using where 虽然使用到索引,但最终查询结果还需回表,较覆盖索引效率较低
标签:事务,数据库,查询,索引,InnoDB,MYSQL,数据 From: https://blog.csdn.net/weixin_47559057/article/details/144583897