索引
索引是帮助MySQL高效获取数据的数据结构
BvsB+
1.B树节点,既有数据,又有Page指针。而B+,只有叶子节点有数据。其他节点,只有键值和Page指针
2.B+叶子节点,全部相连,而B没有
为何选择B+
节点不存储data,这样一个节点就可以存储更多的key。可以使得树更矮,所以IO操作次数更少。叶子节点相连,更便于进行范围查找
主键索引(聚簇索引)
默认是B+树,聚簇索引。B+树叶子节点上存放的是主键字段+整行数据
聚簇索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的就是整张表的行记录数据(所以每张表只能有一个聚簇索引)
非聚簇索引
非主键索引都是。可以使用多种类型的索引,如B+树,Hash索引等
假如用B+树,存储结构:叶子节点:存放索引字段值+主键的值
搜索数据的方式: 索引字段-》主键-》整条数据
(1)先通过索引字段,找到叶子节点上的主键值
(2)再通过主键值,找整条数据(回表操作)
优点:更新代价相对比聚簇索引小(叶子节点是索引值和主键值,没有真实数据)
缺点:
(1)也依赖有序数据
(2)可能产生回表操作导致效率会更低
覆盖索引:
如果一个索引包含所需要查询的字段值,我们旧称之为“覆盖索引”
做法:将被查询的字段,建立到联合索引里去。
联合索引:
使用多列来建立索引,
涉及最左匹配原则:联合索弓|的多个索引字段,遵循从左往右的优先级,最左优先,当出现范围查询(> < between like等等)时停止匹配
索引的优化
尽量使用主键查询: 聚簇索引上存储了全部数据, 相比普通索引查询, 减少了回表的消耗.
MySQL5.6之后引入了索引下推优化, 通过适当的使用联合索引, 减少回表判断的消耗.
若频繁查询某一列数据, 可以考虑利用覆盖索引避免回表.
联合索引将高频字段放在最左边
hash索引:不支持顺序和范围查询是它最大的缺点。
hashmap:
存储数据的特性:键值对,无序,键唯一(不重复 )
底层数据结构:数组+链表+红黑树
如果问到原理就说存取元素,复杂的都是put流程,说这个就行
(1)算数组位置,往上边放(根据key的hashcode值, 基于内部hash函数计算出数组索引) =>找车厢.
(2)如果该位置没有元素:往这个地方放
如果有元素:
往链表上放:是否存在节点equals(key)
存在:替换
不存在:头插?尾插?
可能转红黑树:=》当链表中节点数量大于8时,链表会转成红黑树。
(3)如果放进去了东西,可能需要扩容
(1)对于插入、删除数据频率高的表,不适用索引
(2)对于某列修改频率高的,该列不适用索引
(3)通过某列或某几列的条件查询频率高的,可以对这些列创建索引
事务
事务的概念
事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败
(1)开启事务:start transaction;
(2)执行多条SQL语句
(3)回滚或提交:rollback/commit;
事务四大特性
1.原子性:事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,
要么完全不起作用;
(多条sql,要么都不执行,要么都执行)
2.一致性:数据库从一个事务执行之前和执行之后都必须处于一致性状态。
你有1k坐地铁小偷头300,你俩加起来还有1k
3.隔离性:并发访问数据库时, 一个用户的事务不被其他事务所干扰,各并发事务之间数
据库是独立的;
(不同隔离级别下,可能不一定满足某种场景的隔离性)
4.持久性: -一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故
障也不应该对其有任何影响。
(事务提交后,数据的改变会持久化到硬盘)
并发事务带来哪些问题?
脏读(Dirty read): 第一个事务修改了数据但没有提交到数据库,第二个事务就读取,在第一个事务回滚后,第二个事务读取的就是脏数据
丢失修改(Lost to modify): 指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。
这样第一个事务内的修改结果就被丢失,因此称为丢失修改。 例如:事务1读取某表中的数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。
不可重复读(Unrepeatableread): 指在一个事务两次读同一数据的中间另一个事务也访问该数据并修改。
这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。
幻读(Phantom read): 幻读与不可重复读类似。一个事务两次读取数据的中间另一个事务插入了一些数据,导致两次读到的不一样。
解决办法:使用隔离级别
未提交读(READ UNCOMMITTED)
可以读取未提交的数据变更
事务中的修改,即使没有提交,对其它事务也是可见的。
一般都不会使用
提交读(READ COMMITTED)
可以读取已提交的数据变更
这个是用的比较广泛的
一个事务只能读取已经提交的事务所做的修改。换句话说,-个事务所做的修改在提交之前
对其它事务是不可见的。
可重复读(REPEATABLE READ)
mysql默认的隔离级别
保证在同一个事务中多次读取同一数据的结果是一样的。
可串行化(SERIALIZABLE)几乎也不会有公司使用这个级别 (性能太差)
所有的事务依次逐个执行
强制事务串行执行,这样多个事务互不干扰,不会出现并发-致性问题。
一个事务中多行sq|全部执行完 (提交或回滚),另-一个事务才能执行
安全由低到高,性能由高到低。