我正在阅读使用或不使用Guidint的原因。至于int,我发现的唯一优势是它是独一无二的。在哪种情况下,Guid会比和Guid更好,为什么?

从我所看到的情况来看,int除了数量限制外没有其他缺陷,在许多情况下这是无关紧要的。
为什么要正确创建int?实际上,我认为它除了用作简单表的主键外,还有其他用途。 (是否有使用Guid进行实际应用的示例?)

(Guid = UniqueIdentifier)类型在SQL Server上

评论

我认为,不是主密钥,而是代理密钥,即不是自然密钥的密钥(后者是我们在现实世界中使用的密钥)。您可能是指聚集索引。

还请记住(主)键和索引之间的区别。

在SO上也进行了讨论:stackoverflow.com/questions/11033435/…

“ int除了数目限制外没有缺陷,在许多情况下这是不相关的。”:实际上,在INT与GUID的上下文中,考虑到上限,有符号32位INT的上限完全不相关一个有符号的64位BIGINT远远超出了几乎所有用途(如果您从下限开始编号,则更是如此;对于INT也是如此),它仍然是GUID大小的一半(8字节而不是16字节),并且连续的。

#1 楼

这已经在此处和此处的Stack Overflow中提出了。

Jeff的文章解释了很多有关使用GUID的优缺点。


GUID优点


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

GUID Cons


它比传统的4字节索引值大4倍。如果不注意的话,这可能会严重影响性能和存储

调试麻烦(where userid='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}'
生成的GUID应该部分顺序以获得最佳性能
(例如,SQL Server 2005+上的newsequentialid())并启用
聚集索引



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

评论


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

–布兰恩
2011年7月8日在21:22

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

– datagod
2011年8月6日下午4:32

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

–mrdenny
2011年8月6日在6:37



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

–所罗门·鲁兹基
2015年10月7日在18:54

@ChadKuehn在INT上选择UNIQUEIDENTIFIER,因为INT有上限,这是一个很差的推理,因为无穷无尽(虽然足够真实)并不是实际的好处。通过将INT的有效容量从下限(-21.4亿)而不是从1开始,可以轻松地使INT的有效容量增加一倍。或者,如果全部43亿还不够,则从仍然只有8的BIGINT开始个字节,而GUID则为16个字节,并且是顺序的。

–所罗门·鲁兹基
2015年10月7日18:59



#2 楼

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

评论


如果id已经足以供人类识别行,那么GUID会给出什么值?

–马丁·史密斯
2015年4月3日在18:06

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

–rmirabelle
15年4月3日在21:46

说得通!...

–马丁·史密斯
2015年4月3日在21:47

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

–所罗门·鲁兹基
2015年10月7日在19:05

@SolomonRutzky如果同时拥有两者并将PK设置为INT-IDENTITY而不是GUID,则会失去guid的2个主要优点:1)您必须等待db生成密钥(如果添加parent)和孩子,还有一个额外的往返); 2)如果要同步分布式数据库,则必须重新编号父表的标识和关联的子表的FK。如果您的PK只不过是引导,那么它会容易得多,然后INT仅可用于非关键性内容,例如url标识符。

– drizin
12月13日在22:44

#3 楼

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

#4 楼

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

#5 楼

rmir​​abelle的回答是我要做的。但是,对于大型项目,有一个最终的设计:
使用:键映射表
TableA

- ID int (PK)
- Data varchar(100)

TableAMap

- ID int (PK)
- UniversalID GUID (Indexed - nonclustered)


数据库复制/导入/导出很少需要GUID。因此,与其在主表上不使用GUID,不如在每行上占用额外的8个字节,并且GUID索引(默认情况下)将存储在同一卷上;
有了单独的表,您的DBA可以自由地将其存储在另一个较慢的磁盘上。另外,如果某些批处理作业仅需要GUID,则可以在需要它之前创建GUID索引,然后将其放置在后面。