Navicat 博客

选择主键 - 第 3 部分 2022 年 9 月 14 日,由 Robert Gravelle 撰写

使用字符串作为主键

在本系列关于为关系数据库选择主键的第三部分也是最后一部分中,我们将研究使用字符串数据作为主键(PK)的一些原因。回想一下,在第 1 部分,我们讨论了自然主键和代理主键,并考虑了什么因素决定选择哪一种。而第 2 部分探讨了字符串和数值数据类型,看看哪种更适合作为主键。现在是时候澄清事实并得出结论,字符串或字母数据是否合适的主键。

现成的主键

你的数据通常都会有一个合理的自然主键,它有通用含义,并且可能不是整数。如果是这样,那么仅仅为了要整数类型的主键而添加人工键只会增加冗余。在许多数据库开发人员的估计中,性能可能会受到轻微影响,但它的重要性略低于正确性、完整性和适当的建模。

字母键的一个不明显的好处是,简短的符号字符串可以简化调试,因为在数据转储(无需额外的联接)时人们能立即看得懂。例如,美国各州有一个唯一的字母代码,可作为有意义的键。此外,各个国家或地区有自己的字母 ISO 代码。还有无数其他例子,例如车辆 VIN 号码、发票 ID 等。

使用 GUID 作为主键

如果你有多个数据库,自动递增键可能会导致冗余记录。解决此问题的其中一种方法是使用 GUID。GUID是 “Globally Unique IDentifier”的缩写,它是一个 16 字节的二进制数据类型,保证在表、数据库甚至服务器之间是唯一的。

创建 GUID 的方式因不同的数据库而异,但在 SQL Server 中,NEWID() 函数的使用如下所示:

SELECT NEWID()

以下是用于创建具有 UNIQUEIDENTIFIER 数据类型的表的语句。若要为列设置默认值,我们可以使用 default 关键字并将默认值设置为 NEWID() 函数返回的值:

USE EngDB
GO
 
CREATE TABLE EnglishStudents1
(
	Id UNIQUEIDENTIFIER PRIMARY KEY default NEWID(),
	StudentName VARCHAR (50)
 
)
GO
 
INSERT INTO EnglishStudents1 VALUES (default,'Shane')
INSERT INTO EnglishStudents1 VALUES (default,'Jonny')

这能确保每当在 EngStudents1 表中插入新记录时,默认情况下,NEWID() 函数都会为 Id 列生成唯一值。在插入记录时,我们只需将“default”指定为第一列的值。这将在 Id 列中插入一个默认的唯一值。

GUIDs vs. UUIDs

虽然 GUID(由 Microsoft 使用)和 UUID(由 RFC4122 定义)看起来相似并且有相似的用途,但也存在细微但非常重要的差异。首先,让我们看看什么是 UUID。

必须重申,UUID 是 128 位的值,以十六进制数字表示。因为许多人认为 UUID 是以文本形式存储。而 UUIDv4 值是随机的,无法保证唯一性。但是,发生冲突的可能性很小。此外,请记住,在极不可能发生 UUID 冲突的情况下,由于主键约束,它会被数据库捕获。而且,值得高兴的是 UUIDv4 已被大多数关系数据库完整地进行索引。

一些 Microsoft GUID 文档允许 GUID 在任何位置含有任何十六进制数字,而 RFC4122 需要为版本和变体字段指定值。此外,GUID 应该全部大写,而 UUID 应该“输出为小写字符并且在输入时不区分大小写”。这可能导致代码库之间的不兼容。

您可以说 GUID 是 Microsoft 对 UUID 标准的实现。将它们视为用作唯一值的 16 字节(128 位)值。在 Microsoft 中,它们被称为 GUID,但在其他地方,它们被称为 UUID。

结论

在本系列关于为关系数据库选择主键的第三部分也是最后一部分中,我们得出字符串或字母数据是否可以进行合适的主键的结论。答案是肯定的,但有一些需要注意的地方。你应该预料到性能会受到轻微的影响。如果这不是你考虑的因素,那么可以选择使用短符号字符串、GUIDS 和 UUID。最后,请尽量使用固定长度的字符串而不是 varchar,因为固定长度的字符串在执行方面更好。

Navicat 文章
频道条目
分享
文章归档