当前位置:编程学习 > C#/ASP.NET >>

主键用GUID好还是INT好

由于有服务端,用什么数据类型的主键都方便

GUID加上时间信息来编码也可以排序 INT加上编码区段也可以多数据中心数据合并

GUID使用方便一点,特别合并数据等,就是可能客户感到不爽,我以前刚看到别人软件用GUID主键也不爽 

用哪一种数据类型的主键好,各位请指点一下 --------------------编程问答-------------------- 某人做过的一个测试。http://blog.csdn.net/fox123871/article/details/6578922 --------------------编程问答-------------------- 你怎样保证int编码不重复的呢?特别是多会话并发(例如asp.net下就可能有100个数据库会话同时并发)的情况。

如果根本不能很好地解决这个问题,那么就算弄顺序地弄100w个键值做测试,这种测试也是错误的。是一个错误的前提下做出的测试。 --------------------编程问答-------------------- 看你从什么角度说“好”。

以前回答过一个人的问题,while好还是for循环好,最后他自己总结道,看来还是while循环好,因为可以少写几个字符,真是晕死。举这个例子就是告诉你,实际上你看问题的高度决定了你看问题的观点。表面上你似乎希望别人告诉你什么,其实只是你自己在罗织一种偏见(偏见用在这里无贬义)而已。因而这种问题毫无意义,你获取不了更多的信息。 --------------------编程问答-------------------- 1. GUID也可以不加时间编码。你可以参考一下SEQUENCE。
   SQL Server或者Oracle用SEQUENCE都比较方便。
   PostgreSQL和SQLite也有SEQUENCE的解决方案。

2. GUID/SEQUENCE 和 INT 两种方案,各有利弊。具体如何选择,看你的倾向。
   个人认为,你越在意并发与数据迁移,那么越应该倾向于 GUID/SEQUENCE

--------------------编程问答-------------------- 如果你把多进程/多线程下(在实际应用情况下)的代码写出来,然后进行测试,那么结果估计就会有不一样了。

而测试,仅仅是一个循环,从1到100000,顺序执行一个insert,这个测试是的结果根本不能用!

你实际使用时,如果插入的值是int,你会怎样编程?你绝对不是弄一个自己内存里的int,然后每一次都把它+1就写入数据库。 --------------------编程问答-------------------- 其实我更想知道有人会用int主键来处理排序相关的问题吗 --------------------编程问答-------------------- 有而且也不少。有各种理由,例如我们的要给每天几十万比电商交易单编一个流水号,以便更好地人工进行管理等等。

但是就这个帖子而言,要进行有结论的讨论讨论,首先要统一概念,知道讨论者如何使用int作为主键。于是首先我排除了那种所谓的简单“测试”,以为它的测试方法脱离了现实。

例如一个web服务同时会收到仅百消息,会同时产生仅百线程,例如同时会有100个asp.net的Page对象并发处理。在这样的多用户、多线程处理中,我们根本不可能像那种“循环顺序插入1~10000个数字”的测试方法那样处理。

我认为lz应该先说明在多用户、多线程的系统中“如何用int作为主键”。 --------------------编程问答-------------------- 看你自己的需求嘛 --------------------编程问答-------------------- 个人认为guid好处很多 远远大于它浪费的那点存储和性能
不过还是视项目情况而定吧 如果一个很小的项目 而且不是很严格 也可以用int --------------------编程问答-------------------- 按照正常逻辑,主键即不应该是GUID,也不应该是int,楼主只是在寻找主键的替代字段。
说到多数据库合并,可以考虑双INT+GUID+客户端ID,一个是本地自动编号,一个是远程自动编号。
如果远程自动编号是0,可以用于表示未上传状态。 --------------------编程问答-------------------- 看应用 
比如我就是一个小软件  也就在公司用用   INT较好

我是大型的  很多人会用  而且有很多数据库   以后还会迁移升级  guid --------------------编程问答--------------------
引用 2 楼 sp1234 的回复:
你怎样保证int编码不重复的呢?特别是多会话并发(例如asp.net下就可能有100个数据库会话同时并发)的情况。

如果根本不能很好地解决这个问题,那么就算弄顺序地弄100w个键值做测试,这种测试也是错误的。是一个错误的前提下做出的测试。


说得对。考虑到并发,还是用guid。 --------------------编程问答--------------------
引用 1 楼 guwei4037 的回复:
某人做过的一个测试。http://blog.csdn.net/fox123871/article/details/6578922
我以前写Demo的时候也老用Guid 不过我不知道哪个好 只是感觉用Guid很NB的样子 --------------------编程问答-------------------- 看需求,主键可以在产生后使用的,就用自增长主键即可,如果有父子关系,主键需要提前就拿到并用在后面数据的父ID的情况,就应该用GUID。这两种主键方式都和客户无关,主键只是用在内部,不是在外部使用的。 --------------------编程问答-------------------- 前段时间刚好测试过
用的是sqlserver2008


