8、常考其他
8.常考其他
8.0如何保证幂等性
幂等性概念:一次请求和多次请求造成的结果是一样的,不会因为多次点击而产生副作用。
什么情况会又可能会造成幂等性
多次点击 from 表单
网络的情况不好,超时问题,多次提交
消息队列出现超时问题
MySQL中可能出现幂等性问题的语句
insert操作,可能会出现重复值,但是自增 id 不一样
update情况,update 直接修改不会,但是那种修改数量 +1减1的情况,则有可能造成。
针对上面两种情况,我们应该如何处理
高并发情况下保证幂等性
1.对于insert操作,我们可以这样操作,先通过字段进行搜索,查看是否有该值。如果存在则执行 update或不进行操作,如果没有则 insert。
2.我们可以通过悲观锁
来实现,我们进行修改前先对其加锁,修改完成后再对其解锁,因为我们有insert 之前先判断的习惯,所以这样就能保证幂等性。
3.使用乐观锁
来实现,我们给数据加上版本号,修改前如果和第一次查询的版本号一致,则进行修改,同样可以保证幂等性。
4.加唯一索引
,我们可以通过唯一索引来解决,我们第一次可以添加成功,第二次的时候则不能添加成功。
5.建立防重表
,可以专门建立一个表,防止重复,这个表里存储的数据只有id和唯一索引的属性组,当我们能够插入防重表时,再通过防重表插入数据库。
6.根据状态机
这个就是订单生成的位置,通过订单状态来进行一个修改。如果我们第一次修改了状态之后,第二次就无法进行一个修改。
7.通过分布式锁
,也就是有缓存的情况,通过setnx来对缓存中数据加锁
推荐阅读:https://juejin.cn/post/6944559294939398158
8.1 分页查询
MySQL的每个页的大小为16KB,每个页里面使用了数组进行二分查找
,查找到目标ID所在的那一组,然后在组内遍历单链表进行查询。然后页(也就是B+树的节点)和页之间使用双向链表进行查询,但是我们的页太多时,则需要使用目录页来找到id所在页。

图片来自于:Yes的练级攻略
当我们增加数据时,如果使用自增id来实现的话,则会是追加操作,只需在后面开辟新的页即可,但是如果使用的不是自增ID则可能出现这种情况,就是页分裂,该页满了,将该页的某些数据挤到下一页,然后造成下一页也满了,这就有可能造成多个页分裂的情况,导致性能损耗。所以我们建议使用自增id作为主键。
8.2 如何分库分表
按照列进行划分,也就是属性,可以将表进行分割。
按照行id进行划分,取模等。
