https://github.com/CyC2018/CS-Notes/blob/master/notes/MySQL.md

存储引擎的区别

InnoDB: 支持事务,是面向在线事务处理(OLTP)的应用,特点是行锁设计,支持外键,并支持一致性非锁定读,即默认情况下读取操作不会产生锁.是默认的存储引擎:.还提供了插入缓冲,二次写,自适应哈希索引,预读等高性能和高可用的功能.MyISAM: 不支持事务,是表锁设计和支持全文索引,主要面向一些OLAP的数据库应用.它的缓冲池只缓冲索引文件,而不缓冲数据文件.该存储引擎表由MYD和MYI组成,MYD用来存放数据文件,MYI用来存放索引文件.NDB:是一个集群存储引擎,其特点是数据全部放在内存中,因此主键查找速度极快,并通过添加NDB数据库存储节点可以线性提高数据库性能,是高可用,高性能的集群系统.Memory: 将表中的数据存放在内存中,如果数据库重启或发生崩溃,表中的数据库都将消失,它非常适合存储临时数据的临时表.默认采用哈希索引.Archive: 只支持INSERT和SELECT操作,使用zlib算法将数据行进行压缩,压缩比可以达到1:10,非常适合存储归档数据.但其本身不是事务安全的存储引擎,其设计目标是提供高速的插入和压缩功能.Federated: 并不存放数据,它只是指向一台远程MySQL数据库服务器上的表.Maria存储引擎: 设计目标主要是用来取代原有的MyISAM存储引擎.

MyISAM和InnoDB的区别

  1. MyISAM是非事务安全型的,而InnoDB是事务安全型的。
  2. MyISAM锁的粒度是表级,而InnoDB支持行级锁定。
  3. MyISAM支持全文索引,而Innodb不支持全文索引
  4. MyISAM表是保存成文件形式的,在跨平台的数据转移中使用MyISAM存储会省去不少的麻烦。
  5. InnoDB表比MyISAM表更安全,可以保证数据不丢失的情况下,切换非事务表到事务表

应用场景

  1. MyISAM 管理非事务表,它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择。
  2. InnoDB用于事务处理应用程序,具有众多特性,包括ACID事务支持。如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB,这样可以提高多用户并发操作的性能。

sql注入原理

就是通过把SQL命令插入到Web 表单 提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令1.猜表名,列名等2.后台身份验证绕过漏洞验证绕过漏洞就是'or'='or'后台绕过漏洞,利用的就是AND和OR的运算规则,从而造成后台脚本逻辑性错误.

防范:1.永远不要信任用户的输入,要对用户的输入进行校验,可以通过正则表达式,或限制长度,对单引号和双"-"进行转换等。2.永远不要使用动态拼装SQL,可以使用参数化的SQL或者直接使用存储过程进行数据查询存取。3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。4.不要把机密信息明文存放,请加密或者hash掉密码和敏感的信息。5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装,把异常信息存放在独立的表中。

数据库范式

第一范式(1NF):属性不可分。比如某些数据库系统中需要用到“地址”这个属性,本来直接将“地址”属性设计成一个数据库表的字段就行。但是如果系统经常会访问“地址”属性中的“城市”部分,那么就非要将“地址”这个属性重新拆分为省份、城市、详细地址等多个部分进行存储,这样在对地址中某一部分操作的时候将非常方便。第二范式(2NF):符合1NF,并且,非主属性完全依赖于码(也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中)第三范式(3NF):符合2NF,并且,消除传递依赖(每一列数据都和主键直接相关,而不能间接相关)。BCNF:符合3NF,并且,没有任何属性完全函数依赖于非码的任何一组属性.找个例子说.

参考: http://www.cnblogs.com/linjiqin/archive/2012/04/01/2428695.htmlhttp://blog.sina.com.cn/s/blog_46d817650100yj2i.html

数据库索引

索引是一个单独存储在磁盘上的数据库结构,它们包含着对数据表里所有记录的引用指针,使用索引可以提高数据库特定数据的查询速度.索引时在存储引擎中实现的,因此每种存储引擎的索引不一定完全相同,并且每种存储引擎也不一定支持所有索引类型.