总结:大批量插入数据的时,GUID确实存在着不少的优势,这里考虑是认为Int自增列在插入时需要等待,二GUID则不需要,尽管在数据库中,(GUID上做聚集或者非聚集索引时)GUID插入时会引起页拆分,但是自增列的等待,比这个代价还大


与技术因素无关
但是在实际的生产环境中,存不存在天天批量连续插入的情况呢


--------------------编程问答-------------------- 单线程跟多线程测起来,是相反的结论

而GUID做聚集索引是万万要不得的,做非聚集索引也是不好的选择 --------------------编程问答-------------------- 除非有必要,采用GUID,同时GUID空间的消费是int类型的四倍,这个开销也是要考虑的 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 自增int的插入效率比GUID低,因为需要修改系统表中的当前编号;但是读取或者维护效率高于GUID,特别是小尺寸数据记录。
另外就是,对于成熟的ORM系统,可以很容易的实现程序自增,而不是数据库自增。 --------------------编程问答--------------------
引用 19 楼 sbwwkmyd 的回复:
自增int的插入效率比GUID低,因为需要修改系统表中的当前编号;但是读取或者维护效率高于GUID,特别是小尺寸数据记录。
另外就是,对于成熟的ORM系统,可以很容易的实现程序自增,而不是数据库自增。


ORM系统的自增是缓存级别的自增吗?怎么对付并发? --------------------编程问答--------------------
引用 20 楼 WYhack 的回复:
ORM系统的自增是缓存级别的自增吗?怎么对付并发?

整数自增可以使用内存锁,也可以不使用内存锁。就算使用内存锁,也绝对优于数据库的事物锁+硬盘写。 --------------------编程问答-------------------- 用什么好,就看你的业务逻辑需要 --------------------编程问答-------------------- 我这有很多小应用,几乎不用考虑并发的问题,用guid最烦的是值不是顺序的,用sqlserver提供的顺序guid又没办法在程序中获取插入记录后的值,要么用程序产生的的顺序guid又不好让几个应用同时使用,太烦人了。 --------------------编程问答-------------------- 我们可以看看这个帖子的问题:http://bbs.csdn.net/topics/390609063

假设说人家原本的数据发送协议是:多个消息中使用相同的Id号来表示消息的关联(属于同一组消息),而这个程序设计师却要习惯性地“但A的ID需要添加进数据库以后才能生成(自动字段),所以我就想先弄一个.......”,于是就开始纠结在“需要什么方式来产生这个id并且确保修改到其它消息上”了。

很明显,这个编号不能想当然地随便生成一个顺序编号,而需要你仔细设计一个复杂的机制来、付出超过原来想象100倍的时间代价来保证数据一致,需要你解决许多实际多会话编程访问数据库系统时遇到的bug。这样生成的编号,就算是比GUID占用空间少那么20几个字节,但是这类数据的插入时的瓶颈可能对仍然是一个严重的性能问题(而查询并不是性能瓶颈,尽管主键字段少占用点字节)。

关于所谓“哪个好?”我根本不想说一个武断的结论。我们可以拿出各种测试用例来讨论结果,有测试才有发言权。但是测试方法需要讨论,测试方法需要选择正确的,需要重新来看看每一个程序设计师所有能力说出的实际使用时“生成int编号”的做法具体是怎样的。 --------------------编程问答-------------------- 而需要你仔细设计一个复杂的机制来  -->  而顺序编号其实需要你仔细设计一个复杂的机制来


有人说“要看业务需求”。其实如果满脑子只有数据库增删改查的人,其实并不一定能很好地结合实际开发时的情况来设计程序。使用GUID基本上是说“我们只要有一个非常高查询效率的“散列码”就够了,而使用int顺序编号的做法必须拿出一个复杂机制来才行。 --------------------编程问答--------------------
引用 25 楼 sp1234 的回复:
而需要你仔细设计一个复杂的机制来  -->  而顺序编号其实需要你仔细设计一个复杂的机制来


有人说“要看业务需求”。其实如果满脑子只有数据库增删改查的人,其实并不一定能很好地结合实际开发时的情况来设计程序。使用GUID基本上是说“我们只要有一个非常高查询效率的“散列码”就够了,而使用int顺序编号的做法必须拿出一个复杂机制来才行。

数据库自增确实会存在事物问题。
可是内存自增对于ORM来说真的很简单,实现这个机制并且通过测试2小时足够了。 --------------------编程问答-------------------- GUID吧,用起来还是可以的。 --------------------编程问答-------------------- 针对于楼主所面对的情况,可能选择GUID作为主键算是比较好的选择,因为选择INT做主键,在多数据中心情况下保持不重复,确实需要相对比较复杂的机制来控制,这样的代价可能比选择GUID要大的多。而选择GUID则不需要考虑那么多。选择GUID的影响主要的存储和读取,这个主要是看你自己设定的Benchmark或者Priority来决定了。

one of the main benefits of GUIDs is the fact that they can be generated anywhere
and not conflict across time and space.
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,