我最近开始了一项新工作,发现所有SQL表都使用GUID数据类型作为主键。
在我以前的工作中,我们使用整数(自动增量)作为主键,在我看来,它更容易使用。
例如,假设您有两个相关的表格; Product和ProductType - 我可以轻松地交叉检查特定行的两个表的'ProductTypeID'列,以快速映射我脑中的数据,因为它易于存储数字(2,4,45等),而不是(E75B92A3- 3299-4407-A913-C5CA196B3CAB)。
额外的挫折感来自于我想要理解表格是如何相关的,遗憾的是没有数据库图表:(
很多人说GUID是更好的,因为您可以在C#代码中定义唯一标识符,例如使用NewID()而不需要SQL SERVER来执行此操作 - 这也允许您临时知道ID将是什么。 ...但我已经看到,仍然可以检索'下一个自动递增的整数'。
DBA承包商报告说,如果我们使用Integer类型而不是GUIDS,我们的查询速度可提高30%......
为什么GUID数据类型存在,它真正提供了哪些优势?...即使是某些专业人士的选择,必须有一些很好的理由来解释为什么要实现它?
答案 0 :(得分:17)
GUID在某些情况下作为标识字段很好:
生成的GUID是全局唯一的,这就是它们适合这种情况的原因。
答案 1 :(得分:14)
与大多数人似乎在宣讲的相反,我认为GUID更像是一场瘟疫,而不是一种祝福。原因如下:
GUID似乎是您主键的自然选择 - 如果您真的必须,您可能会争辩将其用于表的PRIMARY KEY。我强烈建议不要使用GUID列作为群集密钥,默认情况下SQL Server会执行此操作,除非您明确告知不要。
你真的需要分开两个问题:
主键是一个逻辑结构 - 唯一且可靠地标识表中每一行的候选键之一。这可以是任何东西,真的 - 一个INT,一个GUID,一个字符串 - 选择对你的场景最有意义的东西。
群集密钥(在表上定义“聚簇索引”的一列或多列) - 这是与物理存储相关的东西,并且在这里,一个小的,稳定的,不断增加的数据类型是你最好的选择 - INT或BIGINT作为你的默认选项。
默认情况下,SQL Server表上的主键也用作群集键 - 但这不一定是这样!我个人看到将以前基于GUID的主/群集密钥分解为两个单独的密钥 - GUID上的主(逻辑)密钥和单独的INT IDENTITY上的群集(排序)密钥(1, 1)专栏。
作为Kimberly Tripp - 索引女王 - 以及其他人已多次声明 - GUID作为聚类键不是最佳的,因为由于其随机性,它将导致大量页面和索引碎片并且通常表现不佳。
是的,我知道 - 在SQL Server 2005及更高版本中有newsequentialid()
- 但即使这样也不是真正完全顺序的,因此也会遇到与GUID相同的问题 - 只是不那么突出。另外,您只能将它用作表中列的默认值 - 您无法在T-SQL代码中获得新的顺序GUID(如触发器或其他内容) - 另一个主要缺点。
然后还有另一个需要考虑的问题:表格上的聚类键也会被添加到表格中每个非聚集索引的每个条目上 - 因此你真的想确保它尽可能小。通常,对于绝大多数表来说,具有2亿行的INT应该足够 - 并且与作为群集密钥的GUID相比,您可以在磁盘和服务器内存中节省数百兆的存储空间。
快速计算 - 使用INT与GUID作为主要和群集密钥:
TOTAL:25 MB vs. 106 MB - 这只是在一张桌子上!
更多值得思考的东西 - 金佰利特里普的优秀作品 - 阅读,再读一遍,消化它!这是SQL Server索引福音,真的。
马克
答案 2 :(得分:6)
<强> INT 强>
优势:
在连接,索引和条件中使用时,数值(特别是整数)更适合性能。 如果显示应用程序用户,则数字值更易于理解。
缺点:
如果您的表很大,很可能会耗尽它,并且在某些数值之后将没有其他标识可供使用。
<强> GUID 强>
优势:
整个服务器都是唯一的。
缺点:
在联接,索引和条件中使用时,字符串值不如性能的整数值那么优化。 需要比INT更多的存储空间。
信用额度为:http://blog.sqlauthority.com/2010/04/28/sql-server-guid-vs-int-your-opinion/
答案 3 :(得分:3)
有很多关于使用GUID作为PK的谷歌文章,几乎所有人都说你的DBA承包商说同样的事情 - 如果没有GUID作为密钥,查询会更快。
我在实践中看到的主要用途(我们从未将它们用作PK)是复制。 uniqueidentifier的MSDN页面大致相同。
答案 4 :(得分:2)
它是全局唯一的,因此表中的每条记录都有一个GUID,世界上没有任何其他项目共享。如果您需要这种独占标识(如果您正在复制数据库,或组合来自多个源的数据),则很方便。否则,你的dba是正确的 - GUID比整数更大,效率更低,你可以加速你的数据库(30%?也许......)
答案 5 :(得分:0)
它们基本上可以帮助您避免使用
更复杂的逻辑set @InsertID = scope_identity()