【Five-Minute Share】“为什么要选择自增型的主键”
我们在开发的时候经常会听到这样的建议:1. 设计数据库表的时候,要为每个表设置一个主键;2. 主键最好是跟业务无关的; 3. 最好是自增的;
于是,很多新入行的程序猿们把这些前辈们的教条拿来就用,每个表的开头都会有个ID字段,并且在自增那里再打上个“勾勾”。OK,万事大吉,开始Coding。这个习惯有不少人甚至是保持了好多年,却从来没思考过对与不对,更不说为什么了。今天,我们来一起简单地分析一下原因,希望起到抛砖引玉的作用,引起大家进一步深入研究的兴趣。
主键主要作用:数据完整性;让相邻键值的数据紧凑地存放在一起;加快访问速度等。
为什么建议业务无关:避免因业务变更导致应用需要进行各种大量的修改,进而对系统的安全、稳定性进行冲击;
为什么一定自增:其实这才是本次分享里最想提的内容。自增保证了每一条新数据的值都是比当前最大值大的,所以新生成的记录会被写入数据页的末端。而末端的好处就是避免了各种复杂的寻址过程,也降低了索引分裂的成本。【可拓展阅读索引分裂相关内容】
在数据库服务中,一般情况下对每一行数据(准确的说是每一个数据块,实际上数据库从来都不是按行而是按页/数据块读取数据)的修改是从磁盘读到缓存(内存),在缓存中修改完成后又刷回磁盘的过程。(【数据库高速缓存—〉磁盘缓存—〉从磁盘读取】 从左到右成本逐步上升)
如果我们的主键是随机的,且有大有小,如果正好新生成的主键比当前最大值要小,数据库就需要先去高速缓存中查找是否已存在新数据需要写入的数据块,如果没有,则需要去磁盘上将该数据块读回缓存,导致增加了磁盘的随机IO(对于数据库性能来说降低磁盘IO非常重要);而频繁的数据页分裂,也导致数据变得不再紧凑,产生大量碎片。
看到这里,大家应该也可以看到。“自增型主键”其实不是一个结果,而是一个解决问题的方式而已,看到问题的本质,其实就算不用自增型,其他方式也一样可以达到同样的效果,不是吗?
凡事都是有利有弊,关键在于你该怎么去平衡、去取舍。那么自增型的主键又存在什么样的弊端呢?因为新数据都是写在末端,那么在高并发写入的情况下,将会产生“热点块”,对“热点块”的读写产生强烈的资源竞争。所以,同样会引起另外一个方面的性能问题。至于解决方法?其实也没有唯一的标准答案,大家都尝试一下吧(o^^o)
【Five-Minute Share】“为什么要选择自增型的主键”的更多相关文章
- MySql数据库查询表信息/列信息(列ID/列名/数据类型/长度/精度/是否可以为null/默认值/是否自增/是否是主键/列描述)
查询表信息(表名/表描述): SELECT table_name name,TABLE_COMMENT value FROM INFORMATION_SCHEMA.TABLES WHERE table ...
- SqlServer数据库查询表信息/列信息(列ID/列名/数据类型/长度/精度/是否可以为null/默认值/是否自增/是否是主键/列描述)
查询表信息(表名/表描述) Value ) AS value FROM sysobjects a Where a.xtype = 'U' AND a.name <> 'sysdiagram ...
- Oracle数据库查询表信息/列信息(列ID/列名/数据类型/长度/精度/是否可以为null/默认值/是否自增/是否是主键/列描述)
查询表信息(表名/表描述) Select table_Name As Name,Comments As Value From User_Tab_Comments Where table_Type='T ...
- PostgreSql数据库查询表信息/列信息(列ID/列名/数据类型/长度/精度/是否可以为null/默认值/是否自增/是否是主键/列描述)
查询表信息(表名/表描述) select a.relname as name , b.description as value from pg_class a ) b on a.oid = b.obj ...
- (转)mysql自增列导致主键重复问题分析
mysql自增列导致主键重复问题分析... 原文:http://www.cnblogs.com/cchust/p/3914935.html 前几天开发童鞋反馈一个利用load data infile ...
- mysql自增列导致主键重复问题分析。。。
前几天开发童鞋反馈一个利用load data infile命令导入数据主键冲突的问题,分析后确定这个问题可能是mysql的一个bug,这里提出来给大家分享下.以免以后有童鞋遇到类似问题百思不得其解,难 ...
- 获取mybatis注解方式新增数据时非自增插入的主键
场景:插入数据的时候,获取不到非自增的主键.原因:对象中没有主键的值,插入后主键才有值. 解决方案:使用 @SelectKey @SelectKey中: statement是要运行的SQL语句,即查询 ...
- mybatis oracle 插入自增记录 获取主键值 写回map参数
网上搜了好多文章照着弄都返回不了主键给map, 实践证明要在传入的map参数里写回插入的主键,要这样写 <selectKey resultType="java.lang.Integer ...
- mybatis+sqlserver中返回非自增主键
首先把实体类贴出来(这里只贴出属性,其它的就是getter和setter方法): public class Around { private String xccd; //对应主键 ...
随机推荐
- 雪花算法生成全局唯一ID
系统中某些场景少不了全局唯一ID的使用,来保证数据的唯一性.除了通过数据库自带的自增id来保证 id 的唯一性,通常为了保证的数据的可移植性会选择通过程序生成全局唯一 id.百度了不少php相关的生成 ...
- 【剑指Offer】6、旋转数组的最小数字
题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5 ...
- 多种方法爬取猫眼电影Top100排行榜,保存到csv文件,下载封面图
参考链接: https://blog.csdn.net/BF02jgtRS00XKtCx/article/details/83663400 https://www.makcyun.top/web_sc ...
- 3.在eclipse中创建Web项目,并部署到Tomcat上
1.找到创建web项目的菜单 2.创建web项目并选择web环境 3.查看创建好的web项目结构 4.在web项目的webContent文件夹下创建jsp页面 5.查看是否创建jsp页面成功,并编辑j ...
- 在win7下,easyphp安装过程中MSVCR110.DLL没有被指定在WINDOWS上运行,或者它包含错误
这是安装easyphp后启动时出现的错误界面.查网上一大堆说法,基本上p用没有.真正解决的办法去m$站点 http://www.microsoft.com/zh-CN/download/details ...
- POJ 1474
半平面交模板 #include <iostream> #include <cstdio> #include <cstring> #include <algor ...
- 4443: [Scoi2015]小秃玩矩阵|二分答案|匈牙利
第K大看成第K小各种WA. .. 第K大也就是第n−K+1小.所以就能够愉快的二分答案了 二分答案找出比当前答案小的数的位置的坐标.推断一下能否够选出满足不在同一行同一列的n−K+1个数,然后就能够愉 ...
- C#之打印乘法表
设计说明 由图可知: 1.我们需要打印出九行: 2.每行中最大列数等于行数: 代码实现 public void Display1() { Console.WriteLine("乘法表:&qu ...
- HDU 5063 Operation the Sequence(暴力)
HDU 5063 Operation the Sequence 题目链接 把操作存下来.因为仅仅有50个操作,所以每次把操作逆回去执行一遍,就能求出在原来的数列中的位置.输出就可以 代码: #incl ...
- oracle 数据库中数据导出到excel
确保安装了PLSQL Developer工具.连接数据库. FIle--new--SQL window 运行查询,选中要导出的数据,右键--copy to excel. 或者 运行查询后.右键--se ...