索引的存储类型有两种:BTREE和HASH,具体和表的存储引擎有关.MyISAM和InnoDB存储引擎只支持BTREE;MEMORY/HEAD存储索引可以支持HASH和BTREE索引.索引的优点:

  1. 通过创建唯一索引,可以保证数据库表中每行数据的唯一性.
  2. 可以加快数据的查询速度.
  3. 在实现数据的参考完整性方面,可以加速表和表之间的连接.
  4. 再使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间
  5. 通过使用索引,可以在查询中使用优化隐藏器,提高系统的性能。

索引的缺点

  1. 创建索引和维护索引要耗费时间,并且随着数据量的增加耗费时间也增加.
  2. 索引需要占空间内存.
  3. 在对表中数据进行增加,删除和修改的时候,索引也需要动态维护,这样降低了数据维护速度.

索引分类

  1. 普通索引和唯一索引
  2. 直接创建索引和间接创建索引
  3. 普通索引和唯一性索引
  4. 单个索引和符合索引
  5. 聚簇索引和非聚簇索引

索引失效??

  1. WHERE字句的查询条件里有不等于号(WHERE column!=...),MYSQL将无法使用索引
  2. 如果WHERE字句的查询条件里使用了函数(如:WHERE DAY(column)=...),MYSQL将无法使用索引
  3. 在JOIN操作中(需要从多个数据表提取数据时),MYSQL只有在主键和外键的数据类型相同时才能使用索引,否则即使建立了索引也不会使用。
  4. 如果WHERE子句的查询条件里使用了比较操作符LIKE和REGEXP,MYSQL只有在搜索模板的第一个字符不是通配符的情况下才能使用索引。比如说,如果查询条件是LIKE 'abc%',MYSQL将使用索引;如果条件是LIKE '%abc',MYSQL将不使用索引。
  5. 在ORDER BY操作中,MYSQL只有在排序条件不是一个查询条件表达式的情况下才使用索引。尽管如此,在涉及多个数据表的查询里,即使有索引可用,那些索引在加快ORDER BY操作方面也没什么作用。
  6. 如果某个数据列里包含着许多重复的值,就算为它建立了索引也不会有很好的效果。比如说,如果某个数据列里包含了净是些诸如“0/1”或“Y/N”等值,就没有必要为它创建一个索引。
  7. 如果条件中有or(并且其中有or的条件是不带索引的),即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)。注意:要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引。
  8. 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引。
  9. 如果mysql估计使用全表扫描要比使用索引快,则不使用索引。

http://www.cnblogs.com/hongfei/archive/2012/10/20/2732589.htmlhttp://my.oschina.net/hebad/blog/370815

数据库锁机制

数据库锁定机制简单来说就是数据库为了保证数据的一致性而使各种共享资源在被并发访问,访问变得有序所设计的一种规则。MySQL各存储引擎使用了三种类型(级别)的锁定机制:行级锁定,页级锁定和表级锁定。

  • 表级锁定(table-level):表级别的锁定是MySQL各存储引擎中最大颗粒度的锁定机制。该锁定机制最大的特点是实现逻辑非常简单,带来的系统负面影响最小。所以获取锁和释放锁的速度很快。由于表级锁一次会将整个表锁定,所以可以很好的避免困扰我们的死锁问题。当然,锁定颗粒度大所带来最大的负面影响就是出现锁定资源争用的概率也会最高,致使并大度大打折扣。表级锁分为读锁和写锁。

  • 页级锁定(page-level):页级锁定的特点是锁定颗粒度介于行级锁定与表级锁之间,所以获取锁定所需要的资源开销,以及所能提供的并发处理能力也同样是介于上面二者之间。另外,页级锁定和行级锁定一样,会发生死锁。

  • 行级锁定(row-level):行级锁定最大的特点就是锁定对象的颗粒度很小,也是目前各大数据库管理软件所实现的锁定颗粒度最小的。由于锁定颗粒度很小,所以发生锁定资源争用的概率也最小,能够给予应用程序尽可能大的并发处理能力而提高一些需要高并发应用系统的整体性能。虽然能够在并发处理能力上面有较大的优势,但是行级锁定也因此带来了不少弊端。由于锁定资源的颗粒度很小,所以每次获取锁和释放锁需要做的事情也更多,带来的消耗自然也就更大了。此外,行级锁定也最容易发生死锁。InnoDB的行级锁同样分为两种,共享锁和排他锁,同样InnoDB也引入了意向锁(表级锁)的概念,所以也就有了意向共享锁和意向排他锁,所以InnoDB实际上有四种锁,即共享锁(S)、排他锁(X)、意向共享锁(IS)、意向排他锁(IX);在MySQL数据库中,使用表级锁定的主要是MyISAM,Memory,CSV等一些非事务性存储引擎,而使用行级锁定的主要是Innodb存储引擎和NDBCluster存储引擎,页级锁定主要是BerkeleyDB存储引擎的锁定方式。

