Guid主要/外键困境SQL Server

时间:2010-06-08 09:12:38

标签: sql database-design guid

我面临着将主键从int身份更改为Guid的困境。我会直接提出问题。这是一个典型的零售管理应用程序,具有POS和后台功能。有大约100张桌子。数据库与其他数据库同步并接收/发送新数据。

大多数表没有频繁的插入,更新或在其上执行的select语句。但是,有些人经常插入并选择它们,例如。产品和订单表。

有些表中最多包含4个外键。如果我将主键从“int”更改为“Guid”,那么在插入或查询具有许多外键的表中的数据时是否会出现性能问题。我知道有人说索引会碎片化,16个字节是个问题。

在我的情况下,空间不会是一个问题,显然索引碎片也可以使用'NEWSEQUENTIALID()'函数。有人可以告诉我,根据经验,如果Guid在有许多外键的表格中会有问题。

我会非常感谢你对它的看法......

6 个答案:

答案 0 :(得分:25)

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相同的问题 - 只是不那么显着。< / p>

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

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

  • 具有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索引福音,真的。

因此,如果您确实必须将主键更改为GUID - 请尝试确保主键不是群集键,并且您在表上仍使用INT IDENTITY字段作为聚类键。否则,你的表现肯定是坦克并受到严重打击。

答案 1 :(得分:3)

使用guid over int的缺点:

在联接,索引和条件中使用时,字符串值不如性能的整数值那么优化。需要比INT更多的存储空间。

为了获得最佳性能,生成的GUID应该是部分顺序的(例如,SQL 2005上的newsequentialid())并且能够使用聚簇索引

了解更多详情:

http://www.codinghorror.com/blog/2007/03/primary-keys-ids-versus-guids.html

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

答案 2 :(得分:1)

我的看法是:在内部使用autoincrement int作为PK,并在每个主表上使用一个唯一的Guid列,用于在数据库之间移动行。

导出数据时加入此列,不导出int,并在导入数据时将其映射回int。

特别是在大批量中,int更小更快。

答案 3 :(得分:0)

对PK使用GUID或int实际上取决于场景。从INT到GUID将会有性能提升。 GUID比INT大4倍。关于使用GUID的优缺点,有一篇很好的文章here

为什么你还要改变整数?

答案 4 :(得分:0)

GUID确实会对整数产生性能影响,但这种影响可能会很小,具体取决于您的应用程序,因此没有测试就无法确定。我曾经将一个应用程序从int转换为GUID,其中包含一些非常大的表,其中包含许多外键,同时执行非常繁重的修改和查询(每天都有数十万条记录转换。)通过分析器运行时速度较慢但是,从用户的角度来看,没有明显的差异。

所以答案是“这取决于”。就像处理性能的所有事情一样,在你尝试之前你无法确定。

答案 5 :(得分:-1)

bence eğer benzersiz bir kod kullanmamız gerekli durumlarda kullanılabilir。 Ama performansa etkisinin göz önünde bulundurulmalıdır。 Identıty bir pk ve fk olarak kullanırken performans açısından daha iyidir。 Bu yüzden duruma bağlı olarak guid ya 聚集密钥 kullanımı yapabiliriz。