Guid vs INT-作为主键哪个更好?


97

我正在阅读有关是否使用Guid和的原因int

int体积更小,速度更快,易于记忆,并按时间顺序排列。至于Guid,我发现的唯一优势是它是独一无二的。在那种情况下,a Guid会比更好int,为什么?

从我所看到的来看,int除了数量上的限制外没有其他缺陷,在许多情况下这是无关紧要的。

为什么要精确Guid创建?实际上,我认为它除了用作简单表的主键外,还有其他用途。(是否有用于实际应用的示例Guid?)

(Guid = UniqueIdentifier)SQL Server上的类型


1
而不是键,我想你的意思代理即关键不是自然键键(后者是我们在现实世界中使用的密钥)。可能是指聚集索引。
2012年

还请记住(主)键和索引之间的区别。
艾伦·汉森


2
int除了数量限制,它没有缺陷,在许多情况下这是不相关的。”:实际上,在INT与GUID的上下文中,有符号的32位INT上限完全无关紧要,因为有符号的上限,64位BIGINT几乎超出了几乎所有用途(如果您从下限开始编号,则更多,甚至更多INT),并且它仍然是GUID(8字节而不是16字节)和顺序大小的一半。
所罗门·鲁兹基

Answers:


89

这在这里这里的堆栈溢出中已被问到。

Jeff的帖子对使用GUID的优缺点作了很多解释。

GUID优点

  • 在每个表,每个数据库和每个服务器上都是唯一的
  • 允许轻松合并来自不同数据库的记录
  • 允许在多个服务器之间轻松分发数据库
  • 您可以在任何地方生成ID,而不必往返于数据库
  • 大多数复制方案仍然需要GUID列

GUID缺点

  • 它比传统的4字节索引值大4倍;如果您不小心,可能会对性能和存储造成严重影响
  • 调试麻烦(where userid='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}'
  • 生成的GUID应该是部分顺序的,以实现最佳性能(例如,newsequentialid()在SQL Server 2005+上)并允许使用聚集索引

如果您对性能有把握,并且不打算复制或合并记录,请使用int,并将其设置为自动递增(SQL Server中的身份种子)。


20
GUID方法的另一个缺点是您不能将其用作最终用户的标识符。您是否真的希望您的用户在电话上告诉您他们对“ BAE7DF4-DDF-3RG-5TY3E3RF456AS10”订单有疑问?:)
Brann

3
如果不使用顺序向导,并且主键是群集的(SQL Server默认),则所有数据插入将随机散布在整个表中,从而导致数据大量碎片化。这是假设数据通常将按某种顺序插入,例如按时间顺序。
datagod 2011年

6
顺序向导只有在重新启动SQL实例之前才是顺序的。然后,由于生成根值的方式,第一个值很可能会比前一个值低,从而再次引起各种问题。
mrdenny

20
@Brann理想情况下,您不会首先将您的PK值提供给最终用户。我知道这样做是很普遍的,这是我本人过去做过的事,后来才学会不这样做。但是由于不应该这样做,所以选择INT而不是GUID的特定原因并不是有效的理由。
所罗门·鲁兹基

2
@ChadKuehn选择UNIQUEIDENTIFIERINT,因为INT有一个上限,因为是无限的推理比较差,而真的不够,是不是一个实际的好处。您可以INT通过在下限(-21.4亿)而不是1下启动,轻松将an的有效容量增加一倍。或者,如果全部43亿还不够,则以BIGINT仍然只有8个字节的a开头与GUID的16相比,它是顺序的。
所罗门·鲁兹基

18

如果您要与外部源同步数据,则持久性GUID会更好。我们在其中使用GUID的一个简单示例是一种工具,该工具可发送给客户以爬网他们的网络并进行某些类型的自动发现,存储找到的记录,然后将所有客户记录集成到中央数据库中回到我们的尽头。如果我们使用整数,则将有7,398个“ 1”,并且很难追踪哪个“ 1”是哪个。


3
GUID绝对可以作为外部标识符,并且我会保留一个非聚集索引作为“外部键”,而我仍然保留一个int作为“内部键”,这是聚簇索引和外键关系的基础。如果有什么东西要跨越架构的界限(例如与另一个应用程序通信),我会很高兴有一些不能混淆的东西。
格雷格

15

我使用成功的混合方法。表包含一个自动递增的主键整数id列和一个guid列。将guid根据需要来全局唯一标识该行并且可以使用id可用于查询,排序和行的人的识别。


3
如果GUID id已足以供人类识别行,GUID会提供什么值?
马丁·史密斯

6
ID标识此表中的行。GUID(至少在理论上)在已知Universe中的任何位置标识此行。在我的项目中,每个Android手机在本地SQLite数据库上都具有表的结构相同副本。该行及其GUID均在Android上生成。然后,当Android同步到后端数据库时,其本地行将写入后端表,而不必担心与从其他任何Android移动设备创建的行发生冲突。
rmir​​abelle 2015年