而意向锁的作用就是当一个事务在需要获取资源锁定的时候,如果遇到自己需要的资源已经被排他锁占用的时候,该事务可以需要锁定行的表上面添加一个合适的意向锁。如果自己需要一个共享锁,那么就在表上面添加一个意向共享锁。而如果自己需要的是某行(或者某些行)上面添加一个排他锁的话,则先在表上面添加一个意向排他锁。意向共享锁可以同时并存多个,但是意向排他锁同时只能有一个存在。

  共享锁(S) 排他锁(X) 意向共享锁(IS) 意向排他锁(IX)
共享锁(S) 兼容 冲突 兼容 冲突
排他锁(X) 冲突 冲突 冲突 冲突
意向共享锁(IS) 兼容 冲突 兼容 兼容
意向排他锁(IX) 冲突 冲突 兼容 兼容

参考地址:http://www.cnblogs.com/ggjucheng/archive/2012/11/14/2770445.html

MyISAM 表锁优化建议:1、缩短锁定时间2、分离能并行的操作3、合理利用读写优先级

乐观锁,悲观锁

悲观锁:它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制。悲观的缺陷是不论是页锁还是行锁,加锁的时间可能会很长,这样可能会长时间的限制其他用户的访问,也就是说悲观锁的并发访问性不好。乐观锁( Optimistic Locking ) :相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则则拒绝更新并返回用户错误的信息,让用户决定如何去做。乐观锁由程序实现,不会存在死锁问题。它适用的场景也相对乐观。但乐观锁不能解决脏读的问题

悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。[1]乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。[1] 乐观锁不能解决脏读的问题。

事务隔离机制

事务隔离级别:

  • 未提交读(READ UNCOMMITTED):事务中的修改,即使未提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也称为脏读。
  • 提交读(READ COMMITTED):一个事物从开始到提交之前,所做的任何修改对其他事物都是不可见的,这个级别有时候叫做不可重复读。这个级别上两次执行同样的查询会得到不一样的结果。
  • 可重复读(REPEATABLE READ):解决了脏读问题,该级别保证了在同一个事务中多次读同样记录的结果是一致的,理论上无法解决幻读问题。幻读就是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入新的记录,当之前的事物再次读取该范围的记录时会产生幻行。
  • 可串行化(SERIZLIZABLE):它通过强制事务串行执行,避免了前面说的幻读的问题。
  脏读 不可重复读 幻读可能性 加锁读
未提交读 YES YES YES NO
提交读 NO YES YES NO
可重复读 NO NO YES NO
可串行化 NO NO NO YES

脏读、不可重复读和幻读

  1. 脏读: 事务T1更新了一行记录内容,但并没有提交修改。事务T2读取更新后的行,然后T1执行回滚操作。读取了刚才所做的修改。现在T2读取的行就无效了。(一个事务读取了另一个事务未提交的数据)
  2. 不可重复读:事务T1读取了一行记录,紧接着T2修改了T1刚才读取的那一行记录,然后T1又再次读取这行记录,发现与刚才读取的结果不同。
  3. 幻读:事务T1读取一个结果集,然后T2事务在T1结果集范围内插入一行记录。然后T1再次对表进行检索,发现多了T2插入的数据。

数据库事务属性

