8、常考其他

厨子大约 3 分钟数据库原创面试题MySQL程序厨

8.常考其他

8.0如何保证幂等性

幂等性概念:一次请求和多次请求造成的结果是一样的,不会因为多次点击而产生副作用。

什么情况会又可能会造成幂等性

  • 多次点击 from 表单

  • 网络的情况不好,超时问题,多次提交

  • 消息队列出现超时问题

MySQL中可能出现幂等性问题的语句

  1. insert操作,可能会出现重复值,但是自增 id 不一样

  2. update情况,update 直接修改不会,但是那种修改数量 +1减1的情况,则有可能造成。

针对上面两种情况,我们应该如何处理

高并发情况下保证幂等性

1.对于insert操作,我们可以这样操作,先通过字段进行搜索,查看是否有该值。如果存在则执行 update或不进行操作,如果没有则 insert。

2.我们可以通过悲观锁来实现,我们进行修改前先对其加锁,修改完成后再对其解锁,因为我们有insert 之前先判断的习惯,所以这样就能保证幂等性。

3.使用乐观锁来实现,我们给数据加上版本号,修改前如果和第一次查询的版本号一致,则进行修改,同样可以保证幂等性。

4.加唯一索引,我们可以通过唯一索引来解决,我们第一次可以添加成功,第二次的时候则不能添加成功。

5.建立防重表,可以专门建立一个表,防止重复,这个表里存储的数据只有id和唯一索引的属性组,当我们能够插入防重表时,再通过防重表插入数据库。

6.根据状态机这个就是订单生成的位置,通过订单状态来进行一个修改。如果我们第一次修改了状态之后,第二次就无法进行一个修改。

7.通过分布式锁,也就是有缓存的情况,通过setnx来对缓存中数据加锁

推荐阅读:https://juejin.cn/post/6944559294939398158open in new window

8.1 分页查询

MySQL的每个页的大小为16KB,每个页里面使用了数组进行二分查找,查找到目标ID所在的那一组,然后在组内遍历单链表进行查询。然后页(也就是B+树的节点)和页之间使用双向链表进行查询,但是我们的页太多时,则需要使用目录页来找到id所在页。

img
img

图片来自于:Yes的练级攻略

当我们增加数据时,如果使用自增id来实现的话,则会是追加操作,只需在后面开辟新的页即可,但是如果使用的不是自增ID则可能出现这种情况,就是页分裂,该页满了,将该页的某些数据挤到下一页,然后造成下一页也满了,这就有可能造成多个页分裂的情况,导致性能损耗。所以我们建议使用自增id作为主键。

8.2 如何分库分表

按照列进行划分,也就是属性,可以将表进行分割。

按照行id进行划分,取模等。