数据库知识点
- MYISAM与innodb搜索引擎原理
- MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。其采用索引文件与数据文件,索引文件只存放索引,叶子节点存放数据的物理地址。数据文件存放数据。其索引方式是非聚集的。
- InnoDB也使用B+Tree作为索引结构。但是它的主索引与数据都放在一个文件中。这种索引叫做聚集索引,因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。
- 区别一:InnoDB的主索引与数据都放在一个文件中。而MYISAM是分开存放的。
- 区别二:InnoDB的辅助索引data域存储相应记录主键的值而不是地址。
- 区别三:InnoDB的主键索引是聚集索引,而MYISAM不是聚集索引。
-
索引,聚簇索引和二级索引的加锁区别
- 聚集(clustered)索引,也叫聚簇索引。数据行的物理顺序与列值(一般是主键的那一列)的逻辑顺序相同,一个表中只能拥有一个聚集索引。
- 非聚集(unclustered)索引。该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同,一个表中可以拥有多个非聚集索引。会发生二次查询。
- 稠密索引:稠密索引文件中的索引块保持键的顺序与文件中的排序顺序一致。
- 稀疏索引:稀疏索引没有为每个数据都创建一个索引,它比稠密索引节省了更多的存储空间,但查找给定值的记录需更多的时间。只有当数据文件是按照某个查找键排序时,在该查找键上建立的稀疏索引才能被使用,而稠密索引则可以应用在任何的查找键。
- 联合索引:将一张表中多个列组成联合索引(col1,col2,col3),其生效方式满足最左前缀原则。
- 最左前缀:假如我们创建了联合索引(col1,col2,col3),那么相当于创建了(col1),(col1,col2),(col1,col2,col3)这3个索引,然后where条件会根据出现的列名挑选最严格的索引。例如where col1=? and col2=? and col3=?,那么就会使用(col1,col2,col3);如果where col1=? and col3 =?,那么就会使用(col1);如果where col2=? and col3=?,那么一个都不会使用。因此在创建多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。
- 选择性:不重复数占所有记录的比例,假如有10w条记录,unique之后有9w条,那么选择性位90%。主要有两个作用:1. 查看某一列是否有必要建立索引;2. 对于String、hash值、日期等字段,应该取多少位来建立索引(即使用前缀索引),因为主键越短,整个索引表越小。
- 覆盖索引:对于二级索引而言,在innodb中一般是需要先根据二级索引查询到主键,然后在根据一级索引查询到数据。但是如果select的列都在索引中,就避免进行一级查询。
-
主键选择
where 1 = 1:能够方便我们拼sql,但是使用了之后就无法使用索引优化策略,因此会进行全表扫描,影响效率。
- 在使用InnoDB存储引擎时,如果没有特别的需要,请永远使用一个与业务无关的自增字段作为主键。
-
分表分库
validationQuery:用来验证数据库连接的查询语句,这个查询语句必须是至少返回一条数据的SELECT语句。
- 水平拆分:依据表中的数据的逻辑关系,将同一个表中的数据依照某种条件拆分到多台数据库(主机)上面。按照1个或多个字段以及相应的规则,将一张表重的数据分到多张表中去。比如按照id%5的规则,将一张大表拆分成5张小表。适合具有超大表的系统。
- 垂直拆分:依照不同的表(或者Schema)来切分到不同的数据库(主机)之上。一般按照模块来分库。适合各业务之间耦合度非常低的系统。
-
select锁定记录
- select * from table where ?;不加锁
- 将查询放到事物中
- select * from table where ? lock in share mode;加共享锁
- select * from table where ? for update;加排它锁
- insert, update, delete;加排它锁
-
隔离级别
- read uncommit:读不加锁,写加共享锁。会产生脏读、幻读。
- read commit:读加共享锁,写加排它锁,但不加间隙锁。间隙锁的主要作用是防止不可重复读,但会加大锁的范围。
- repeatable read(innodb默认):读加共享锁,写加间隙排它锁。注意,Innodb对这个级别进行了特殊处理,使得这个级别能够避免幻读,但不是所有引擎都能够防止幻读!(网易面试官问)
- serialization:会给整张表加锁,强一致,但是效率低。
-
innodb中的锁
- MVCC(multi-Version Concurrency Control):读不加锁,读写不冲突。适合写少读多的场景。读操作分为:快照读(返回记录的可见版本,不加锁)、当前读(记录的最新版本,加锁,保证其它记录不修改)。
- LBCC(Lock-Based Concurrency Control):
-
join原理
- Simple Nested-Loop Join:效率最低,按照join的次序,在join的属性上一个个扫描,并合并结果。
- Index Nested-Loop Join:效率最高,join的属性上面有索引,根据索引来匹配。
- Block Nested-Loop Join:用于没有索引的列。它会采用join buffer,将外表的值缓存到join buffer中,然后与内表进行批量比较,这样可以降低对外表的访问频率
-
galera
- 多主架构:真正的多点读写的集群,在任何时候读写数据,都是最新的。
- 同步复制,各节点间无延迟且节点宕机不会导致数据丢失。
- 紧密耦合,所有节点均保持相同状态,节点间无不同数据。
- 无需主从切换操作。
- 无需进行读写分离。
- 并发复制:从节点在APPLY数据时,支持并行执行,有更好的性能表现。
- 故障切换:在出现数据库故障时,因为支持多点写入,切的非常容易。
- 热插拔:在服务期间,如果数据库挂了,只要监控程序发现的够快,不可服务时间就会非常少。在节点故障期间,节点本身对集群的影响非常小。
- 自动节点克隆:在新增节点,或者停机维护时,增量数据或者基础数据不需要人工手动备份提供,Galera Cluster会自动拉取在线节点数据,最终集群会变为一致。
- 对应用透明:集群的维护,对应用程序是透明的,几乎感觉不到。
-
以下是缺点
- 目前的复制仅仅支持InnoDB存储引擎
- DELETE操作不支持没有主键的表
- 在多主环境下LOCK/UNLOCK TABLES不支持以及锁函数GET_LOCK(), RELEASE_LOCK()
- 由于集群是乐观的并发控制,事务commit可能在该阶段中止。
- 整个集群的写入吞吐量是由最弱的节点限制,如果有一个节点变得缓慢,那么整个集群将是缓慢的。为了稳定的高性能要求,所有的节点应使用统一的硬件。
-
LSM Tree,主要应用于nessDB、leveldb、hbase
- 核心思想的核心就是放弃部分读能力,换取写入的最大化能力。它假设假定内存足够大,因此不需要每次有数据更新就必须将数据写入到磁盘中,而可以先将最新的数据驻留在内存中,等到积累到最后多之后,再使用归并排序的方式将内存内的数据合并追加到磁盘队尾。(使用归并排序是要因为带排序树都是有序树)
- LSM具有批量特性,存储延迟。B树在insert的时候可能会造成分裂,可能会造成随机读写。而LSM将多次单页随机写,变成一次多页随机写,复用了磁盘寻道时间,极大提升效率。
- LSM Tree放弃磁盘读性能来换取写的顺序性。
- 一般会使用Bloom Filter来优化LSM。当将内存中的数据与磁盘数据合并的时候,先要判断数据是否有重复,如果不用Bloom Filter就需要在磁盘上一层层地找,而使用了之后就会降低搜索代价。