【面试题集】数据库主键常用方式?为什么用自增列作为主键?

品茗IT-面试题集-首发

如果大家正在寻找一个java的学习环境,或者在开发中遇到困难,可以加入我们的java学习圈,点击即可加入,共同学习,节约学习时间,减少很多在学习中遇到的难题。

常用主键生成方式

  1. Mysql自增长主键策略
    这种简单,不需要程序特别处理 ,但是这种方法对项目移植到其它数据库上改动会比较大,oracle、db2采用Sequence,Mysql、sqlServer又采用自增长,通用性不好 。
  2. 使用时间戳相关生成策略
    这种实现简单,与数据库无关,移植性较好 ,但长度太长,最少也得20位;
    比如雪花算法,可以生成20位有序的的ID。
  3. UUID、GUID
    这种方式简单,代码方便,全球唯一,与数据库无关,移植性较好,但没有排序,无法保证趋势递增。UUID往往是使用字符串存储,查询的效率比较低。
  4. 每次取主键最大值+1做为新的主键
    这种主键长度可控,移植性较好 ,但并发写可能会造成主键冲突,对并发也不太好控制
  5. 单独建一个存放主键的表
    这种实现简单,移植性较好 ,需要考虑并发问题,整个系统主键生成都依赖该表,性能影响可能较大

默认主键

  1. 如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引;

  2. 如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引;

  3. 如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID作为隐含的聚集索引(ROWID随着行记录的写入而主键递增,这个ROWID不像ORACLE的ROWID那样可引用,是隐含的)。

自增的好处

  1. 数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点);

  2. 如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页;

  3. 如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。

扩展

主键尽量采用自增方式,InnoDB 表实际是一棵索引组织表,顺序存储可以提高存取效率,充分利用磁盘空间。
还有对一些复杂查询可能需要自连接来优化时需要用到。

如果没有主键或唯一索引,update/delete 是通过所有字段来定位操作的行,相当于每行就是一次全表扫描。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • InnoDB体系架构 上图简单显示了InnoDB存储引擎的体系架构图中可见,InnoDB存储引擎有多个内存块,可以...
    Rick617阅读 4,066评论 0 6
  • 这篇文章主要涉及到MySQL的知识点: 索引(包括分类及优化方式,失效条件,底层结构) sql语法(join,un...
    一根薯条阅读 2,750评论 0 8
  • 以前 特别喜欢跟一大群人一起玩耍 即使上厕所也要拉个人作伴 可惜 现在的我喜欢一个人 以前 我怕独处的尴尬 特别是...
    拜星月慢阅读 439评论 0 3
  • 昨天听完了如尘个人品牌打造课程的复盘,感触很多,为什么有的人说改变就能改变,说行动就能行动,而有的人天天在说自己要...
    竹溪Sophie阅读 288评论 0 0
  • 一个男生他每天都莫名很惆怅,他喜欢观察,甚至到一只蜘蛛都能看一天,总是静静的看着身边的一切,即使很小的细节都会留意...
    菱之舞阅读 208评论 0 0