一、什么是GUID

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

二、GUID的使用

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

SELECT NEWID()

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

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

DECLARE @UNI UNIQUEIDENTIFIER

SET @UNI = NEWID()

SELECT @UNI

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

三、GUID解决了什么问题

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

执行以下脚本:

CREATE DATABASE EngDB

GO

USE EngDB

GO

CREATE TABLE EnglishStudents

(

Id INT PRIMARY KEY IDENTITY,

StudentName VARCHAR (50)

)

GO

INSERT INTO EnglishStudents VALUES ('谢恩')

INSERT INTO EnglishStudents VALUES ('强尼')

在上面的脚本中,我们创建一个名为“ EngDB”的数据库。

然后,我们在此数据库中创建一个表“ EnglishStudents”。

该表有两列:Id和StudentName。 Id列是主键列,我们使用Identity作为约束将其设置为自动递增。

最后,我们将两个名为“ Shane”和“ Jonny”的学生记录插入“ EnglishStudents”表中。

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

 现在,让我们创建另一个数据库“ 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 ('莎莉')

INSERT INTO MathStudents VALUES ('爱德华')

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

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

SELECT * FROM EngDB.dbo.EnglishStudents

SELECT * FROM MathDB.dbo.MathStudents

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

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

现在,我们创建一个新表“ 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

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

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

此错误是由于MathStudents和EnglishStudents表的Id列(也是新创建的Students表的主键列)具有相同的值。

因此,当我们尝试从MathStudents和EnglishStudents表中插入记录的并集时,会发生“违反PRIMARY KEY约束”错误。 执行以下脚本,以查看我们实际尝试在“学生”表中插入的内容。

SELECT * FROM EngDB.dbo.EnglishStudents

UNION ALL

SELECT * FROM MathDB.dbo.MathStudents

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

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

四、GUID解决方案

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

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

这将确保每当在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,'强尼')

INSERT INTO EnglishStudents1 VALUES (default,'谢恩')

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

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

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

USE MathDB

GO

CREATE TABLE MathStudents1

(

Id UNIQUEIDENTIFIER PRIMARY KEY default NEWID(),

StudentName VARCHAR (50)

)

GO

INSERT INTO MathStudents1 VALUES (default,'莎莉')

INSERT INTO MathStudents1 VALUES (default,'爱德华')

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

 现在,我们在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

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

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

作者有话说

该文档希望能解决你的问题,不能解决你的问题的话,请问“度娘”,走上编程这条路,“度娘”永远是你的法宝。

有些废话的东西你懂的话,完全可以不看;我其实也不喜欢理论上的知识;看看也是涨涨见识,可以在面试的时候,装那什么。

当然很多的理论知识也是借鉴了各位大神的,或者去官网找的。如有冒犯,还请见谅。

坚持日拱一卒、相信复利效应、不断践行践修,让我们活在成长中

查看原文