使用 GUID 作为外键可以吗?

zer*_*law 6 foreign-key sql-server uuid

这是我目前的情况:

我们有一个表格存储从网站表单提交的数据,比如“MyTable”。该表使用 bigint(自动增量)作为主键。到目前为止一切都很好。

现在,该表需要能够存储从移动设备上传的记录。但从手机上传的记录要先经过验证,然后才能存储到“MyTable”中。因此,创建了一个临时表,比如“Temp_MyTable”。

换句话说,这是流程:

移动设备 ------> 临时表 ------> 实际表

                    [GUID as PK]         [bigint as PK], [GUID as FK]
Run Code Online (Sandbox Code Playgroud)

问题是,临时表使用 GUID 作为主键。原因,我们必须引用从多个设备上传的记录。用户修改后可重新上传记录。注意:这里的 GUID 是由移动端生成的(简单的 javascript)。

所以,现在,我想将 Actual Table 的记录引用回 Staging Table。在这种情况下,“可能”需要外键。不幸的是,它是 GUID 数据类型。

而且看了多篇文章,似乎使用GUID作为外键可能是不利的——存储更多或更慢。

我想知道,使用 GUID 作为外键可以吗?有人可以证明它实际上“非常好”吗?或者有更好的设计吗?

Dav*_*ett 6

使用 UUID 列作为外键很好,如果这是推荐/要求的父记录上唯一的候选键。FK 必须引用在引用表中唯一的值,这通常意味着主键,尽管通过约束或索引定义为唯一的任何列(或列组合)都可以。有些人建议它也应该总是填充的(即定义为不可为空的),否则 FK 并非可以引用所引用表中的所有行,尽管有很多例子表明这是不正确的。

如果引用表上的主键是 uniqueidentifier 列,那么除非该表中有另一个唯一值,否则应将其用作外键目标

人们可能建议不要将 UUID 用作外键的唯一真正原因是空间:此类值需要 16 个字节来存储,而不是 4 个(假设替代方案是 32 位整数)或 8 个(对于 bigint)。

有反对使用 UUID 作为主键的论据(尽管也有同样有效的论据!),尤其是如果您的 PK 也是您的聚集键(即表的聚集索引中的唯一成员或重要成员,如果有的话),但这是一个不同的讨论。