事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性,通常简称为事务的ACID属性。原子性(Atomicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态,即要求事务做完后,要求满足数据库的一些完整性约。这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性;事务结束时,所有的内部数据结构(如B树索引或双向链表)也都必须是正确的。隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然。持久性(Durable):事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。

数据库事务的几种粒度;

是否了解数据库的索引是如何实现的

MyISAM索引实现

MyISAM索引使用了B+Tree作为索引结构,叶子结点的data域存放的是数据记录的地址。MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。主索引和辅助索引的存储结构没有任何区别。

InnoDB索引实现

虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。第一个重大区别是InnoDB的数据文件本身就是索引文件。从上文知道,MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据。第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域。

Memory索引实现

Memory索引适用于需要快速访问数据的场景,显示支持哈希索引。内部基于哈希表数据结构实现,只包含哈希值和行指针,对于每一行数据,存储引擎都会对所有的引擎列计算一个哈希码,在哈希表对应位置存放该行数据的指针或地址。为了解决多个hash冲突问题,哈希索引采用了链地址法来解决冲突问题。所以采用链表数组作为存储结构。这种索引结构十分紧凑,且具有很快的查询速度。但也存在一些问题,

  1. 哈希表数据不是按照索引顺序存储的,所以无法用于排序。
  2. 只能支持等值比较查询。
  3. 存在冲突情况下查询速度变慢。
  4. 如果宕机,数据丢失https://msdn.microsoft.com/zh-cn/library/dn133190.aspx

索引实现涉及的一些B树概念:

BTree,B-Tree,B+Tree,B*Tree都是什么

B树

即二叉搜索树:

1.所有非叶子结点至多拥有两个儿子(Left和Right);

2.所有结点存储一个关键字;

3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树;

如:

B树的搜索,从根结点开始,如果查询的关键字与结点的关键字相等,那么就命中;否则,如果查询关键字比结点关键字小,就进入左儿子;如果比结点关键字大,就进入右儿子;如果左儿子或右儿子的指针为空,则报告找不到相应的关键字;

如果B树的所有非叶子结点的左右子树的结点数目均保持差不多(平衡),那么B树的搜索性能逼近二分查找;但它比连续内存空间的二分查找的优点是,改变B树结构(插入与删除结点)不需要移动大段的内存数据,甚至通常是常数开销;

如:

但B树在经过多次插入与删除后,有可能导致不同的结构:

右边也是一个B树,但它的搜索性能已经是线性的了;同样的关键字集合有可能导致不同的树结构索引;所以,使用B树还要考虑尽可能让B树保持左图的结构,和避免右图的结构,也就是所谓的“平衡”问题;

实际使用的B树都是在原B树的基础上加上平衡算法,即“平衡二叉树”;如何保持B树结点分布均匀的平衡算法是平衡二叉树的关键;平衡算法是一种在B树中插入和删除结点的策略;

B-树

是一种多路搜索树(并不是二叉的):

1.定义任意非叶子结点最多只有M个儿子;且M>2;

2.根结点的儿子数为[2, M];

3.除根结点以外的非叶子结点的儿子数为[M/2, M];

4.每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)

5.非叶子结点的关键字个数=指向儿子的指针个数-1;

6.非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];

7.非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;

8.所有叶子结点位于同一层;

如:(M=3)

B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的儿子指针为空,或已经是叶子结点;

B-树的特性:

1.关键字集合分布在整颗树中;

2.任何一个关键字出现且只出现在一个结点中;

3.搜索有可能在非叶子结点结束;

4.其搜索性能等价于在关键字全集内做一次二分查找;

5.自动层次控制;

由于限制了除根结点以外的非叶子结点,至少含有M/2个儿子,确保了结点的至少利用率,其最底搜索性能为:

其中,M为设定的非叶子结点最多子树个数,N为关键字总数;

所以B-树的性能总是等价于二分查找(与M值无关),也就没有B树平衡的问题;

由于M/2的限制,在插入结点时,如果结点已满,需要将结点分裂为两个各占M/2的结点;删除结点时,需将两个不足M/2的兄弟结点合并;

B+树

B+树是B-树的变体,也是一种多路搜索树:

