索引和日志:

        索引是一种排序好的数据结构,可以用于快速查询和检索数据。索引通过将键值对作为结点构成特定的数据结构:哈希表或者红黑树、B树和B+树等。在目前的数据库主流的引擎中,InnoDB和MyISAM都使用了B+树作为索引的数据结构。如果不使用索引:则在数据库中搜索数据的方式类似于在数组中完全遍历。查找符合条件的数据需要遍历整个数组。而如果引入索引,一种实现是会将主键按序构成一棵B+树(主键索引),我们进行数据查询时,会从这个索引B+树中进行查询。按照B+树的性质,最后会找到一个B+树的叶节点,而这个叶结点存储着取值在该范围内的数据的存储位置(MyISAM引擎使用)。InnoDB引擎则是叶节点就存储了数据本身,InnoDB的索引和数据文件本身都存在一个.idb文件中。

        一个创建索引的语句:CREATE INDEX 索引名 ON 表名(列名1,列名2,...);

索引的类型:

主键索引:

                B+树结点的key为主键的索引,如果没有主键,会寻找可以作为主键的属性,若都不适合,则会新开一个自增字段做主键。

二级索引:

        二级索引的叶子结点的数据域存储的是主键。

        分为:

                1)唯一索引:属性列不重复,数据不能为null。目的:保护属性列的唯一性。如何保护?在B+树中插入时发现相同的key。

                2)普通索引:加速查询数据。属性列可以为null或重复。

                3)前缀索引:使用该属性数据的前N个字符作为key创建索引。

                4)全文索引:使用所有字符作为key创建索引。

聚簇索引和非聚簇索引

        1)聚簇索引:数据和索引在同一个文件中一起存放。mysql中的主键索引即为聚簇索引。聚簇索引的属性列不宜修改,适合较为固定的能用作主键的属性。原因是如果修改此列中的数据,则会使索引调整(聚族索引的value就是数据,这些数据有可能较大,而非聚族索引的value常为主键值,因此移动聚簇索引的代价可能会很大),需要承担索引调整的代价。且需要属性列有序。

        2)非聚簇索引:索引和数据分开在不同的文件中存放的索引。二级索引就是非聚簇索引,由于非聚簇索引存放的value不是数据而是主键列的值,再通过这次得到的主键列的值去查一级索引。        优点:更新代价减小,但是会查询两次才能得到数据,且需要属性列有序。

        问:非聚族索引一定会回表查询吗?不一定:如果你要查询的data就是key值(当前B+树的key属性列)。

覆盖索引和联合索引:        

        1)覆盖索引:索引中包含了需要查询的属性的data,则为覆盖索引。

        2)联合索引:建立多个属性作为key的索引。

最左前缀匹配:在使用联合索引时,如果发现查询的条件中有当前最左侧(从左往右,每当前最左个过滤一部分,直到全部过滤完成)相匹配的字段,则会根据这个字段过滤掉一部分数据。

索引下推:过滤掉索引的key中与条件不匹配的元素,以减少回表次数。

使用索引的一些建议:

        1)选用不为null;

        2)选用频繁被查询的字段

        3)选用多出现在条件中的字段

        4)频繁使用排序(Order by)的字段

        5)尽量不选取频繁更新字段

        6)冗余较少的字段

        7)字符串类型使用前缀索引

避免索引失效:

        不要用select *

        联合索引遵守最左匹配原则

        不要在索引属性上使用计算

        用%号开头的数据也会失效

日志log的分类:

redo log:使得innoDB引擎可以从崩溃中恢复(物理日志)

        类似于把魔方直接拆了重建回1s之前的样子。

        数据库的数据是按页为单位记录的,每次读取时数据库读取一个页,从这个页中进行修改更新操作,数据被记录在一个一个的页中。redo log记录的是每次修改时,这一页的变化情况。在每一个事物提交前,都会先修改redo log buffer,redo log buffer再将自己的数据刷盘。

        刷盘模式有三种:可以通过参数innodb_flush_log_at_trx_commit=0修改

        参数为0时:事物提交不主动刷盘。

        参数为1时:每有一个事物提交就刷一次盘。

        参数为2时:有一个事物提交就更新一下文件系统缓存,文件系统缓存再按自己的机制刷盘。

        除此之外,innoDB引擎会1s内对redo log进行一次刷盘(固定)。

bin log:记录语句的原始逻辑(逻辑日志)

        类似于通过转动魔方来使魔方恢复。

        bin log用作数据库的备份和主从同步。其记录的格式可以是:statement(造成数据变化的sql语句),row(变化的实际数据)和mixed,例如:update tset  update_time = now() where id=1;         其中,1和now()就是row的存储范畴。但是对于now(),如果让statement来存储这条sql语句,等到要恢复的时候,now()会得到恢复时的时间,这就会导致与原先数据不一致。此时应该用row模式,将当时得到的now()的返回值做为恢复要执行的sql语句的相关数据存储起来。

        mixed模式:会自动检测当前sql语句是否会引起数据不一致,如果会,则使用row,否则使用statement。

机制:

        执行时间:在redo log写入之后,在事物完成提交之前。

        执行过程:写入bin log缓冲区,binlog缓冲区写到page cache中,OS负责从Page Cache写入到文件。

        存在问题:由于在redo log写入之后,事物完成提交之前。因此如果redo log已经写入,正在写bin log时,发生宕机。则可能会产生从服务器和主服务器的状态不一致的问题。(主服务器从redo log借助恢复,从服务器借助bin log中与主服务器主从同步)主服务器根据已经写入的redo log发现数据变了,而bin log由于在执行时宕机因此bin log上并没有记录这一次的操作。造成不一致的问题。

        解决方案:将redo log分为prepare状态和commit状态。在恢复时如果redo log中的记录为prepare状态,而bin log没有此记录,则回滚该事物。

        如果bin log有此记录,则该事物视为有效。

Undo Log:实现回滚机制,保证事物的原子性。

        undolog其实存储的也是逻辑日志,比如说我们要insert一条语句,那么undolog就记录着一条delete语句,所以说它可以用来做回滚。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值