事实上在这之前我一直觉得,设计表结构的时候,只要挑选其中一个不会有重复值且非空的字段作为主键就可以了,在看到某些表结构中,虽然已经有符合主键特性的字段了,但依旧会特地去加一个id字段作为主键(当时觉得这纯属是多余),这样的设计有它的道理。
1. 主键字段应尽可能的短
首先需要了解一下什么是主索引(一级索引)和辅助索引(二级索引)。
在MyISAM中,使用的是非聚簇索引,使用B+Tree数据结构。
BTree: 所有key:value分布在整个树中。
B+Tree: 所有key:value分布在叶子结点中,非叶子结点只有key用作路由,叶子节点之间通过指针连接。
故MyISAM的一级索引叶子节点的value是数据表行指针,二级索引也是如此,区别在于二级索引允许key值重复。
在InnoDB中,使用的是聚簇索引,同样使用B+Tree数据结构。
故InnoDB的数据和索引是一体的,一级索引的叶子结点的value即数据,而二级索引的叶子结点的value是一级索引上的key,同样的InnoDB的二级索引上的key是允许重复的。
二级索引一般就是非主键字段的索引。故而通过二级key检索数据需要扫描两边索引:①二级索引获取key;②一级索引获取数据。
但并不是所有非主键索引都会回表查询,覆盖索引就是一个例外。
看到这里应该理解了,如果主键的字段很长,那么会导致所有的二级索引过大,因此设计主键时应尽量让其更短。
2. 主键字段应尽可能单调
这一点依旧和索引有关,B+Tree本质上是一颗多路搜索树,非单调的主键在插入一条记录时,为了维持B+Tree的特性会导致频繁的分裂调整。
这时候使用自增字段作为主键就能够巧妙地解决这个问题,就类似于在一个有序的数组中插入元素一样,每一次插入的元素都是数组中最大的元素,避免了大量元素的移动。