1.其定义基本与B-树同,除了:

2.非叶子结点的子树指针与关键字个数相同;

3.非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);

5.为所有叶子结点增加一个链指针;

6.所有关键字都在叶子结点出现;

如:(M=3)

B+的搜索与B-树也基本相同,区别是B+树只有达到叶子结点才命中(B-树可以在非叶子结点命中),其性能也等价于在关键字全集做一次二分查找;

B+的特性:

1.所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;

2.不可能在非叶子结点命中;

3.非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;

4.更适合文件索引系统;

B*树

是B+树的变体,在B+树的非根和非叶子结点再增加指向兄弟的指针;

B*树定义了非叶子结点关键字个数至少为(2/3)*M,即块的最低使用率为2/3(代替B+树的1/2);

B+树的分裂:当一个结点满时,分配一个新的结点,并将原结点中1/2的数据复制到新结点,最后在父结点中增加新结点的指针;B+树的分裂只影响原结点和父结点,而不会影响兄弟结点,所以它不需要指向兄弟的指针;

B*树的分裂:当一个结点满时,如果它的下一个兄弟结点未满,那么将一部分数据移到兄弟结点中,再在原结点插入关键字,最后修改父结点中兄弟结点的关键字(因为兄弟结点的关键字范围改变了);如果兄弟也满了,则在原结点与兄弟结点之间增加新结点,并各复制1/3的数据到新结点,最后在父结点增加新结点的指针;

所以,B*树分配新结点的概率比B+树要低,空间使用率更高;

小结

B树:二叉树,每个结点只存储一个关键字,等于则命中,小于走左结点,大于走右结点;

B-树:多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键字范围的子结点;

所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;

B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中;

B*树:在B+树基础上,为非叶子结点也增加链表指针,将结点的最低利用率从1/2提高到2/3;

MySQL索引背后的数据结构及算法原理

为什么使用B-Tree(B+Tree)

上文说过,红黑树等数据结构也可以用来实现索引,但是文件系统及数据库系统普遍采用B-/+Tree作为索引结构,这一节将结合计算机组成原理相关知识讨论B-/+Tree作为索引的理论基础。

一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样的话,索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,所以评价一个数据结构作为索引的优劣最重要的指标就是在查找过程中磁盘I/O操作次数的渐进复杂度。换句话说,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。下面先介绍内存和磁盘存取原理,然后再结合这些原理分析B-/+Tree作为索引的效率。

主存存取原理

目前计算机使用的主存基本都是随机读写存储器(RAM),现代RAM的结构和存取原理比较复杂,这里本文抛却具体差别,抽象出一个十分简单的存取模型来说明RAM的工作原理。

图5

从抽象角度看,主存是一系列的存储单元组成的矩阵,每个存储单元存储固定大小的数据。每个存储单元有唯一的地址,现代主存的编址规则比较复杂,这里将其简化成一个二维地址:通过一个行地址和一个列地址可以唯一定位到一个存储单元。图5展示了一个4 x 4的主存模型。

主存的存取过程如下:

当系统需要读取主存时,则将地址信号放到地址总线上传给主存,主存读到地址信号后,解析信号并定位到指定存储单元,然后将此存储单元数据放到数据总线上,供其它部件读取。

写主存的过程类似,系统将要写入单元地址和数据分别放在地址总线和数据总线上,主存读取两个总线的内容,做相应的写操作。

这里可以看出,主存存取的时间仅与存取次数呈线性关系,因为不存在机械操作,两次存取的数据的“距离”不会对时间有任何影响,例如,先取A0再取A1和先取A0再取D3的时间消耗是一样的。

磁盘存取原理

上文说过,索引一般以文件形式存储在磁盘上,索引检索需要磁盘I/O操作。与主存不同,磁盘I/O存在机械运动耗费,因此磁盘I/O的时间消耗是巨大的。

图6是磁盘的整体结构示意图。

图6

