了解SQL Server中的GUID数据类型

GUID是SQL Server中一种16字节的全局唯一标识符,用于在表、数据库和服务器间创建唯一的主键。NEWID()函数用于生成GUID。当在不同数据库中存在冗余记录时,使用GUID可以避免主键冲突。通过将INT主键替换为UNIQUEIDENTIFIER,可以实现跨数据库的记录唯一性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是GUID? (What is a GUID?)

GUID is a 16 byte binary SQL Server data type that is globally unique across tables, databases, and servers. The term GUID stands for Globally Unique Identifier and it is used interchangeably with UNIQUEIDENTIFIER.

GUID是16字节的二进制SQL Server数据类型,在表,数据库和服务器之间全局唯一。 GUID代表全局唯一标识符,可与UNIQUEIDENTIFIER互换使用。

To create a GUID in SQL Server, the NEWID() function is used as shown below:

要在SQL Server中创建GUID,将使用NEWID()函数,如下所示:

SELECT NEWID()

Execute the above line of SQL multiple times and you will see a different value every time. This is because the NEWID() function generates a unique value whenever you execute it.

多次执行上面SQL行,您每次都会看到一个不同的值。 这是因为NEWID()函数每执行一次都会生成一个唯一值。

To declare a variable of type GUID, the keyword used is UNIQUEIDENTIFIER as mentioned in the script below:

要声明类型为GUID的变量,使用的关键字是UNIQUEIDENTIFIER,如以下脚本中所述:

DECLARE @UNI UNIQUEIDENTIFIER
SET @UNI = NEWID()
 
SELECT @UNI

As mentioned earlier, GUID values are unique across tables, databases, and servers. GUIDs can be considered as global primary keys. Local primary keys are used to uniquely identify records within a table. On the other hand, GUIDs can be used to uniquely identify records across tables, databases, and servers.

如前所述,GUID值在表,数据库和服务器之间是唯一的。 GUID可以视为全局主键。 本地主键用于唯一标识表中的记录。 另一方面,GUID可用于唯一地标识跨表,数据库和服务器的记录。

问题GUID解决了 (The Problem GUID Solves)

Let’s see what issues we face if we have redundant records within tables across different databases and how GUID solves these issues.

让我们看看如果我们在不同数据库的表中有冗余记录会遇到什么问题,以及GUID如何解决这些问题。

Execute the following script.

执行以下脚本。

CREATE DATABASE EngDB
GO
 
USE EngDB
GO
 
CREATE TABLE EnglishStudents
(
	Id INT PRIMARY KEY IDENTITY,
	StudentName VARCHAR (50)
 
)
GO
 
INSERT INTO EnglishStudents VALUES ('Shane')
INSERT INTO EnglishStudents VALUES ('Jonny')

In the script above, we create a database named “EngDB”. We then create a table “EnglishStudents” within this database. The table has two columns: Id and StudentName. The Id column is the primary key column and we set it to auto increment using Identity as the constraint. Finally, we insert two records for students called ‘Shane’ and ‘Jonny’ into the “EnglishStudents” table.

在上面的脚本中,我们创建一个名为“ EngDB”的数据库。 然后,我们在此数据库中创建一个表“ EnglishStudents”。 该表有两列:Id和StudentName。 Id列是主键列,我们使用Identity作为约束将其设置为自动递增。 最后,我们将两个名为“ Shane”和“ Jonny”的学生记录插入“ EnglishStudents”表中。

Now if you select all the records from the “EnglishStudents” table, you should see the following output:

现在,如果您从“ EnglishStudents”表中选择所有记录,您将看到以下输出:

Id StudentName
1 Shane
2 Jonny
ID 学生姓名
1个 谢恩
2 强尼

Now, let’s create another database “MathDB”, create a table “MathStudents” in the DB and insert some records into the table. Execute the following script to do so.

现在,让我们创建另一个数据库“ MathDB”,在数据库中创建表“ MathStudents”,并将一些记录插入表中。 执行以下脚本。

CREATE DATABASE MathDB
GO
 
USE MathDB
GO
 
CREATE TABLE MathStudents
(
	Id INT PRIMARY KEY IDENTITY,
	StudentName VARCHAR (50)
 
)
GO
 
INSERT INTO MathStudents VALUES ('Sally')
INSERT INTO MathStudents VALUES ('Edward')

The MathStudents table of the MathDB should have the following records.

MathDB的MathStudents表应具有以下记录。

Id StudentName
1 Sally
2 Edward
ID 学生姓名
1个 莎莉
2 爱德华

Now if you select all the records from the EnglishStudents table of the EngDB and MathStudents table of the MathDB, you will see that records from both tables will have the same values for the primary key columns Id. Execute the following script to see this result:

