从int移到GUID作为主键

时间:2020-03-06 14:46:14  来源:igfitidea点击:

我将几个引用的表与整数主键一起使用。现在,我想将int更改为GUID,保留所有引用不变。最简单的方法是什么?

谢谢!

添加

我确实了解该过程,所以我需要更详细的建议,例如,如何填充新的GUID列。使用默认值newid()是正确的,但是对于已经存在的行呢?

解决方案

首先:亲爱的上帝,为什么?!?!?

其次,我们将必须首先将GUID列添加到所有表,然后根据int值填充它们。完成后,我们可以将GUID设置为主键/外键,然后删除int列。

要更新值,我们可以执行以下操作

  • 在主键表中设置新的GUID
  • 运行这个:

UPDATE foreignTable f
SET f.guidCol = p.guidCol
FROM primaryTable p
WHERE p.intCol = f.intCol

是的,我和Glenn在一起...实际上,我在发布相同内容之前一直在犹豫,...。

为什么不希望将自动增量int主键与GUID分开?它更加灵活,我们只需将GUID列编入索引,以便在查询中获得良好的性能...

至于灵活性,我喜欢将id保留为autoincrement int,因为这样其他看似唯一且具有主键的有价值的项就可以更改。

灵活性的一个很好的例子是,如果我们使用用户名作为主键。即使它们是唯一的,也能够更改它们是很好的。如果用户使用电子邮件地址作为用户名怎么办?能够更改用户名并且不影响所有查询是一个很大的优势,我怀疑GUID可能也是如此。

我认为,我们必须手动进行。或者,我们可以为其编写一些实用程序。该方案应为:

  • 将" int" PK / FK列与新的" guid"列重复。
  • 为"引导" PK列生成新值。
  • 用指定的值更新" guid" FK列中的值(我们可以通过" int" PK查找记录)。
  • 用" int"个PK / FK列删除引用(关系)。
  • 使用" guid" PK / FK列创建类似的引用(关系)。
  • 删除" int" PK / FK列。

  • 在主表中为guid值创建一个新列。使用uniqueidentifier数据类型,并使其不为null,默认值为newid(),以便将填充所有现有行。
  • 在子表中创建新的uniqueidentifier列。
  • 运行更新语句以使用exisitng int关系引用实体来建立公会关系。
  • 删除原始的int列。

另外,由于Guid不像int标识列那样连续,因此请在数据/索引页中保留一些空间(指定fillfactor <100)。这意味着插入内容可以在数据范围内的任何位置,并且如果页面100%充满,将导致页面拆分。

这在实现分布式计算模型的系统中是无关紧要的。如果在我们将信息保留在系统中时要求系统知道主键,则使用由ONE处理程序维护的自动递增主键会降低系统速度。相反,我们需要一种类似于GUID生成器的机制来创建主键(请注意,主键的真正特征是其唯一性)。因此,我可以扩展多个服务,每个服务彼此独立地创建其主键。

我之前曾有这样做的可疑特权,基本上我要做的就是将整个该死的数据库导出为XML。接下来,我有一个Java应用程序,该应用程序使用java.util.Random的nextLong()函数将主键替换为其新的guid键。之后,我将整个内容重新导入到数据库中。

当然,当我第一次尝试将XML文件导入回来时,我忘记了关闭主键字段的自动编号功能,因此请从我的错误中吸取教训。我敢肯定,有更好的方法可以做到这一点,但这是一种快速而肮脏的方法……而且行之有效。如果我们想知道,该项目将扩大应用程序规模。

有趣的是,由于另一个问题,我需要做相反的事情……

如何在具有GUID主键和默认newsequentialid()的表上使用SQLBulkCopy?

这是一个很好的选择。对于我的一种应用程序,我从longs切换到UUID,我并不后悔。如果我们使用MS SQL Server,则它包含在标准中(我使用的是postgresql,它仅包含在8.3及更高版本的标准中)。

就像Glenn Slaven提到的那样,我们可以根据当前记录中的键来重新创建UUID。请注意,虽然它们并不是唯一的,但是这样可以很容易地保持关系的完整性。我们在移动后创建的新记录将是唯一的。

不要做!我们开始使用GUID,现在几乎完成了将INT转换为PK的工作。我们保留了GUID以便进行日志记录(以及某些表,例如"可协商的关系完整性";)),但是使用int的速度显着提高。

请注意,只有当表的行数达到数百万时,这才真正变得明显。

到目前为止,我们最大的愚蠢是使用NEWID()作为我们(顺序)日志表的PK,当我们意识到自己的错误时,头晕目眩。