一个磁盘由大小相同且同轴的圆形盘片组成,磁盘可以转动(各个磁盘必须同步转动)。在磁盘的一侧有磁头支架,磁头支架固定了一组磁头,每个磁头负责存取一个磁盘的内容。磁头不能转动,但是可以沿磁盘半径方向运动(实际是斜切向运动),每个磁头同一时刻也必须是同轴的,即从正上方向下看,所有磁头任何时候都是重叠的(不过目前已经有多磁头独立技术,可不受此限制)。

图7是磁盘结构的示意图。

图7

盘片被划分成一系列同心环,圆心是盘片中心,每个同心环叫做一个磁道,所有半径相同的磁道组成一个柱面。磁道被沿半径线划分成一个个小的段,每个段叫做一个扇区,每个扇区是磁盘的最小存储单元。为了简单起见,我们下面假设磁盘只有一个盘片和一个磁头。

当需要从磁盘读取数据时,系统会将数据逻辑地址传给磁盘,磁盘的控制电路按照寻址逻辑将逻辑地址翻译成物理地址,即确定要读的数据在哪个磁道,哪个扇区。为了读取这个扇区的数据,需要将磁头放到这个扇区上方,为了实现这一点,磁头需要移动对准相应磁道,这个过程叫做寻道,所耗费时间叫做寻道时间,然后磁盘旋转将目标扇区旋转到磁头下,这个过程耗费的时间叫做旋转时间。

局部性原理与磁盘预读

由于存储介质的特性,磁盘本身存取就比主存慢很多,再加上机械运动耗费,磁盘的存取速度往往是主存的几百分分之一,因此为了提高效率,要尽量减少磁盘I/O。为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。这样做的理论依据是计算机科学中著名的局部性原理:

当一个数据被用到时,其附近的数据也通常会马上被使用。

程序运行期间所需要的数据通常比较集中。

由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率。

预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(在许多操作系统中,页得大小通常为4k),主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回,程序继续运行。

B-/+Tree索引的性能分析

从使用磁盘I/O次数评价索引结构的优劣性:根据B-Tree的定义,可知检索一次最多需要访问h个结点。数据库系统的设计者巧妙的利用了磁盘预读原理,将一个结点的大小设为等于一个页面,这样每个结点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧:

每次新建结点时,直接申请一个页面的空间,这样可以保证一个结点的大小等于一个页面,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。

B-Tree中一次检索最多需要h-1次I/O(根结点常驻内存),渐进复杂度为O(h)=O(logdN)。一般实际应用中,出读d是非常大的数字,通常超过100,因此h非常小。

综上所述,用B-Tree作为索引结构效率是非常高的。

而红黑树结构,h明显要深得多。由于逻辑上很近的结点(父子结点)物理上可能离得很远,无法利用局部性原理。所以即使红黑树的I/O渐进复杂度也为O(h),但是查找效率明显比B-Tree差得多。

B+Tree更适合外存索引,是和内结点出度d有关。从上面分析可以看到,d越大索引的性能越好,而出度的上限取决于结点内key和data的大小:dmax=floor(pagesize/(keysize+datasize+pointsize))。

floor表示向下取整。由于B+Tree内结点去掉了data域,因此可以拥有更大的出度,拥有更好的性能。

Hash索引

hash索引

1、概述及存储结构

主要就是通过Hash算法(常见的Hash算法有直接定址法、平方取中法、折叠法、除数取余法、随机数法),将数据库字段数据转换成定长的Hash值,与这条数据的行指针一并存入Hash表的对应位置;如果发生Hash碰撞(两个不同关键字的Hash值相同),则在对应Hash键下以链表形式存储。

检索算法:在检索查询时,就再次对待查关键字再次执行相同的Hash算法,得到Hash值,到对应Hash表对应位置取出数据即可,如果发生Hash碰撞,则需要在取值时进行筛选。目前使用Hash索引的数据库并不多,主要有Memory等。

2、Hash索引的弊端

一般来说,索引的检索效率非常高,可以一次定位,不像B-Tree索引需要进行从根节点到叶节点的多次IO操作。有利必有弊,Hash算法在索引的应用也有很多弊端。

a、Hash索引仅仅能满足等值的查询,范围查询不保证结果正确。因为数据在经过Hash算法后,其大小关系就可能发生变化。

b、Hash索引不能被排序。同样是因为数据经过Hash算法后,大小关系就可能发生变化,排序是没有意义的。

