2010-05-10 19 views
14

我最近开始一个新的工作,并注意到所有的SQL表都使用主键的GUID数据类型。SQL GUID与整数

在我以前的工作中,我们使用整数(自动递增)作为主键,在我看来这更容易处理。

例如,假设您有两个相关的表格;产品和产品类型 - 我可以很容易地跨两个表中的'ProductTypeID'列检查特定行,以快速映射数据,因为它容易存储数字(2,4,45等),而不是(E75B92A3- 3299-4407-A913-C5CA196B3CAB)。

额外的挫折来自我想了解这些表是如何关联的,遗憾的是没有数据库图:(

很多人说,GUID的更好,因为你可以在C#中定义的独特IDENTIFER代码例如使用NewID()而不需要SQL SERVER来完成它 - 这也允许您临时知道该ID是什么......但我已经看到,仍然可以检索'下一个自动递增的整数'

一位DBA承包商报告说,如果我们使用Integer类型而不是GUIDS,我们的查询速度可能会高出30%...

为什么存在GUID数据类型,它的真正优势是什么?......即使某些专业人士选择了它,但是为什么它的实现还需要一些很好的理由?

+0

可能重复http://stackoverflow.com/questions/829284/guid-vs -int-identity) – 2012-04-18 03:03:04

回答

17

GUID是好,因为在某些情况下标识字段:

  • 当你有SQL(不同的服务器)的多个实例,你需要不同的更新,而不会影响参照完整性后来结合
  • 断开连接创建数据的客户端 - 通过这种方式,他们可以创建数据,而无需担心ID字段已被占用

GUID生成为全局唯一的,这就是为什么它们适用于此类s cenarios。

+0

好吧,现在这实际上有很大的意义,因为我遇到过当我不得不重新插入一些数据和自动增加列的原因beca我是一个噩梦...与GUID这不会是一个问题......谢谢:) – Dal 2010-05-10 17:51:29

2

它是全局唯一的,所以表中的每条记录都有一个GUID,该GUID不会被世界上任何类型的其他项共享。如果您需要这种独占识别(如果您正在复制数据库或组合来自多个来源的数据),方便使用。否则,你的DBA是正确的 - GUID是更大的,效率较低是整数,你可以加快你的分贝(30%也许...?)

+0

是的,我可以看到'如何复制数据'这将是非常有利的,并删除限制,自动递增的列会给。数据库设计不是我见过的最好的 - 我可以相信30%的改进大声笑。 – Dal 2010-05-10 17:52:55

0

他们基本上是从多个有时候复杂的逻辑为您节省使用

set @InsertID = scope_identity() 
3

有很多关于将GUID用作PK的Google文章,而且几乎所有人都说你的DBA承包商说的同样的东西 - 查询更快,没有GUID作为关键字。

我在实践中看到的主要用途(我们从未使用过它们作为PK)与复制有关。 uniqueidentifier的MSDN页面大致相同。

+0

感谢您的输入,他们正在使用他们的PK,这是很难虚拟导航行。 – Dal 2010-05-10 17:54:21

+1

@marc_s:哦上帝......错字。好抓 – 2010-05-10 18:32:30

+0

是的,有复制,GUID可能有意义 - 作为主键。但即使如此,我仍会尽量避免(如瘟疫)将GUID列作为我的集群密钥在桌面上! – 2010-05-10 18:44:56

6

INT

优势:在联接,索引和条件下使用时

数字值(具体的整数)是用于性能更好。 如果显示应用程序用户,则数值更易于理解。

缺点

如果你的表是大,很可能会耗尽它经过一番数值不会有额外的身份来使用。

GUID

优势

跨服务器的唯一。

缺点:在联接,索引和条件下使用时

字符串值不为整数的性能值作为最佳的。 需要更多的存储空间比INT。

归功于:http://blog.sqlauthority.com/2010/04/28/sql-server-guid-vs-int-your-opinion/

+1

我怀疑人们可能会有比4字节整数(20亿)更多的行,甚至更少的会比8字节BIGINT的限制更多:9,223,372,036,854,775,807。如果他们这样做,则为负数,您可以将行数加倍。 – 2010-05-10 17:48:24

+0

INT的缺点很容易通过使用BIGINT作为必要条件来克服。至少在Mysql中,这是一个64位的整数,你永远不会拥有那么多的记录,它仍然只有一个GUID大小的50%。使用GUID的唯一原因是可伸缩性。如果你想要使用GUID,大多数数据库都允许将GUID存储为二进制而不是十六进制字符串,这可以节省一半的存储空间并加快索引的速度。 – wump 2010-05-10 17:50:34

+0

由于大量索引和页面碎片,GUID作为SQL Server中的集群密钥具有很大的不利之处:非常糟糕的性能。看看我的答案中提到的文章 - 然后再想一想。 GUID很方便 - 但他们是DBA的地狱成真...... – 2010-05-10 18:21:23

14

相反的是这里大多数人似乎讲道,我看到GUID的更瘟疫比祝福。原因如下:

GUID似乎是您主键的自然选择 - 如果您确实需要,您可能会争论将其用于表的PRIMARY KEY。我强烈建议不要做是使用GUID列作为集群密钥,默认情况下SQL Server会这样做,除非您明确地告诉它不要。

你真的需要保留两个问题分开:

  1. 主键是一个逻辑结构 - 候选键唯一和可靠地识别你的表中每一行的一个。这可以是任何东西,真的 - 一个INT,一个GUID,一个字符串 - 选择对你的场景最有意义的东西。

  2. 聚集键(列或定义表上的“聚集索引”列) - 这是一个物理存储相关的事情,在这里,一个小的,稳定的,不断增长的数据类型是您的最佳选择 - INT或BIGINT作为您的默认选项。

默认情况下,SQL Server表上的主键也用作集群键 - 但这并不需要那样!将以前基于GUID的主键/集群键分解为两个单独的键 - GUID上的主键(逻辑键)和单独的INT IDENTITY上的集群(排序)键(1, 1)栏。

由于Kimberly Tripp-索引的女王 - 和其他人已经说了很多次 - 作为聚类键的GUID并不是最佳的,因为由于它的随机性,它将导致大量的页面和索引碎片,并且通常糟糕的表现。

是的,我知道 - 在SQL Server 2005中有newsequentialid()及以上 - 但即使这不是真正的完全顺序,因此也遭受与GUID相同的问题 - 只是稍微突出一点。另外,您只能将它用作表中列的默认值 - 您无法在T-SQL代码中获得新的顺序GUID(如触发器或其他) - 另一个主要缺点。

然后还有一个需要考虑的问题:表上的聚簇键将被添加到表上每个非聚簇索引中的每个条目上 - 因此,您确实希望确保它小到可能。通常情况下,具有超过250亿行的INT应该足以满足绝大多数表的要求 - 并且与GUID作为集群密钥相比,您可以为磁盘和服务器内存节省数百兆的存储空间。

快速计算 - 使用INT与GUID作为主要和聚集键:

  • 基表与1'000'000行(3.8 MB与15.26 MB)
  • 6个的非聚集索引(22.89 MB与91.55 MB)

总计:25 MB与106 MB - 这只是一个单一的表!

还有一些值得思考的东西 - 金伯利特里普的优秀作品 - 读它,再读一遍,消化它!这真是SQL Server索引福音书。

马克

[GUID VS INT IDENTITY(的