问题:mysql聚簇索引,覆盖索引,底层结构,主键索引,没有主键怎么办,会自己生成主键为什么还要自定义主键,自动生成的主键有什么问题
Q1:mysql聚簇索引,覆盖索引,底层结构
聚簇索引(主键索引):索引下对应整行的值
非主键索引:索引下对应主键的值
查询过程:非主键索引查询时找到对应的主键后,再带着主键去主键索引查找对应的行数据,这一过程也称为回表
避免回表(覆盖索引):即非主键索引查询到的值就是需要的返回值,则不需要再回表,这就是所谓的覆盖索引
- 前提知识:当一张表将某个列设为主键的时候,则该列就是主键索引
Q2:主键索引,没有主键怎么办,会自己生成主键为什么还要自定义主键?
1、如果定义了主键,定义的主键会作为主键索引
2、如果没有定义主键,会使用第一排非空的唯一索引作为主键索引
3、如果以上两点均不满足:那么InnoDB会自动生成一个不可见的名为row_id的列名为GEN_CLUST_INDEX的聚簇索引,该列是一个6字节的自增数值,随着插入而自增--补充:该全局row_id在代码实现上使用的是bigint unsigned类型,但实际上只给row_id留了6字节。
这种设计就会存在一个问题:如果全局row_id一直涨,一直涨,直到2的48幂次-1时,这个时候再+1,row_id的低48位都为0,结果在插入新一行数据时,拿到的row_id就为0,存在主键冲突的可能性。
Q3:自动生成的主键有什么问题?
- 使用不了主键索引,查询会进行全表扫描
- 影响数据插入性能,插入数据需要生成ROW_ID,而生成的ROW_ID是全局共享的(InnoDB 维护了一个全局的 dictsys.row_id,所有未定义主键的表都共享该row_id),并发会导致锁竞争,影响性能