2
@MartinSmith我自己使用了这种方法,效果很好。GUID只是具有非聚集索引的备用键,是从应用程序传入的,但仅驻留在主表中。所有相关表都通过INTPK 相关。我感到奇怪的是,鉴于这是两全其美的做法,这种方法并不普遍。似乎大多数人只喜欢以绝对主义者的方式解决问题,而不是意识到PK不必是GUID即可使应用程序仍使用GUID来实现全局唯一性和/或可移植性。
所罗门·鲁茨基

1
@rmirabelle我曾经考虑过这种方法,并且很犹豫,但是您的回答使我信服。基本上,我处于一种需要为工作项具有唯一标识符(可以从任何地方通过网络进入)的情况,但是我不想首先往返于数据库。GUID是一个很好的解决方案,但是我想如果没有连续的集群键,JOIN的速度会慢很多。
easuter 2015年

1
@easuter我同意不“仅出于此目的”不添加ID字段,例如在多对多“桥”表中,其中PK应该是两个相关FK的组合。但是这里并不是权衡取舍,因为ID字段不仅仅是出于此目的。允许系统高效运行非常重要;-)。而且,我认为在您的情况下,由于GUID是在外部生成的,因此即使在实用上也不能保证它们是唯一的。但是数据完整性的责任足以使GUID成为备用键,而ID为PK :)
Solomon Rutzky 2015年

1

仍然有一些最佳实践提到您应该使用一种数据类型,该数据类型应尽可能减少要使用的整个值集的内存。例如,如果您使用它来存储一家小型企业的雇主数量,并且不太可能达到100,那么没人会建议使用bigint值,而int(甚至smallint)会这样做。

当然,这样做的缺点是“对扩展性说不!”


另外,我知道这并不完全相关,但是还有另一个因素。如果不适合,我通常会建议您使用非自动生成的主键(如果确实可行)。例如,如果您要保存驾驶员的信息,则不必为“ ID”创建新的自动生成的列,只需使用许可证号即可。

我知道这听起来确实很明显,但是我经常看到它被忘记了。

对于上下文:答案的这一部分是通过数据理论方法解决的,您希望您的PK成为记录的唯一数据标识符。在大多数情况下,我们会在它们已经存在时创建它们,因此是先前的答案。

但是,很少能够对这些数据点进行严格控制,因此,您可能需要进行更正或调整。您不能使用主键来做到这一点(可以,但是会很痛苦)。

感谢@VahiD的澄清。


根本不建议使用有意义的主键,请考虑以下情况,有人输入了错误的许可证号,并且您已在3-4个表中将此ID用作外键,如何解决此错误?在这种情况下,仅编辑许可证号是不够的。
VahiD 2015年

1
有趣:我读了您的评论,然后以为“是”,然后回头阅读我的回答并以为“我说了吗”?有趣的是几年后情况如何变化。我可能来自更理论的背景,但是除非您对此有严格的控制(很少),否则它不会带来太多好处。我将更新答案。
Alpha

支持多年来的发展:)
VahiD

1

使用自动增量ID可能会泄漏有关您的业务活动的信息。如果您正在经营一家商店并用于order_id公开识别购买,那么任何人都可以通过简单的算术找出您的每月销售额。


0

关于如何生成GUID的另一件事。mrdenny正确指出,即使正在使用newsequentialid(),重新启动实例也会导致新值开始于先前处理中留下的“漏洞”。影响“顺序” GUID的另一件事是网卡。如果我没记错的话,NIC的UID用作GUID算法的一部分。如果更换了NIC,则无法保证UID会具有较高的值以保持事物的顺序状态。我也不确定使用该算法,多个NIC如何影响值的分配。

只是一个想法,我希望我能正确记住。祝你有美好的一天!


2
欢迎使用数据库管理员,bobo8734。您能找到这些评论的来源吗?如果您不确定它们,也许最好将它们用作注释(如果您有代表)(比起独立答案)。
LowlyDBA '18年

-6

同时使用

对主键使用int / Bigint,因为它易于维护并用作外键关系。

但是将一列绑定到GUID,以便每一行也都有一个唯一的列


2
我敢肯定,解释这个建议背后的理由不会伤害任何人。
Andriy M

GUID是36个字符长将是难以阅读如果你正在寻找一个特定的情况下..
阿卜杜勒·汉南Ijaz

1
好的,但这并不能真正解释为什么OP应该同时使用intguid,正如您在答案中所建议的那样。而且,我并不是在向我解释您的建议,而是要您更新答案。顺便说一句,您是否知道其他回答者已经建议与您相同(或多或少)
Andriy M

是的,我的意思是同一件事..很酷的顺便说一句:)
阿卜杜勒·汉南·伊贾兹
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.