自增主键与UUID
自增主键
设计表时,将id字段的值设置为自增的形式,当插入一行数据时,无需指定id会自动根据前一字段的ID值+1 进行填充,mysql中可通过auto-increment来实现。
- 字段长度小于uuid,可以是bigint甚至int类型,使用innodb引擎时,根据索引找到主键,再找记录,读性能会好
- 数据库自动编号,速度快,增量增长,按顺序存放,对检索有利
- 数字型,占用空间小,易排序,在程序中传递也比较方便
- 增加记录时可以不指定id字段,不用担心主键重复问题
自增主键存在的问题
- 高并发情况下,竞争自增锁会降低数据库吞吐能力
- 不具备连续性,最大值被删除,将不会重用,造成跳号
- 对于分布式存储的数据表不友好,尤其需要合并表情况时
UUID
- 在一台机器上生成的数字,保证对同一时空中所有的机器都是唯一的,在一定范围内保证主键id的唯一性
- 不会产生冲突,进行数据拆分,合并存储时,可以达到全局唯一性
- 在应用层生成,提高数据库吞吐能力
- 安全性高
UUID存在的问题
- 影响插入速度,硬盘使用率低,innodb数据是按照主键顺序存放的
- uuid之间比较大小,比数字慢不少
- uuid占用空间大
- 读取出的数据是无序的
MySQL 官方不建议使用UUID与不连续不重复的雪花ID
- 使用自增id的索引内部结构 自增的主键是顺序的,Innodb将每一条记录都存储在一条记录后面,当达到页面的最大填充因子(15/16预留1/16做修改),下一条记录就会写入新的页中,按照这种方式加载,主键页就会近乎于顺序的记录填满,提升了页面的最大填充率,新插入的数据一定会有在原有的最大数据的下一行,MySQL定位和寻址很快,减少页分裂与碎片产生
- 使用uuid索引的内部结构 innodb无法将新行插入到索引的后面,写入是乱序的,innodb不得不频繁做页分裂操作,为新行分配空间,页分裂导致大量数据移动,页会变得稀疏并被不规则填充,会导致页有碎片,将随机值载入聚族索引以后,会需要做一次optimeize table来重建表并优化页的填充,需要一定的时间消耗
- 可在逻辑上使用uuid,物理上使用自增id