我们在开发的时候经常会听到这样的建议: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. Django—链接MySQL

    Djalgo基础配置方法 静态文件配置方法 1 所有的静态文件都放在 static 文件夹下,例如Bootstrap值类的第三方库,通常 static 文件下会创建 css image js 文件,用 ...

  2. LINUX KERNEL SPINLOCK使用不当的后果

    LINUX KERNEL SPINLOCK使用不当的后果 spinlock(自旋锁)是内核中最常见的锁,它的特点是:等待锁的过程中不休眠,而是占着CPU空转,优点是避免了上下文切换的开销,缺点是该CP ...

  3. Git 基础教程 之 Bug分支和Stash

    在Git中,每个Bug都可以通过一个新的临时分支修复,修复后,合并分支,然后删除. ①    当接到一个Bug任务时,但dev上进行的工作还没有提交时: ②    git stash 把现场工作“储藏 ...

  4. CentOS 7 x64下Apache+MySQL(Mariadb)+PHP5.6的安装

    每次搭建新服务器,都要来来回回把这些包再装一下,来来回回搞了不下20遍了吧,原来都是凭经验,配置过程中重复入坑是难免的,故写此文做个备忘.虽然有像xampp这样的集成包,但是在生产环境的Linux发行 ...

  5. lca学习题

    http://www.cnblogs.com/scau20110726/archive/2013/06/14/3135095.html

  6. 0419MySQL ORDER BY的实现分析

    转自:http://www.2cto.com/database/201202/120001.html 简朝阳 总的来说,在 MySQL 中的ORDER BY有两种排序实现方式,一种是利用有序索引获取有 ...

  7. Wireshark中的一些SNMP相关的过滤器

    Wireshark中的一些SNMP相关的过滤器 转自 http://linmingren2003.blog.163.com/blog/static/567510032011419825097/   由 ...

  8. cogs 10. 信号无错传输

    10. 信号无错传输 ★★☆   输入文件:dlj.in   输出文件:dlj.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 为提高传递信息的保密性和可靠性,两个军事 ...

  9. Extensions for Spatial Data

    http://dev.mysql.com/worklog/task/?spm=5176.100239.blogcont4270.8.j3asa7&id=6609 前文: 这两天因为项目原因看了 ...

  10. 5.2 calendar--通用日期的相关函数(4)

    calendar类提供以下的函数来推断日历相关的内容: calendar.setfirstweekday(weekday) 设置一周里那一天作为第一天.0是表示星期一,6是表示星期天. 样例: #py ...