我们在开发的时候经常会听到这样的建议:1. 设计数据库表的时候,要为每个表设置一个主键;2. 主键最好是跟业务无关的; 3. 最好是自增的;
于是,很多新入行的程序猿们把这些前辈们的教条拿来就用,每个表的开头都会有个ID字段,并且在自增那里再打上个“勾勾”。OK,万事大吉,开始Coding。这个习惯有不少人甚至是保持了好多年,却从来没思考过对与不对,更不说为什么了。今天,我们来一起简单地分析一下原因,希望起到抛砖引玉的作用,引起大家进一步深入研究的兴趣。
主键主要作用:数据完整性;让相邻键值的数据紧凑地存放在一起;加快访问速度等。
为什么建议业务无关:避免因业务变更导致应用需要进行各种大量的修改,进而对系统的安全、稳定性进行冲击;
为什么一定自增:其实这才是本次分享里最想提的内容。自增保证了每一条新数据的值都是比当前最大值大的,所以新生成的记录会被写入数据页的末端。而末端的好处就是避免了各种复杂的寻址过程,也降低了索引分裂的成本。【可拓展阅读索引分裂相关内容】
在数据库服务中,一般情况下对每一行数据(准确的说是每一个数据块,实际上数据库从来都不是按行而是按页/数据块读取数据)的修改是从磁盘读到缓存(内存),在缓存中修改完成后又刷回磁盘的过程。(【数据库高速缓存—〉磁盘缓存—〉从磁盘读取】 从左到右成本逐步上升)
如果我们的主键是随机的,且有大有小,如果正好新生成的主键比当前最大值要小,数据库就需要先去高速缓存中查找是否已存在新数据需要写入的数据块,如果没有,则需要去磁盘上将该数据块读回缓存,导致增加了磁盘的随机IO(对于数据库性能来说降低磁盘IO非常重要);而频繁的数据页分裂,也导致数据变得不再紧凑,产生大量碎片。
看到这里,大家应该也可以看到。“自增型主键”其实不是一个结果,而是一个解决问题的方式而已,看到问题的本质,其实就算不用自增型,其他方式也一样可以达到同样的效果,不是吗?
凡事都是有利有弊,关键在于你该怎么去平衡、去取舍。那么自增型的主键又存在什么样的弊端呢?因为新数据都是写在末端,那么在高并发写入的情况下,将会产生“热点块”,对“热点块”的读写产生强烈的资源竞争。所以,同样会引起另外一个方面的性能问题。至于解决方法?其实也没有唯一的标准答案,大家都尝试一下吧(o^^o)

【Five-Minute Share】“为什么要选择自增型的主键”的更多相关文章

  1. MySql数据库查询表信息/列信息(列ID/列名/数据类型/长度/精度/是否可以为null/默认值/是否自增/是否是主键/列描述)

    查询表信息(表名/表描述): SELECT table_name name,TABLE_COMMENT value FROM INFORMATION_SCHEMA.TABLES WHERE table ...

  2. SqlServer数据库查询表信息/列信息(列ID/列名/数据类型/长度/精度/是否可以为null/默认值/是否自增/是否是主键/列描述)

    查询表信息(表名/表描述) Value ) AS value FROM sysobjects a Where a.xtype = 'U' AND a.name <> 'sysdiagram ...

  3. Oracle数据库查询表信息/列信息(列ID/列名/数据类型/长度/精度/是否可以为null/默认值/是否自增/是否是主键/列描述)

    查询表信息(表名/表描述) Select table_Name As Name,Comments As Value From User_Tab_Comments Where table_Type='T ...

  4. PostgreSql数据库查询表信息/列信息(列ID/列名/数据类型/长度/精度/是否可以为null/默认值/是否自增/是否是主键/列描述)

    查询表信息(表名/表描述) select a.relname as name , b.description as value from pg_class a ) b on a.oid = b.obj ...

  5. (转)mysql自增列导致主键重复问题分析

    mysql自增列导致主键重复问题分析...  原文:http://www.cnblogs.com/cchust/p/3914935.html 前几天开发童鞋反馈一个利用load data infile ...

  6. mysql自增列导致主键重复问题分析。。。

    前几天开发童鞋反馈一个利用load data infile命令导入数据主键冲突的问题,分析后确定这个问题可能是mysql的一个bug,这里提出来给大家分享下.以免以后有童鞋遇到类似问题百思不得其解,难 ...

  7. 获取mybatis注解方式新增数据时非自增插入的主键

    场景:插入数据的时候,获取不到非自增的主键.原因:对象中没有主键的值,插入后主键才有值. 解决方案:使用 @SelectKey @SelectKey中: statement是要运行的SQL语句,即查询 ...

  8. mybatis oracle 插入自增记录 获取主键值 写回map参数

    网上搜了好多文章照着弄都返回不了主键给map, 实践证明要在传入的map参数里写回插入的主键,要这样写 <selectKey resultType="java.lang.Integer ...

  9. mybatis+sqlserver中返回非自增主键

    首先把实体类贴出来(这里只贴出属性,其它的就是getter和setter方法): public class Around {     private String xccd;  //对应主键      ...

随机推荐

  1. hadoop中的job.setOutputKeyClass与job.setMapOutputKeyClass

    初学mr时,觉得没什么,但是学了一段时间,重新复习时发现程序中mr程序中一般都会有 hadoop中的job.setOutputKeyClass(theClass)与job.setOutputValue ...

  2. 国庆day2

    a[问题描述]你是能看到第一题的 friends呢.—— hja世界上没有什么比卖的这 贵弹丸三还令人绝望事了,所以便么一道题.定义

  3. centos7系统修改内核

    修改centos6的内核启动顺序,只需要修改/etc/grub.conf 里的default项配置即可.那么centos7系统该如何修改呢? 下面就centos7系统修改内核,做如下记录: 一般在编译 ...

  4. Deepin & ROMS 安装详细流程

    按照这个过程,完美安装,当然并不能排除会出现其他的问题.如果遇到了,那就老老实实上网搜吧.

  5. tp5 前置方法

    Route::any('adminapi/v1/login','adminapi/v1.login/login');Route::any('adminapi/v1/first','adminapi/v ...

  6. Codeforces 947E Perpetual Subtraction (线性代数、矩阵对角化、DP)

    手动博客搬家: 本文发表于20181212 09:37:21, 原地址https://blog.csdn.net/suncongbo/article/details/84962727 呜啊怎么又是数学 ...

  7. [置顶] Java Web学习总结(24)——SSM(Spring+SpringMVC+MyBatis)框架快速整合入门教程

    1.基本概念 1.1.Spring Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One  ...

  8. setTimeout(fn,0)的作用分析

    众所周知,大家对setTimeout的用法肯定都比较熟悉了,但是不是还是会经常忘记使用呢,例如博主阿里面试时就忘了,见阿里前端面试. 今天跟大家讨论一下setTimeout(fn,0)的用法,相信很多 ...

  9. css sprites拼合

    一.什么是css sprites css sprites直译过来就是CSS精灵.通常被解释为“CSS图像拼合”或“CSS贴图定位”.就是把网页中一些背景图片整合拼合成一张图片中,再利用DIV CSS的 ...

  10. Docker--微软dotconf截图