c、Hash索引不能避免表数据的扫描。因为发生Hash碰撞时,仅仅比较Hash值是不够的,需要比较实际的值以判定是否符合要求。

d、Hash索引在发生大量Hash值相同的情况时性能不一定比B-Tree索引高。因为碰撞情况会导致多次的表数据的扫描,造成整体性能的低下,可以通过采用合适的Hash算法一定程度解决这个问题。

e、Hash索引不能使用部分索引键查询。因为当使用组合索引情况时,是把多个数据库列数据合并后再计算Hash值,所以对单独列数据计算Hash值是没有意义的。

Full-Text索引

1、概述

全文索引,目前MySQL中只有MyISAM存储引擎支持,并且只有CHAR、VARCHAR、TEXT类型支持。它用于替代效率较低的LIKE模糊匹配操作,而且可以通过多字段组合的全文索引一次性全模糊匹配多个字段。

2、存储结构

同样使用B-Tree存放索引数据,但使用的是特定的算法,将字段数据分割后再进行索引(一般每4个字节一次分割),索引文件存储的是分割前的索引字符串集合,与分割后的索引信息,对应Btree结构的节点存储的是分割后的词信息以及它在分割前的索引字符串集合中的位置。

数据库连接池原理

背景

传统的数据库连接方式是,用户每次请求都要向数据库获取连接,而数据库连接的创建和关闭需要一定的开销。频繁的建立、关闭数据库,会极大的降低系统的性能,增大系统的开销,甚至成为系统的瓶颈。另外使用这种传统的模式,还必须管理数据库的每一个连接,以确保他们能正确关闭,如果出现程序异常而导致某些连接未能关闭。同时无节制的创建连接极易导致数据库服务器内存溢出。

原理

数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。以及一套连接使用、分配、管理策略,使得该连接池中的连接可以得到高效、安全的复用,避免了数据库连接频繁建立、关闭的开销。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。

开源java连接池:

现在很多Web服务器(Weblogic, WebSphere, Tomcat)都提供了DataSoruce的实现,即连接池的实现。通常我们把DataSource的实现,按其英文含义称之为数据源,数据源中都包含了数据库连接池的实现。

1.C3P0 :是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。参考网站: http://sourceforge.net/projects/c30/

2.Proxool :是一个Java SQL Driver驱动程序,提供了对你选择的其它类型的驱动程序的连接池封装。可以非常简单的移植到现存的代码中。完全可配置。快速,成熟,健壮。可以透明地为你现存的JDBC驱动程序增加连接池功能。 参考网站: http://proxool.sourceforge.net

3.Jakarta DBCP :是一个依赖Jakarta commons-pool对象池机制的数据库连接池.DBCP可以直接的在应用程序用使用。参考网站: http://jakarta.apache.org/commons/dbcp/

原理: http://www.uml.org.cn/sjjm/201004153.asp实现: http://www.cnblogs.com/lihuiyy/archive/2012/02/14/2351768.html

连接池使用什么数据结构实现链表

实现连接池: http://www.cnblogs.com/lihuiyy/archive/2012/02/14/2351768.html四个表 记录成绩,每个大约十万条记录,如何找到成绩最好的同学servlet的一些相关问题webservice相关

mysql有那些存储引擎,分别有什么特点

