GUID加上时间信息来编码也可以排序 INT加上编码区段也可以多数据中心数据合并
GUID使用方便一点,特别合并数据等,就是可能客户感到不爽,我以前刚看到别人软件用GUID主键也不爽
用哪一种数据类型的主键好,各位请指点一下
28 个解决方案
#2
你怎样保证int编码不重复的呢?特别是多会话并发(例如asp.net下就可能有100个数据库会话同时并发)的情况。
如果根本不能很好地解决这个问题,那么就算弄顺序地弄100w个键值做测试,这种测试也是错误的。是一个错误的前提下做出的测试。
如果根本不能很好地解决这个问题,那么就算弄顺序地弄100w个键值做测试,这种测试也是错误的。是一个错误的前提下做出的测试。
#3
看你从什么角度说“好”。
以前回答过一个人的问题,while好还是for循环好,最后他自己总结道,看来还是while循环好,因为可以少写几个字符,真是晕死。举这个例子就是告诉你,实际上你看问题的高度决定了你看问题的观点。表面上你似乎希望别人告诉你什么,其实只是你自己在罗织一种偏见(偏见用在这里无贬义)而已。因而这种问题毫无意义,你获取不了更多的信息。
以前回答过一个人的问题,while好还是for循环好,最后他自己总结道,看来还是while循环好,因为可以少写几个字符,真是晕死。举这个例子就是告诉你,实际上你看问题的高度决定了你看问题的观点。表面上你似乎希望别人告诉你什么,其实只是你自己在罗织一种偏见(偏见用在这里无贬义)而已。因而这种问题毫无意义,你获取不了更多的信息。
#4
1. GUID也可以不加时间编码。你可以参考一下SEQUENCE。
SQL Server或者Oracle用SEQUENCE都比较方便。
PostgreSQL和SQLite也有SEQUENCE的解决方案。
2. GUID/SEQUENCE 和 INT 两种方案,各有利弊。具体如何选择,看你的倾向。
个人认为,你越在意并发与数据迁移,那么越应该倾向于 GUID/SEQUENCE
SQL Server或者Oracle用SEQUENCE都比较方便。
PostgreSQL和SQLite也有SEQUENCE的解决方案。
2. GUID/SEQUENCE 和 INT 两种方案,各有利弊。具体如何选择,看你的倾向。
个人认为,你越在意并发与数据迁移,那么越应该倾向于 GUID/SEQUENCE
#5
如果你把多进程/多线程下(在实际应用情况下)的代码写出来,然后进行测试,那么结果估计就会有不一样了。
而测试,仅仅是一个循环,从1到100000,顺序执行一个insert,这个测试是的结果根本不能用!
你实际使用时,如果插入的值是int,你会怎样编程?你绝对不是弄一个自己内存里的int,然后每一次都把它+1就写入数据库。
而测试,仅仅是一个循环,从1到100000,顺序执行一个insert,这个测试是的结果根本不能用!
你实际使用时,如果插入的值是int,你会怎样编程?你绝对不是弄一个自己内存里的int,然后每一次都把它+1就写入数据库。
#6
其实我更想知道有人会用int主键来处理排序相关的问题吗
#7
有而且也不少。有各种理由,例如我们的要给每天几十万比电商交易单编一个流水号,以便更好地人工进行管理等等。
但是就这个帖子而言,要进行有结论的讨论讨论,首先要统一概念,知道讨论者如何使用int作为主键。于是首先我排除了那种所谓的简单“测试”,以为它的测试方法脱离了现实。
例如一个web服务同时会收到仅百消息,会同时产生仅百线程,例如同时会有100个asp.net的Page对象并发处理。在这样的多用户、多线程处理中,我们根本不可能像那种“循环顺序插入1~10000个数字”的测试方法那样处理。
我认为lz应该先说明在多用户、多线程的系统中“如何用int作为主键”。
但是就这个帖子而言,要进行有结论的讨论讨论,首先要统一概念,知道讨论者如何使用int作为主键。于是首先我排除了那种所谓的简单“测试”,以为它的测试方法脱离了现实。
例如一个web服务同时会收到仅百消息,会同时产生仅百线程,例如同时会有100个asp.net的Page对象并发处理。在这样的多用户、多线程处理中,我们根本不可能像那种“循环顺序插入1~10000个数字”的测试方法那样处理。
我认为lz应该先说明在多用户、多线程的系统中“如何用int作为主键”。
#8
看你自己的需求嘛
#9
个人认为guid好处很多 远远大于它浪费的那点存储和性能
不过还是视项目情况而定吧 如果一个很小的项目 而且不是很严格 也可以用int
不过还是视项目情况而定吧 如果一个很小的项目 而且不是很严格 也可以用int
#10
按照正常逻辑,主键即不应该是GUID,也不应该是int,楼主只是在寻找主键的替代字段。
说到多数据库合并,可以考虑双INT+GUID+客户端ID,一个是本地自动编号,一个是远程自动编号。
如果远程自动编号是0,可以用于表示未上传状态。
说到多数据库合并,可以考虑双INT+GUID+客户端ID,一个是本地自动编号,一个是远程自动编号。
如果远程自动编号是0,可以用于表示未上传状态。
#11
看应用
比如我就是一个小软件 也就在公司用用 INT较好
我是大型的 很多人会用 而且有很多数据库 以后还会迁移升级 guid
比如我就是一个小软件 也就在公司用用 INT较好
我是大型的 很多人会用 而且有很多数据库 以后还会迁移升级 guid
#12
说得对。考虑到并发,还是用guid。
#13
我以前写Demo的时候也老用Guid 不过我不知道哪个好 只是感觉用Guid很NB的样子
#14
看需求,主键可以在产生后使用的,就用自增长主键即可,如果有父子关系,主键需要提前就拿到并用在后面数据的父ID的情况,就应该用GUID。这两种主键方式都和客户无关,主键只是用在内部,不是在外部使用的。
#15
前段时间刚好测试过
用的是sqlserver2008
总结:大批量插入数据的时,GUID确实存在着不少的优势,这里考虑是认为Int自增列在插入时需要等待,二GUID则不需要,尽管在数据库中,(GUID上做聚集或者非聚集索引时)GUID插入时会引起页拆分,但是自增列的等待,比这个代价还大
与技术因素无关
但是在实际的生产环境中,存不存在天天批量连续插入的情况呢
用的是sqlserver2008
总结:大批量插入数据的时,GUID确实存在着不少的优势,这里考虑是认为Int自增列在插入时需要等待,二GUID则不需要,尽管在数据库中,(GUID上做聚集或者非聚集索引时)GUID插入时会引起页拆分,但是自增列的等待,比这个代价还大
与技术因素无关
但是在实际的生产环境中,存不存在天天批量连续插入的情况呢
#16
单线程跟多线程测起来,是相反的结论
而GUID做聚集索引是万万要不得的,做非聚集索引也是不好的选择
而GUID做聚集索引是万万要不得的,做非聚集索引也是不好的选择
#17
除非有必要,采用GUID,同时GUID空间的消费是int类型的四倍,这个开销也是要考虑的
#18
#19
自增int的插入效率比GUID低,因为需要修改系统表中的当前编号;但是读取或者维护效率高于GUID,特别是小尺寸数据记录。
另外就是,对于成熟的ORM系统,可以很容易的实现程序自增,而不是数据库自增。
另外就是,对于成熟的ORM系统,可以很容易的实现程序自增,而不是数据库自增。
#20
ORM系统的自增是缓存级别的自增吗?怎么对付并发?
#21
整数自增可以使用内存锁,也可以不使用内存锁。就算使用内存锁,也绝对优于数据库的事物锁+硬盘写。
#22
用什么好,就看你的业务逻辑需要
#23
我这有很多小应用,几乎不用考虑并发的问题,用guid最烦的是值不是顺序的,用sqlserver提供的顺序guid又没办法在程序中获取插入记录后的值,要么用程序产生的的顺序guid又不好让几个应用同时使用,太烦人了。
#24
我们可以看看这个帖子的问题:
http://bbs.csdn.net/topics/390609063
假设说人家原本的数据发送协议是:多个消息中使用相同的Id号来表示消息的关联(属于同一组消息),而这个程序设计师却要习惯性地“但A的ID需要添加进数据库以后才能生成(自动字段),所以我就想先弄一个.......”,于是就开始纠结在“需要什么方式来产生这个id并且确保修改到其它消息上”了。
很明显,这个编号不能想当然地随便生成一个顺序编号,而需要你仔细设计一个复杂的机制来、付出超过原来想象100倍的时间代价来保证数据一致,需要你解决许多实际多会话编程访问数据库系统时遇到的bug。这样生成的编号,就算是比GUID占用空间少那么20几个字节,但是这类数据的插入时的瓶颈可能对仍然是一个严重的性能问题(而查询并不是性能瓶颈,尽管主键字段少占用点字节)。
关于所谓“哪个好?”我根本不想说一个武断的结论。我们可以拿出各种测试用例来讨论结果,有测试才有发言权。但是测试方法需要讨论,测试方法需要选择正确的,需要重新来看看每一个程序设计师所有能力说出的实际使用时“生成int编号”的做法具体是怎样的。
假设说人家原本的数据发送协议是:多个消息中使用相同的Id号来表示消息的关联(属于同一组消息),而这个程序设计师却要习惯性地“但A的ID需要添加进数据库以后才能生成(自动字段),所以我就想先弄一个.......”,于是就开始纠结在“需要什么方式来产生这个id并且确保修改到其它消息上”了。
很明显,这个编号不能想当然地随便生成一个顺序编号,而需要你仔细设计一个复杂的机制来、付出超过原来想象100倍的时间代价来保证数据一致,需要你解决许多实际多会话编程访问数据库系统时遇到的bug。这样生成的编号,就算是比GUID占用空间少那么20几个字节,但是这类数据的插入时的瓶颈可能对仍然是一个严重的性能问题(而查询并不是性能瓶颈,尽管主键字段少占用点字节)。
关于所谓“哪个好?”我根本不想说一个武断的结论。我们可以拿出各种测试用例来讨论结果,有测试才有发言权。但是测试方法需要讨论,测试方法需要选择正确的,需要重新来看看每一个程序设计师所有能力说出的实际使用时“生成int编号”的做法具体是怎样的。
#25
而需要你仔细设计一个复杂的机制来 --> 而顺序编号其实需要你仔细设计一个复杂的机制来
有人说“要看业务需求”。其实如果满脑子只有数据库增删改查的人,其实并不一定能很好地结合实际开发时的情况来设计程序。使用GUID基本上是说“我们只要有一个非常高查询效率的“散列码”就够了,而使用int顺序编号的做法必须拿出一个复杂机制来才行。
有人说“要看业务需求”。其实如果满脑子只有数据库增删改查的人,其实并不一定能很好地结合实际开发时的情况来设计程序。使用GUID基本上是说“我们只要有一个非常高查询效率的“散列码”就够了,而使用int顺序编号的做法必须拿出一个复杂机制来才行。
#26
数据库自增确实会存在事物问题。
可是内存自增对于ORM来说真的很简单,实现这个机制并且通过测试2小时足够了。
#27
GUID吧,用起来还是可以的。
#28
针对于楼主所面对的情况,可能选择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.
one of the main benefits of GUIDs is the fact that they can be generated anywhere
and not conflict across time and space.
#1
#2
你怎样保证int编码不重复的呢?特别是多会话并发(例如asp.net下就可能有100个数据库会话同时并发)的情况。
如果根本不能很好地解决这个问题,那么就算弄顺序地弄100w个键值做测试,这种测试也是错误的。是一个错误的前提下做出的测试。
如果根本不能很好地解决这个问题,那么就算弄顺序地弄100w个键值做测试,这种测试也是错误的。是一个错误的前提下做出的测试。
#3
看你从什么角度说“好”。
以前回答过一个人的问题,while好还是for循环好,最后他自己总结道,看来还是while循环好,因为可以少写几个字符,真是晕死。举这个例子就是告诉你,实际上你看问题的高度决定了你看问题的观点。表面上你似乎希望别人告诉你什么,其实只是你自己在罗织一种偏见(偏见用在这里无贬义)而已。因而这种问题毫无意义,你获取不了更多的信息。
以前回答过一个人的问题,while好还是for循环好,最后他自己总结道,看来还是while循环好,因为可以少写几个字符,真是晕死。举这个例子就是告诉你,实际上你看问题的高度决定了你看问题的观点。表面上你似乎希望别人告诉你什么,其实只是你自己在罗织一种偏见(偏见用在这里无贬义)而已。因而这种问题毫无意义,你获取不了更多的信息。
#4
1. GUID也可以不加时间编码。你可以参考一下SEQUENCE。
SQL Server或者Oracle用SEQUENCE都比较方便。
PostgreSQL和SQLite也有SEQUENCE的解决方案。
2. GUID/SEQUENCE 和 INT 两种方案,各有利弊。具体如何选择,看你的倾向。
个人认为,你越在意并发与数据迁移,那么越应该倾向于 GUID/SEQUENCE
SQL Server或者Oracle用SEQUENCE都比较方便。
PostgreSQL和SQLite也有SEQUENCE的解决方案。
2. GUID/SEQUENCE 和 INT 两种方案,各有利弊。具体如何选择,看你的倾向。
个人认为,你越在意并发与数据迁移,那么越应该倾向于 GUID/SEQUENCE
#5
如果你把多进程/多线程下(在实际应用情况下)的代码写出来,然后进行测试,那么结果估计就会有不一样了。
而测试,仅仅是一个循环,从1到100000,顺序执行一个insert,这个测试是的结果根本不能用!
你实际使用时,如果插入的值是int,你会怎样编程?你绝对不是弄一个自己内存里的int,然后每一次都把它+1就写入数据库。
而测试,仅仅是一个循环,从1到100000,顺序执行一个insert,这个测试是的结果根本不能用!
你实际使用时,如果插入的值是int,你会怎样编程?你绝对不是弄一个自己内存里的int,然后每一次都把它+1就写入数据库。
#6
其实我更想知道有人会用int主键来处理排序相关的问题吗
#7
有而且也不少。有各种理由,例如我们的要给每天几十万比电商交易单编一个流水号,以便更好地人工进行管理等等。
但是就这个帖子而言,要进行有结论的讨论讨论,首先要统一概念,知道讨论者如何使用int作为主键。于是首先我排除了那种所谓的简单“测试”,以为它的测试方法脱离了现实。
例如一个web服务同时会收到仅百消息,会同时产生仅百线程,例如同时会有100个asp.net的Page对象并发处理。在这样的多用户、多线程处理中,我们根本不可能像那种“循环顺序插入1~10000个数字”的测试方法那样处理。
我认为lz应该先说明在多用户、多线程的系统中“如何用int作为主键”。
但是就这个帖子而言,要进行有结论的讨论讨论,首先要统一概念,知道讨论者如何使用int作为主键。于是首先我排除了那种所谓的简单“测试”,以为它的测试方法脱离了现实。
例如一个web服务同时会收到仅百消息,会同时产生仅百线程,例如同时会有100个asp.net的Page对象并发处理。在这样的多用户、多线程处理中,我们根本不可能像那种“循环顺序插入1~10000个数字”的测试方法那样处理。
我认为lz应该先说明在多用户、多线程的系统中“如何用int作为主键”。
#8
看你自己的需求嘛
#9
个人认为guid好处很多 远远大于它浪费的那点存储和性能
不过还是视项目情况而定吧 如果一个很小的项目 而且不是很严格 也可以用int
不过还是视项目情况而定吧 如果一个很小的项目 而且不是很严格 也可以用int
#10
按照正常逻辑,主键即不应该是GUID,也不应该是int,楼主只是在寻找主键的替代字段。
说到多数据库合并,可以考虑双INT+GUID+客户端ID,一个是本地自动编号,一个是远程自动编号。
如果远程自动编号是0,可以用于表示未上传状态。
说到多数据库合并,可以考虑双INT+GUID+客户端ID,一个是本地自动编号,一个是远程自动编号。
如果远程自动编号是0,可以用于表示未上传状态。
#11
看应用
比如我就是一个小软件 也就在公司用用 INT较好
我是大型的 很多人会用 而且有很多数据库 以后还会迁移升级 guid
比如我就是一个小软件 也就在公司用用 INT较好
我是大型的 很多人会用 而且有很多数据库 以后还会迁移升级 guid
#12
说得对。考虑到并发,还是用guid。
#13
我以前写Demo的时候也老用Guid 不过我不知道哪个好 只是感觉用Guid很NB的样子
#14
看需求,主键可以在产生后使用的,就用自增长主键即可,如果有父子关系,主键需要提前就拿到并用在后面数据的父ID的情况,就应该用GUID。这两种主键方式都和客户无关,主键只是用在内部,不是在外部使用的。
#15
前段时间刚好测试过
用的是sqlserver2008
总结:大批量插入数据的时,GUID确实存在着不少的优势,这里考虑是认为Int自增列在插入时需要等待,二GUID则不需要,尽管在数据库中,(GUID上做聚集或者非聚集索引时)GUID插入时会引起页拆分,但是自增列的等待,比这个代价还大
与技术因素无关
但是在实际的生产环境中,存不存在天天批量连续插入的情况呢
用的是sqlserver2008
总结:大批量插入数据的时,GUID确实存在着不少的优势,这里考虑是认为Int自增列在插入时需要等待,二GUID则不需要,尽管在数据库中,(GUID上做聚集或者非聚集索引时)GUID插入时会引起页拆分,但是自增列的等待,比这个代价还大
与技术因素无关
但是在实际的生产环境中,存不存在天天批量连续插入的情况呢
#16
单线程跟多线程测起来,是相反的结论
而GUID做聚集索引是万万要不得的,做非聚集索引也是不好的选择
而GUID做聚集索引是万万要不得的,做非聚集索引也是不好的选择
#17
除非有必要,采用GUID,同时GUID空间的消费是int类型的四倍,这个开销也是要考虑的
#18
#19
自增int的插入效率比GUID低,因为需要修改系统表中的当前编号;但是读取或者维护效率高于GUID,特别是小尺寸数据记录。
另外就是,对于成熟的ORM系统,可以很容易的实现程序自增,而不是数据库自增。
另外就是,对于成熟的ORM系统,可以很容易的实现程序自增,而不是数据库自增。
#20
ORM系统的自增是缓存级别的自增吗?怎么对付并发?
#21
整数自增可以使用内存锁,也可以不使用内存锁。就算使用内存锁,也绝对优于数据库的事物锁+硬盘写。
#22
用什么好,就看你的业务逻辑需要
#23
我这有很多小应用,几乎不用考虑并发的问题,用guid最烦的是值不是顺序的,用sqlserver提供的顺序guid又没办法在程序中获取插入记录后的值,要么用程序产生的的顺序guid又不好让几个应用同时使用,太烦人了。
#24
我们可以看看这个帖子的问题:
http://bbs.csdn.net/topics/390609063
假设说人家原本的数据发送协议是:多个消息中使用相同的Id号来表示消息的关联(属于同一组消息),而这个程序设计师却要习惯性地“但A的ID需要添加进数据库以后才能生成(自动字段),所以我就想先弄一个.......”,于是就开始纠结在“需要什么方式来产生这个id并且确保修改到其它消息上”了。
很明显,这个编号不能想当然地随便生成一个顺序编号,而需要你仔细设计一个复杂的机制来、付出超过原来想象100倍的时间代价来保证数据一致,需要你解决许多实际多会话编程访问数据库系统时遇到的bug。这样生成的编号,就算是比GUID占用空间少那么20几个字节,但是这类数据的插入时的瓶颈可能对仍然是一个严重的性能问题(而查询并不是性能瓶颈,尽管主键字段少占用点字节)。
关于所谓“哪个好?”我根本不想说一个武断的结论。我们可以拿出各种测试用例来讨论结果,有测试才有发言权。但是测试方法需要讨论,测试方法需要选择正确的,需要重新来看看每一个程序设计师所有能力说出的实际使用时“生成int编号”的做法具体是怎样的。
假设说人家原本的数据发送协议是:多个消息中使用相同的Id号来表示消息的关联(属于同一组消息),而这个程序设计师却要习惯性地“但A的ID需要添加进数据库以后才能生成(自动字段),所以我就想先弄一个.......”,于是就开始纠结在“需要什么方式来产生这个id并且确保修改到其它消息上”了。
很明显,这个编号不能想当然地随便生成一个顺序编号,而需要你仔细设计一个复杂的机制来、付出超过原来想象100倍的时间代价来保证数据一致,需要你解决许多实际多会话编程访问数据库系统时遇到的bug。这样生成的编号,就算是比GUID占用空间少那么20几个字节,但是这类数据的插入时的瓶颈可能对仍然是一个严重的性能问题(而查询并不是性能瓶颈,尽管主键字段少占用点字节)。
关于所谓“哪个好?”我根本不想说一个武断的结论。我们可以拿出各种测试用例来讨论结果,有测试才有发言权。但是测试方法需要讨论,测试方法需要选择正确的,需要重新来看看每一个程序设计师所有能力说出的实际使用时“生成int编号”的做法具体是怎样的。
#25
而需要你仔细设计一个复杂的机制来 --> 而顺序编号其实需要你仔细设计一个复杂的机制来
有人说“要看业务需求”。其实如果满脑子只有数据库增删改查的人,其实并不一定能很好地结合实际开发时的情况来设计程序。使用GUID基本上是说“我们只要有一个非常高查询效率的“散列码”就够了,而使用int顺序编号的做法必须拿出一个复杂机制来才行。
有人说“要看业务需求”。其实如果满脑子只有数据库增删改查的人,其实并不一定能很好地结合实际开发时的情况来设计程序。使用GUID基本上是说“我们只要有一个非常高查询效率的“散列码”就够了,而使用int顺序编号的做法必须拿出一个复杂机制来才行。
#26
数据库自增确实会存在事物问题。
可是内存自增对于ORM来说真的很简单,实现这个机制并且通过测试2小时足够了。
#27
GUID吧,用起来还是可以的。
#28
针对于楼主所面对的情况,可能选择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.
one of the main benefits of GUIDs is the fact that they can be generated anywhere
and not conflict across time and space.