这个问题不能一概而论:
(1)如果是InnoDB存储引擎,主键不能太长;
(2)如果是MyISAM存储引擎,影响不大;
我们举一个简单的栗子来解释序言知识。
假设有一个数据表:
t(id主键,姓名键,性别,标志);
其中包括:
(1)id是主键;
(2)名称已建立通用索引;
假设表中有四条记录:
1、沈剑,文学硕士
3、张三,m,A
5、李思,文学硕士,文学硕士
9,吴王,f,B
如果存储引擎是MyISAM,则其索引和记录结构如下:
(1)有单独的区域存储记录(备案);
(2)主键索引与普通索引结构差不多,都存储记录的指针(暂且理解为指针);
画外音:
(1)主键索引不与记录存储在一起,因此它是一个非聚集索引;
(2)MyISAM可以不PK;
MyISAM使用index进行搜索时,会先从索引树中定位记录指针,然后通过记录指针定位具体的记录。
画外音:不管主键索引,也是普通索引,流程是一样的。
InnoDB不一样。其索引和记录结构如下:
(1)主键索引与记录一起存储;
(2)普通索引存储主键(现在不是指针);
画外音:
(1)主键索引是和记录一起存储的,所以叫聚集索引;
(2)InnoDB必须有聚集索引;
InnoDB可以在通过主键索引查询时直接定位行记录。
但是,如果通过公共索引进行查询,将首先查询主键,然后从主键索引开始遍历索引树两次。
回到正题,InnoDB的主键为什么不能太长?
假设有一个以用户为中心的场景,这个场景包含了身份证号、ID MD5、姓名、出生日期等业务属性。,都有查询需求。
思考设计最简单的方法是:
身份证作为主键其他属性上建立索引
用户(id_code主键,
id_md5(索引),
名称(索引),
生日(指数));
此时,索引树和行记录结构如下:
id_code聚集索引,关联行记录其他索引,存储id_code属性值
Id_code是一个相对较长的字符串,每个索引都存储这个值。MySQL数据量大,内存珍贵,缓冲区有限,所以存储的索引和数据会减少,磁盘IO的概率会增加。
画外音:同时索引占用的磁盘空也会增加。
此时,应该添加一个没有业务意义的id自添加列:
以id自增列为聚集索引,关联行记录其他索引,存储id值
用户(id PK汽车公司,
id_code(索引),
id_md5(索引),
名称(索引),
生日(指数));
因此,有限的缓冲区可以缓冲很多的索引和行数据,磁盘IO的频率将会降低,整体性能将会提高。
摘要
(1)MyISAM的索引与数据分开存储,索引留下存储指针。主键索引和普通索引差别不大;
(2)InnoDB的聚集索引和数据行统一存储,聚集索引存储数据行本身,普通索引存储主键;
(3)InnoDB不建议用太长的字段做PK(此时可以加一个自增键PK),但是MyISAM不在乎;
–
从微信到微信官方账号架构师