MySQL存储引擎 优化 索引问题相关推荐

  1. mysql存储引擎优化参数

    MySQL配置参数优化 本文来自道森学习笔记,版权归 http://wubx.net/ 所有 MyISAM存储引擎优化 涉及参数如下: Key_buffery_size Concurrent_inse ...

  2. 【MySQL】MySQL 存储引擎、索引、锁、集群

    MySQL存储引擎 MySQL体系结构 体系结构的概念任何一套系统当中,每个部件都能起到一定的作用! MySQL的体系结构 体系结构详解 客户端连接 支持接口:支持的客户端连接,例如C.Java.PH ...

  3. MySQL存储引擎以及索引

    文章目录 一.数据库引擎 1. 查看数据库引擎 2. 查看表结构 3. 查看表相关文件 4. 各存储引擎的区别 二.MySQL索引 1. 索引分类 2. 索引的创建和删除 3. 关于缓存问题 4. 过 ...

  4. MySQL——存储引擎与索引应用

    文章目录 一. 存储引擎 1.1 MySQL结构 1.2 存储引擎简介 1.3 存储引擎特点 1.3.1 InnoDB 1.3.1.1 InnoDB 基本介绍 1.3.1.2 InnoDB 逻辑存储结 ...

  5. MySQL存储引擎,索引,锁机制

    一,MySQL存储引擎 介绍: MySQL数据库使用不同的机制存取表文件,包括存储方式,索引技巧,锁定水平等不同的功能,这些不同的技术以及配套的功能称为索引引擎 Oracle,Sqlserver等数据 ...

  6. 后端学习 - MySQL存储引擎、索引与事务

    文章目录 一 存储引擎 1 MyISAM 与 InnoDB 的差异 2 表级锁与行级锁 二 索引 1 主键索引与二级索引 2 聚簇索引与非聚簇索引 3 数据结构:哈希表 4 数据结构:B树 5 数据结 ...

  7. mysql存储引擎 索引优化_MySQL存储引擎,索引及基本优化策略

    存储引擎 与Oracle, SQL Server这些数据库不同,MySQL提供了多种存储引擎.什么是存储引擎?存储引擎其实就是一套对于数据如何存储,查询,更新,建立索引等接口的实现.不同存储引擎特性有 ...

  8. mysql 学习笔记--存储引擎、索引、sq优化

    全面的 mysql学习笔记–通用语法.函数.数据类型.约束.多表查询.事务 全面的 mysql学习笔记–存储引擎.索引.sql优化 全面的mysql学习笔记–视图/存储过程/触发器.锁.InnoDB引 ...

  9. 为什么用B+树做索引MySQL存储引擎简介

    索引的数据结构 为什么不是二叉树,红黑树什么的呢? 首先,一般来说,索引本身也很大,不可能全部存在内存中,因此索引往往以索引文件的方式存在磁盘上.然后一般一个结点一个磁盘块,也就是读一个结点要进行一次 ...

最新文章

  1. GPT-3等三篇论文获NeurIPS2020最佳论文奖 | AI日报
  2. [译][python]ImportError:attempted relative import with no known parent package
  3. LeetCode215:数组中第K个最大元素
  4. (转)在WCF服务的ServiceReferences.ClientConfig中使用相对路径
  5. 随机生成元素升序向量_推荐系统中用户向量的表示学习
  6. 设计模式——4.抽象工厂模式
  7. go mysql recover_golang用panic和recover做业务流程中断的尝试
  8. 自制 移动端 纯原生 Slider滑动插件
  9. “农业大数据”专题征文通知
  10. oracle 最小权限,oracle低权限下获取shell
  11. ajax-page局部刷新分页实例
  12. 使用Async方法 Using Async Methods 精通ASP-NET-MVC-5-弗瑞曼 Listing 4-32.
  13. 云服务器发送开锁信息给单车,云服务器发送开锁信息给单车
  14. 数据挖掘导论课后习题答案-第二章
  15. 年仅30岁!腾讯游戏程序员毛星云意外身故。。。
  16. 计算机网络吞吐量计算
  17. 微信接口类php,【微信接口库】分享10个常用的php微信接口类
  18. k8s rbac 权限管理控制创建过程+理论知识
  19. 懒羊羊找朋友 C++
  20. 国外大学诸多自学课程

热门文章

  1. node js 写按键精灵_带有按键的Node.js Raw模式
  2. SqlServer 对数据库文件进行增删改查
  3. C专家编程 读书笔记
  4. XYOJ1255: 寻找最大数X(按数的一个一个元素输出)
  5. antv G2 折线图遇到的坑
  6. 怎么调整计算机的音量,教你电脑声音如何调大
  7. centos7安装并使用licode四:下载licode并使用
  8. CVE-2020-11100: HAProxy 内存越界写入漏洞通告
  9. “不安分”的花椒直播,搞了史上首个网红演唱会
  10. “旁观者”给阿里未来发展“把的脉”