自增主键的弊端 我个人觉得缺少弹性当你有 1-10个ID 你删除了9个 只剩下1 再添加一次就是 11 而不是2或者你有1-10个ID 你删除了8个 只剩下1和10 当你的最大ID仅仅到10的时候,你可以用一些算法来调整插入空缺ID自增主键都是做不到的时间越长ID变多,这些隐藏的问题暴露出来后,将变得越难以控制 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 个人感觉,用自增ID是为了方便设主键,以满足第二范式的要求.插入记录也方便. 而且int型做为索引速度也快. id跟翻页没有关系.如果你表有一个int型可做主键,没完没有必要用自增ID. int32最大可达20多亿, 就算经常删增也很少会达到最大的. 如果设计初能预见记录多太多,可用bigint. 2的63次方. 足够了.我觉得用自增还是很不错的. 当然也有人建议用newId(), 仁人见仁. 这个不是主键的问题而是你设计的问题...主键应该是无意义的与业务无关...也就是说主键不必是顺序的甚至不必是有规律的...自增主键的弊端主要是主外键关系表的并发性能问题和分布式系统的唯一性问题...另外就是数字类型的溢出问题...大型系统或分布式系统一般采用GUID作为主键... 自增主键的弊端主要是主外键关系表的并发性能问题和分布式系统的唯一性问题==================非常希望virusplayer 能给稍微详细解析下这句话包含的内容,洗耳恭听! 本公司的数据库表用的是自增主键,用的是SQL SERVER,短期是没什么问题(3-4年了最多的表记录有20多万条).不过就在出报表的时候表连接很多,速度慢.大型数据库ORACLE一般不会用自增的主键. 这根本就不是弊端,而是你的需求不同罢了.有的人就正好有这样的需求,即使删除后,再插入一条一模一样的记录,也能因为这个值的不同而区分开.那这不成了利端?Int型可以达到二十多亿,一张表里短期是很少会达到这个数量级的. 不过就在出报表的时候表连接很多,速度慢. 大型数据库ORACLE一般不会用自增的主键.=====================================据我的了解,相信出报表慢和是否自增没有关系,而且你也说了,是“表连接很多”,表连接的多和自增更没关系了ORACLE里印象里也没有自增的主键,而是用nextval来产生一个键值 没感觉有弊端,像RoR还强制要求每一个表必须有一个自增id呢 个人觉的自增id存在不连续性,如当你有 1-10个ID 你删除了9 只剩下1 再添加一次就是 11 而不是2 那么显示出来数据如下: 1 ... 11 ... 这样不如这样的数据条理化: 1 ...... 2...... 没有弊端,自增int型主键用作排序,检索起来也很块!不要被别人误导了,根据项目需求来! 个人觉的自增id存在不连续性,如当你有 1-10个ID 你删除了9 只剩下1 再添加一次就是 11 而不是2 那么显示出来数据如下: 1 ... 11 ... 这样不如这样的数据条理化: 1 ...... 2......========================================从你的视角回复你:从五月一日到10日每天写一条记录,序号分别内是1-1011号这天删除2号的,再写入一条记录,它的ID=2于是你在界面上看到的数据是:标题一 2008.05.01标题xx 2008.05.11标题三 2008.05.03不知这是否是你要的效果另外为了保持“见缝插针”,我想你每insert一次就得把数据全部读出然后从前往后循环寻找第一个空缺,是不是? 没有弊端,自增int型主键用作排序,检索起来也很块!不要被别人误导了,根据项目需求来!===============================================================TO : ludeli2004 我所想知道的,正是在什么需求下需要"非自增" 数据迁移时,问题非常大======================tnt1980兄弟给举个例子吧,我以前面试时,考官提出的反对意见印象里不是迁移句是备份,可惜当时没求教,你给说说吧 这个例子没有说服里假设有个城市表1000条记录,删除第100条的“上海”,然后又增加了“泉州”,把泉州经过计算写成100比自动写为1001必要在什么地方呢?至于IP表,一样想象不出有什么样的需求要要保持ID连续“根据你的需求来”——我真是想不出在什么时候才会出现这样的需求,所以才问的 排序的时候貌似会乱如1~10的记录读出来就是:1,10,2,3,4...,9 了(GridView) 这里有个含糊的概念:需求上要考虑“极端的情况”的情况,但咱们的讨论在系统设计的范畴,设计无从谈起“极端的情况”,设计满足需求就是好设计。举个你可能认可的例子:数据库中的字段是byte型,你的系统对应的某个变量一定要搞成long型,因为这样可以最大程度的满足某种想象不出的”极端的情况“,不太合适吧?大家是在讨论具体的问题,“某些时候”、“随便一个”的泛泛而谈对大家都是浪费时间 系统设计的范畴?按你的思路,那也无从谈起“弊端”。因为“弊端”是在系统最后运行起来后才发现的(至于设计之前就知道,那是因为有了前人在多次“系统最后运行”多次后的经验总结)设计是为了运行,所以设计阶段是要“根据经验来考虑各种极端情况”,如:溢出怎么办?我想显示ID,用N位宽高位不足用0补,怎么办?……设计脱离不了需求。这类问题在楼上们的回答中有些都给出具体不足的情况了,还要怎么具体?A问:筷子有几种用途?B:答,吃饭,剔牙,起啤酒瓶盖,沾水写字画画…… ,你要这样的具体?PS:你举的例子我没理解。1.我不会搞成long型。2.看不懂后面“因为”相关描述,这和搞成long型根本不搭边。 自增主键...缺点1.在插入数据时无法确定主键的值,除非使用事务否则,通过其它方法获得,无法保证获得的值就是刚插入数据的主键,因为在插入数据库前无法获得主键导致后续代码编写困难.2.自增值在使用事务回滚,以及在插入失败的情况下,其值不会回滚,当使用此值作为条目的连续编号时回发生编号不连续的问题.3.在合并数据库表时,因为都是从1开始编号造成数据合并困难,特别对于一些可以离线的操作的系统,自动编号只是累赘..因以上几点我的数据库的主键已全部改为GUID. 求助 Dephi 5调用 C# DLL 编译器错误:Type 'Byte' is not yet completely defined 求事件的例子 webBrowser获取post数据问题 C#判断WORD的range 关于Progressbar控件,看看这段代码 【求助】软件安装过程中如何自动卸载以前的版本?急,有高分!谢谢! 【思归等大哥请进】 如何处理文件名里的空格键? c# vs 2005 文件下载 请问数据库的连接效率 我们公司现在用的数据访问类,觉得有挺多欠缺,请高手给指点指点。 C#中.XSD是什么文件 100分高分请教关于如何设置DataGridView的列自适应大小!
如果你表有一个int型可做主键,没完没有必要用自增ID.
我觉得用自增还是很不错的. 当然也有人建议用newId(), 仁人见仁.
==================
非常希望virusplayer 能给稍微详细解析下这句话包含的内容,洗耳恭听!
不过就在出报表的时候表连接很多,速度慢.
大型数据库ORACLE一般不会用自增的主键.
这根本就不是弊端,而是你的需求不同罢了.
有的人就正好有这样的需求,即使删除后,再插入一条一模一样的记录,也能因为这个值的不同而区分开.那这不成了利端?
Int型可以达到二十多亿,一张表里短期是很少会达到这个数量级的.
大型数据库ORACLE一般不会用自增的主键.
=====================================
据我的了解,相信出报表慢和是否自增没有关系,而且你也说了,是“表连接很多”,表连接的多和自增更没关系了
ORACLE里印象里也没有自增的主键,而是用nextval来产生一个键值
那么显示出来数据如下: 1 ...
11 ...
这样不如这样的数据条理化: 1 ......
2......
那么显示出来数据如下: 1 ...
11 ...
这样不如这样的数据条理化: 1 ......
2......
========================================
从你的视角回复你:
从五月一日到10日每天写一条记录,序号分别内是1-10
11号这天删除2号的,再写入一条记录,它的ID=2
于是你在界面上看到的数据是:
标题一 2008.05.01
标题xx 2008.05.11
标题三 2008.05.03
不知这是否是你要的效果另外为了保持“见缝插针”,我想你每insert一次就得把数据全部读出然后从前往后循环寻找第一个空缺,是不是?
===============================================================
TO : ludeli2004
我所想知道的,正是在什么需求下需要"非自增"
======================
tnt1980兄弟给举个例子吧,我以前面试时,考官提出的反对意见印象里不是迁移句是备份,可惜当时没求教,你给说说吧
这个例子没有说服里
假设有个城市表1000条记录,删除第100条的“上海”,然后又增加了“泉州”,把泉州经过计算写成100比自动写为1001必要在什么地方呢?
至于IP表,一样想象不出有什么样的需求要要保持ID连续“根据你的需求来”——我真是想不出在什么时候才会出现这样的需求,所以才问的
如1~10的记录
读出来就是:1,10,2,3,4...,9 了(GridView)
这里有个含糊的概念:
需求上要考虑“极端的情况”的情况,但咱们的讨论在系统设计的范畴,设计无从谈起“极端的情况”,设计满足需求就是好设计。举个你可能认可的例子:数据库中的字段是byte型,你的系统对应的某个变量一定要搞成long型,因为这样可以最大程度的满足某种想象不出的”极端的情况“,不太合适吧?大家是在讨论具体的问题,“某些时候”、“随便一个”的泛泛而谈对大家都是浪费时间
按你的思路,那也无从谈起“弊端”。因为“弊端”是在系统最后运行起来后才发现的
(至于设计之前就知道,那是因为有了前人在多次“系统最后运行”多次后的经验总结)设计是为了运行,所以设计阶段是要“根据经验来考虑各种极端情况”,如:溢出怎么办?我想显示ID,用N位宽高位不足用0补,怎么办?……
设计脱离不了需求。这类问题在楼上们的回答中有些都给出具体不足的情况了,还要怎么具体?
A问:筷子有几种用途?B:答,吃饭,剔牙,起啤酒瓶盖,沾水写字画画…… ,你要这样的具体?
PS:你举的例子我没理解。1.我不会搞成long型。2.看不懂后面“因为”相关描述,这和搞成long型根本不搭边。
1.在插入数据时无法确定主键的值,除非使用事务否则,通过其它方法获得,无法保证获得的值就是刚插入数据的主键,因为在插入数据库前无法获得主键导致后续代码编写困难.
2.自增值在使用事务回滚,以及在插入失败的情况下,其值不会回滚,当使用此值作为条目的连续编号时回发生编号不连续的问题.
3.在合并数据库表时,因为都是从1开始编号造成数据合并困难,特别对于一些可以离线的操作的系统,自动编号只是累赘..因以上几点我的数据库的主键已全部改为GUID.