现在,如果您从EngDB的EnglishStudents表和MathDB的MathStudents表中选择所有记录,您将看到两个表中的记录将具有相同的主键列ID值。 执行以下脚本以查看此结果:

SELECT * FROM EngDB.dbo.EnglishStudents
SELECT * FROM MathDB.dbo.MathStudents

You will see the following output in SQL Server Management Studio

您将在SQL Server Management Studio中看到以下输出

The student records from different tables that exist in two different databases have the same value for the Id column. This is the default behavior of SQL Server.

来自两个不同数据库中不同表的学生记录的Id列具有相同的值。 这是SQL Server的默认行为。

Now let’s create a new table “Student” that contains the union of all the records from the MathStudents table and EnglishStudents table. Execute the following script:

现在,我们创建一个新表“ Student”,其中包含MathStudents表和EnglishStudents表中所有记录的并集。 执行以下脚本:

USE EngDB
GO
 
CREATE TABLE Students
(
	Id INT PRIMARY KEY,
	StudentName NVARCHAR (50)
)
GO
 
INSERT INTO Students
SELECT * FROM EngDB.dbo.EnglishStudents
UNION ALL
SELECT * FROM MathDB.dbo.MathStudents

In the above script, we create a new table “Students” in the EngDB. This table contains Id and StudentName columns.

在上面的脚本中,我们在EngDB中创建一个新表“ Students”。 该表包含Id和StudentName列。

If you try to run the above script, you will see an error:

如果尝试运行上述脚本,则会看到错误:

This error is due to both the MathStudents and EnglishStudents table having the same values for the Id column which is also the primary key column for the newly created Students table. Therefore, when we try to insert the union of the records from MathStudents and EnglishStudents tables, the “Violation of PRIMARY KEY constraint” error occurs. Execute the following script to see what we are actually trying to insert in the Students table.

此错误是由于MathStudents和EnglishStudents表的Id列(也是新创建的Students表的主键列)具有相同的值。 因此,当我们尝试从MathStudents和EnglishStudents表中插入记录的并集时,会发生“违反PRIMARY KEY约束”错误。 执行以下脚本,以查看我们实际尝试在“学生”表中插入的内容。

SELECT * FROM EngDB.dbo.EnglishStudents
UNION ALL
SELECT * FROM MathDB.dbo.MathStudents

However, what if we want records to have unique values across multiple databases? For instance, we want that the Id column of the EnglishStudents table and the MathStudents table to have unique values, even if they belong to different databases. This is when we need to use the GUID data type.

但是,如果我们希望记录在多个数据库中具有唯一值怎么办? 例如,我们希望EnglishStudents表和MathStudents表的Id列具有唯一的值,即使它们属于不同的数据库也是如此。 这是我们需要使用GUID数据类型的时候。

You can see that students Shane and Sally both have Ids of 1 while Jonny and Edward both have Ids of 2. This causes the violation of primary key constraint for the Students table.

您会看到学生Shane和Sally的ID均为1,而Jonny和Edward的ID均为2。这导致违反了Student表的主键约束。

GUID解决方案 (Solution with GUID)

Now, let’s see how GUID can be used to solve this issue

现在,让我们看看如何使用GUID解决此问题

Let’s create a table EngStudents1 within the EngDB but this time we change the data type of the Id column from INT to UNIQUEIDENTIFIER. To set a default value for the column we will use the default keyword and set the default value as the value returned by the ‘NEWID()’ function.

让我们在EngDB中创建一个表EngStudents1,但是这次我们将Id列的数据类型从INT更改为UNIQUEIDENTIFIER。 要为该列设置默认值,我们将使用default关键字,并将默认值设置为'NEWID()'函数返回的值。

This will ensure that whenever a new record is inserted in the EngStudents1 table, by default, the NEWID() function generates a unique value for the Id column. When inserting the records, we simply have to specify “default” as value for the first column. This will insert a default unique value to the Id column. Execute the following script to create EngStudents1 table:

这将确保每当在EngStudents1表中插入新记录时,默认情况下,NEWID()函数都会为Id列生成唯一值。 插入记录时,我们只需指定“默认”作为第一列的值。 这会将默认唯一值插入Id列。 执行以下脚本来创建EngStudents1表:

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')

Now if you select all the records from EnglishStudents1 table, you will a result that looks like this:

现在,如果您从EnglishStudents1表中选择所有记录,则结果将如下所示:

Id StudentName
4B900A74-E2D9-4837-B9A4-9E828752716E Jonny
AEDC617C-D035-4213-B55A-DAE5CDFCA366 Shane
ID 学生姓名
4B900A74-E2D9-4837-B9A4-9E828752716E 强尼
AEDC617C-D035-4213-B55A-DAE5CDFCA366 谢恩

Note: Your values for the Id column will be different from the ones shown in the above table, because they are generated randomly on the fly. However, they should be globally unique.

注意: “ Id”列的值将不同于上表中显示的值,因为它们是即时生成的。 但是,它们应该是全局唯一的。

In the same way, create another table MathStudents1 in the MathDB database. Execute the following script:

以相同的方式,在MathDB数据库中创建另一个表MathStudents1。 执行以下脚本:

USE MathDB
GO
 
CREATE TABLE MathStudents1
(
	Id UNIQUEIDENTIFIER PRIMARY KEY default NEWID(),
	StudentName VARCHAR (50)
 
)
GO
 
INSERT INTO MathStudents1 VALUES (default,'Sally')
INSERT INTO MathStudents1 VALUES (default,'Edward')

Again if you try to retrieve all the records from the MathStudents1 table of the MathDB database, you will see results similar to the one below:

再次,如果您尝试从MathDB数据库的MathStudents1表中检索所有记录,您将看到类似于以下结果:

Id StudentName
69121893-3AFC-4F92-85F3-40BB5E7C7E29 Sally
CB77CCE6-C2CB-471B-BDD4-5DAC8C93B756 Edward
ID 学生姓名
69121893-3AFC-4F92-85F3-40BB5E7C7E29 莎莉
CB77CCE6-C2CB-471B-BDD4-5DAC8C93B756 爱德华

Now we have globally unique values in the Id columns of both the EnglishStudents1 and MathStudents1 table. Let’s create a new Table named Student1s and just as we did before, try to insert the union of the records from EnglishStudents1 and MathStudents1. This time we will see that there will be no “Violation of PRIMARY KEY constraint” error, since the values in the Id column of both EnglishStudents1 and MathStudents1 are unique across both the EngDB and MathDB databases.

现在,我们在EnglishStudents1和MathStudents1表的Id列中具有全局唯一值。 让我们创建一个名为Student1s的新表,就像以前一样,尝试插入EnglishStudents1和MathStudents1中记录的并集。 这次,我们将看到不会出现“违反PRIMARY KEY约束”错误,因为EnglishStudents1和MathStudents1的Id列中的值在EngDB和MathDB数据库中都是唯一的。

USE EngDB
GO
 
CREATE TABLE Students1
(
	Id UNIQUEIDENTIFIER PRIMARY KEY,
	StudentName NVARCHAR (50)
)
GO
 
INSERT INTO Students1
SELECT * FROM EngDB.dbo.EnglishStudents1
UNION ALL
SELECT * FROM MathDB.dbo.MathStudents1

You can see in the above script that the type of the Id column is UNIQUEIDENTIFIER. Run the above script and then try to retrieve all the records from the Students1 table and you should see results similar to the following:

您可以在上面的脚本中看到,Id列的类型为UNIQUEIDENTIFIER。 运行上面的脚本,然后尝试从Students1表中检索所有记录,您应该看到与以下内容类似的结果:

Id StudentName
69121893-3AFC-4F92-85F3-40BB5E7C7E29 Sally
CB77CCE6-C2CB-471B-BDD4-5DAC8C93B756 Edward
4B900A74-E2D9-4837-B9A4-9E828752716E Jonny
AEDC617C-D035-4213-B55A-DAE5CDFCA366 Shane
ID 学生姓名
69121893-3AFC-4F92-85F3-40BB5E7C7E29 莎莉
CB77CCE6-C2CB-471B-BDD4-5DAC8C93B756 爱德华
4B900A74-E2D9-4837-B9A4-9E828752716E 强尼
AEDC617C-D035-4213-B55A-DAE5CDFCA366 谢恩

You can see that using GUID, we are able to insert a union of records from two different databases into a new table without any “Violation of PRIMARY KEY constraint” error.

您可以看到,使用GUID,我们可以将两个不同数据库中的记录并集插入到新表中,而不会出现“违反PRIMARY KEY约束”错误。

参考资料 (References)

本的其他精彩文章 (Other great articles from Ben)

Difference between Identity & Sequence in SQL Server
What is the difference between Clustered and Non-Clustered Indexes in SQL Server?
Understanding the GUID data type in SQL Server
SQL Server中身份和序列之间的区别
SQL Server中的聚集索引和非聚集索引有什么区别?
了解SQL Server中的GUID数据类型

翻译自: https://www.sqlshack.com/understanding-the-guid-data-type-in-sql-server/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值