在高可用性,主动 - 主动环境中使用UNIQUE IDENTIFIERS作为PRIMARY KEY

时间:2016-07-08 21:10:27

标签: sql sql-server

我们公司正在将数据库迁移到高可用性,主动 - 主动(HA / AA)环境。我们选择的中间件工具使得在实例之间迁移Identity列非常痛苦。因此,我和其他人想要使用uniqueidentifiers(即Guid' s)作为所有新表的主键。

注意事项:

  • 有些表格会很浅
  • 其他表格会变得非常大(随着时间的推移)
  • 许多旧表已包含数百万条记录

建议的解决方案:

使用顺序uniqueidentifier作为表的主键

关注:

使用uniqueidentifier作为表的主键,有数百万条记录的效果。

问题:一般情况下,uniqueidentifier在这些情况下表现得如何?

更新

按主键我的意思是代理。

2 个答案:

答案 0 :(得分:6)

GUID似乎是您主键的自然选择 - 如果您真的必须,您可能会争辩将其用于表的PRIMARY KEY。我强烈建议不要使用GUID列作为群集密钥,默认情况下SQL Server会执行此操作,除非您明确说明它没有。

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

  1. 主键是一个逻辑结构 - 唯一且可靠地标识表中每一行的候选键之一。这可以是任何事情,真的 - INTGUID,字符串 - 选择对您的方案最有意义的内容。

  2. 群集密钥(定义"聚簇索引"在表中的一列或多列) - 这是物理存储相关的事情,在这里,一个小的,稳定的,不断增加的数据类型是您的最佳选择 - INTBIGINT作为您的默认选项。

  3. 默认情况下,SQL Server表上的主键也用作群集键 - 但这不是必须的!我将以前基于GUID的主/密钥分解为两个单独的密钥 - GUID上的主(逻辑)密钥和集群(排序)密钥时,个人看到了巨大的性能提升。单独的INT IDENTITY(1,1)列。

    作为Kimberly Tripp - 索引女王 - 以及其他人已多次声明 - GUID作为群集密钥并非最佳,因为对于它的随机性,它将导致大量的页面和索引碎片以及通常不良的性能。

    是的,我知道 - 在SQL Server 2005及更高版本中有newsequentialid() - 但即使这样也不是真正完全顺序的,因此也遇到与GUID相同的问题 - 只是有点不那么突出。

    然后还有另外一个需要考虑的问题:表格上的聚类键也会添加到表格中每个非聚集索引的每个条目上 - 因此你真的想确保它和#39; s尽可能小。通常,对于绝大多数表来说,具有2亿行的INT应该足够 - 并且与作为群集密钥的GUID相比,您可以在磁盘上保存数百兆字节的存储空间。服务器内存。

    快速计算 - 使用INTGUID作为主要和群集密钥:

    • 基本表,1' 000' 000行(3.8 MB对15.26 MB)
    • 6个非聚簇索引(22.89 MB vs. 91.55 MB)

    TOTAL:25 MB vs. 106 MB - 这只是在一张桌子上!

    更多值得思考的东西 - 金佰利特里普的优秀作品 - 阅读,再读一遍,消化它!它确实是SQL Server索引福音书。

答案 1 :(得分:1)

在此处阅读GUIDs与INT辩论https://blogs.msdn.microsoft.com/sqlserverfaq/2010/05/27/guid-vs-int-debate/

Seq GUID并没有像许多人想到的那样比INT / BIGINT差。当问题是数据的合并时,它比BIGINT有优势,因为问题更多。 Seq GUID也有一个稳定的碎片,并且对BIGINT的性能略有下降。

注意:当节点之间发生意外切换时,Identnity数据类型会出现一些问题。 http://sqlblog.com/blogs/kalen_delaney/archive/2014/06/17/lost-identity.aspx 我个人经历过在这样的环境(AlwaysOn)上使用trace flat -t272的必要性,导致ID存在差距。有时,业务逻辑可以与身份密钥相关。

所以这个问题变得像辩论一样。 但是,它取消了!