数据库索引的坏处
作者:互联网
一、数据库索引的坏处
索引是完全独立于基础数据之外的一部分数据。假 设在Table ta 中的Column ca 创建了索引 idx_ta_ca,那么任何更新 Column ca 的操作,MySQL在更新表中 Column ca的同时,都须要更新Column ca 的索引数据,调整因为更新带来键值变化的索引信息。而如果没有对 Column ca 进行索引,MySQL要做的仅仅是更新表中 Column ca 的信息。这样,最明显的资源消耗就是增加了更新所带来的 IO 量和调整索引所致的计算量。此外,Column ca 的索引idx_ta_ca须要占用存储空间,而且随着 Table ta 数据量的增加,idx_ta_ca 所占用的空间也会不断增加,所以索引还会带来存储空间资源消耗的增加。
较频繁的作为查询条件的字段应该创建索引
唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件
唯一性太差的字段主要是指哪些呢?如状态字段、类型字段等这些字段中存放的数据可能总共就是那么几个或几十个值重复使用,每个值都会存在于成千上万 或更多的记录中。对于这类字段,完全没有必要创建单独的索引。因为即使创建了索引,MySQL Query Optimizer 大多数时候也不会去选择使用,如果什么时候 MySQL Query Optimizer选择了这种索引,那么非常遗憾地告诉你,这可能会带来极大的性能问题。由于索引字段中每个值都含有大量的记录,那么存储引擎在根据索引 访问数据的时候会带来大量的随机IO,甚至有些时候还会出现大量的重复IO。
二、数据库事务
在介绍分布式事务之前,先简单了解下数据库事务。
数据库事务(Database Transaction) :是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
事务具有ACID四个特性:
1、原子性(Atomic):事务必须是原子工作单元,对于其修改数据,要么全部成功,要么全部失败。
2、一致性(Consistent):事务在完成时,必须使所有的数据都保持一致状态。
3、隔离性(Insulation):由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。
4、持久性(Duration):事务完成之后,它对于系统的影响是永久性的。
三、分布式事务
在分布式系统中,不止使用一个数据库,比如订单系统使用db_order数据库,产品系统使用的是db_product数据库,在订单系统中只能保证订单相关操作的事务,在产品系统中只能保证产品相关操作的事务。比如:如果在订单系统中进行生成订单、扣减库存的业务,如果出现异常,那么创建订单的事务会回滚,而扣减库存的事务则不会,因为本地事务是不能夸数据库的。跨库的事务就属于分布式事务。
把分布式系统中两个相关操作看成是一个单元,比如创建订单和修改库存的操作,该单元要么一起成功,要么一起失败,这就是分布式事务。
关于分布式事务你不得不知的两个理论:
1、CAP定理
CAP原则又称CAP定理,指的是在一个分布式系统中,WEB服务无法同时满足以下3个特性:
-
一致性(Consistency) : 在分布式系统中数据一旦更新,所有数据变动都是同步的
-
可用性(Availability) : 好的响应性能,每个操作都必须有预期的响应结束
-
分区容错性(Partition tolerance) : 在网络分区的情况下,即使出现单个节点无法可用,系统依然正常对外提供服务
首先在分布式系统中,横向扩展策略依赖于数据分区,所以一般会在一致性和可用性上做出牺牲。
2、BASE理论
BASE理论中的三个特性:
-
Basically Available(基本可用)
-
Soft state(软状态)
-
Eventually consistent(最终一致性)
三个特性分别指的是:
(1)基本可用是指分布式系统在出现不可预知的故障的时候,允许损失部分可用性——但请注意,这绝不等价于系统不可用。
(2)软状态,和硬状态对应,是指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统不同节点的数据副本之间进行数据同步的过程存在延时。
(3)最终一致性强调的是系统所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要试试保证系统数据的强一致性。
BASE理论是对CAP中的一致性和可用性进行一个权衡的结果,理论的核心思想就是:我们无法做到强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。
三、分布式事务解决方案
主要介绍目前主流的两种分布式事务解决方案:
1、TCC-补偿型事务解决方案
TCC指的是Try(尝试)、Confirm(确认)、Cancle(取消),其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。它分为三个阶段:
-
Try 阶段主要是对业务系统做检测及资源预留
-
Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。
-
Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。
举个例子,假入 Bob 要向 Smith 转账,思路大概是:
1、首先在 Try 阶段,要先调用远程接口把 Smith 和 Bob 的钱给冻结起来。
2、在 Confirm 阶段,执行远程调用的转账的操作,转账成功进行解冻。
3、如果第2步执行成功,那么转账成功,如果第二步执行失败,则调用远程冻结接口对应的解冻方法 (Cancel)。
优点: 跟两阶段提交(2PC)比起来,实现以及流程相对简单了一些,但数据的一致性比2PC也要差一些
缺点: 缺点还是比较明显的,在2,3步中都有可能失败。TCC属于应用层的一种补偿方式,所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。
2、基于可靠消息的最终一致性解决方案
举例说明:订单系统创建订单成功后、产品系统扣减相应库存
订单系统流程图如下:
1.创建订单之前,创建预发送消息,保存到消息表中,此时消息状态为:未发送
2.创建订单,如果创建订单失败则将消息表预发送消息删除
3.创建订单成功后,修改消息表预发送消息状态为发送中,并发送消息至mq
4.如果发送消息失败,则订单回滚并删除消息表消息;发送成功则万事大吉
产品系统流程图如下:
1.从mq消息中间件中监听并消费消息,将json消息转为订单对象
2.根据消息编号查询该消息是否已被消费,保证幂等性
3.如果消息未被消费(即存在此消息),则产品表扣减库存;如果已经消费(不存在此消息),则不做处理
4.产品表扣减库存成功,则删除此消息;扣减失败,则不做处理
5.定时任务会定时扫描消息表中超时未被消费的消息,然后尝试重发,如果超过最大重试次数后仍未被消费,则记录日志并通知工作人员进行人工补偿操作
基于可靠消息的分布式事务虽然不能保证结果的强一致,但是可以通过可靠消息使得结果最终一致
标签:事务,订单,数据库,坏处,索引,消息,一致性,ca 来源: https://www.cnblogs.com/zoro-zero/p/13494686.html