1.事故描述
1.1 业务需求
主表保存个人基本信息,子表保存受伤情况记录
1.2 事故描述
需要保存用户两次受伤情况,受伤描述分别为“事故描述1”、“事故描述2”,查询结果为:”事故描述2“、”事故描述1“,与期望结果相反
数据库记录如下
1.3 事故分析
页面查询结果采用默认排序方式,InnoDB使用默认排序方式查询数据时,默认会根据主键排序,由于主键使用UUID,导致数据库不会按照插入的顺序进行排序,导致查询出的数据不满足期望要求。
1.4 解决方案
- 为数据库表增加字段用于查询时排序,保证按照插入顺序进行排序
- 使用自增ID代替UUID
- 修改数据库表引擎为MyISAM(MyISAM默认按照插入顺序排序)
2.MySQL为什么不推荐使用UUID或雪花id作为主键
2.1MySQL索引的数据结构
InnoDB存储引擎下使用B+树的数据结构,每个节点不保存数据,只用来索引,所有数据都保存在叶子节点上。所以每个表都会创建一个主键索引,不管是否指定了主键,B+树节点上保存的是主键索引,并且必定是有序的。
2.2 数据操作步骤分析
由于B+树存储的数据是有序的,当有新的数据插入时,如果数据是有序的(自增ID),那么数据将直接插入到到末尾处;如果数据是无序的(UUID/雪花id等随机生成的id),为了保证数据的有序性,那么数据将有可能插入到已有的数据中间,后面的数据将依次往后移位。
MySQL中存储数据的最小单元是page(页),大小为16KB,也就是说一个page可以存储多个数据。我们分析这样一种情况,当page1已经存满,page存了部分数据时需要插入一条数据,如果此时使用的自增ID,即数据是有序的,那么数据将直接插入到末尾,如果数据是无序的呢?
显然,为了保证数据有序性,数据有可能被插入到page1中,但此时page1已经满了,那么插入数据后面的数据都必须往后移动,存不下的数据只有移动到page2,此时就发生了page的分裂与合并,会大大影响数据的插入和删除,这也就是为什么MySQL不推荐使用UUID或雪花id这类随机id的原因。