Sql 如何从整数值创建确定性uniqueidentifier(GUID)
注意:这与数据库设计无关,也与GUID的一般使用无关。这是关于在Microsoft SQL server上确定地为测试数据创建这样的GUID 我们正在将数据库从整数标识符迁移到uniqueidentifier数据类型 出于测试目的,我们希望将测试数据集迁移到已知的GUID值,这是基于我们以前的整数值确定的Sql 如何从整数值创建确定性uniqueidentifier(GUID),sql,sql-server,guid,Sql,Sql Server,Guid,注意:这与数据库设计无关,也与GUID的一般使用无关。这是关于在Microsoft SQL server上确定地为测试数据创建这样的GUID 我们正在将数据库从整数标识符迁移到uniqueidentifier数据类型 出于测试目的,我们希望将测试数据集迁移到已知的GUID值,这是基于我们以前的整数值确定的 显然,这并不能马上奏效。如何使用UnitId创建确定性GUID?您可以创建keymap表: CREATE TABLE tab_map(id_old INT PRIMARY KEY, guid
显然,这并不能马上奏效。如何使用UnitId创建确定性GUID?您可以创建keymap表:
CREATE TABLE tab_map(id_old INT PRIMARY KEY, guid UNIQUEIDENTIFIER);
INSERT INTO tab_map(id_old, guid)
SELECT id, NEWID()
FROM src_table;
之后,您可以使用简单的查询或包装功能:
SELECT guid
FROM tab_map
WHERE id_old = ?
您可以创建keymap表:
CREATE TABLE tab_map(id_old INT PRIMARY KEY, guid UNIQUEIDENTIFIER);
INSERT INTO tab_map(id_old, guid)
SELECT id, NEWID()
FROM src_table;
之后,您可以使用简单的查询或包装功能:
SELECT guid
FROM tab_map
WHERE id_old = ?
最后我自己解决了这个问题。以下是我的解决方案供将来参考: 我以deadbeef-0000-0000-0000-的形式创建GUID的前缀部分,然后将Id列整数值的字符串化、零填充版本附加到它,如000000000001,这将导致
DEADBEEF-0000-0000-0000-000000000001
在这个例子中
下面是整个表上此操作的SQL命令:
-- Deterministically creates a uniqueidentifier value out of an integer value.
DECLARE @GuidPrefix nvarchar(max) = N'deadbeef-0000-0000-0000-'; -- without the last 12 digits
UPDATE Unit
SET UniqueColumn =
(SELECT @GuidPrefix + RIGHT('000000000000' + CAST(IntegerId AS NVARCHAR (12)), 12 ) AS NUMBER_CONVERTED)
警告:
此实现仅适用于向上的正int值
至最大2147483647
这仅用于测试数据!用途是
强烈反对使用生产数据!
下面是一个完整的工作示例:
-- Create an example table with random GUID's
CREATE TABLE Unit
(
UniqueColumn UNIQUEIDENTIFIER DEFAULT NEWID(),
Characters VARCHAR(10),
IntegerId int
)
-- Add 2 data rows
INSERT INTO Unit(Characters, IntegerId) VALUES ('abc', 1111)
INSERT INTO Unit(Characters, IntegerId) VALUES ('def', 2222)
-- Deterministically creates a uniqueidentifier value out of an integer value.
DECLARE @GuidPrefix nvarchar(max) = N'deadbeef-0000-0000-0000-'; -- without the last 12 digits
UPDATE Unit
SET UniqueColumn =
(SELECT @GuidPrefix + RIGHT('000000000000' + CAST(IntegerId AS NVARCHAR (12)), 12 ) AS NUMBER_CONVERTED)
-- Check the result
SELECT * FROM Unit
结果:
UniqueColumn Characters IntegerId
--------------------------------------- ---------- ---------
DEADBEEF-0000-0000-0000-000000001111 abc 1111
DEADBEEF-0000-0000-0000-000000002222 def 2222
最后我自己解决了这个问题。以下是我的解决方案供将来参考: 我以deadbeef-0000-0000-0000-的形式创建GUID的前缀部分,然后将Id列整数值的字符串化、零填充版本附加到它,如000000000001,这将导致
DEADBEEF-0000-0000-0000-000000000001
在这个例子中
下面是整个表上此操作的SQL命令:
-- Deterministically creates a uniqueidentifier value out of an integer value.
DECLARE @GuidPrefix nvarchar(max) = N'deadbeef-0000-0000-0000-'; -- without the last 12 digits
UPDATE Unit
SET UniqueColumn =
(SELECT @GuidPrefix + RIGHT('000000000000' + CAST(IntegerId AS NVARCHAR (12)), 12 ) AS NUMBER_CONVERTED)
警告:
此实现仅适用于向上的正int值
至最大2147483647
这仅用于测试数据!用途是
强烈反对使用生产数据!
下面是一个完整的工作示例:
-- Create an example table with random GUID's
CREATE TABLE Unit
(
UniqueColumn UNIQUEIDENTIFIER DEFAULT NEWID(),
Characters VARCHAR(10),
IntegerId int
)
-- Add 2 data rows
INSERT INTO Unit(Characters, IntegerId) VALUES ('abc', 1111)
INSERT INTO Unit(Characters, IntegerId) VALUES ('def', 2222)
-- Deterministically creates a uniqueidentifier value out of an integer value.
DECLARE @GuidPrefix nvarchar(max) = N'deadbeef-0000-0000-0000-'; -- without the last 12 digits
UPDATE Unit
SET UniqueColumn =
(SELECT @GuidPrefix + RIGHT('000000000000' + CAST(IntegerId AS NVARCHAR (12)), 12 ) AS NUMBER_CONVERTED)
-- Check the result
SELECT * FROM Unit
结果:
UniqueColumn Characters IntegerId
--------------------------------------- ---------- ---------
DEADBEEF-0000-0000-0000-000000001111 abc 1111
DEADBEEF-0000-0000-0000-000000002222 def 2222
不要从一个角度思考这个问题。整数由4个字节组成。唯一标识符由16个字节组成。您可以轻松地获取12个固定字节,并将int中的4个字节附加到这些字节的末尾,从而获得适用于所有int值的解决方案: 结果:
UniqueColumn Characters IntegerId
------------------------------------ ---------- -----------
DEADBEEF-0000-0000-0000-000000000457 abc 1111
DEADBEEF-0000-0000-0000-0000000008AE def 2222
DEADBEEF-0000-0000-0000-0000FFFFFFEF ghi -17
出于各种原因,我们必须以不同的顺序提供前四个字节,而不是在将uniqueidentifier显示为字符串时默认使用的顺序,这就是为什么如果我们要显示死角,我们必须以EFbeade启动二进制文件的原因
当然,还要插入一些常见的警告,即如果您正在创建guid/uniqueidentifiers,但没有使用其中一种指定的方法来生成它们,那么您就不能假设任何关于唯一性的常见保证。停止从一个角度思考这个问题。整数由4个字节组成。唯一标识符由16个字节组成。您可以轻松地获取12个固定字节,并将int中的4个字节附加到这些字节的末尾,从而获得适用于所有int值的解决方案: 结果:
UniqueColumn Characters IntegerId
------------------------------------ ---------- -----------
DEADBEEF-0000-0000-0000-000000000457 abc 1111
DEADBEEF-0000-0000-0000-0000000008AE def 2222
DEADBEEF-0000-0000-0000-0000FFFFFFEF ghi -17
出于各种原因,我们必须以不同的顺序提供前四个字节,而不是在将uniqueidentifier显示为字符串时默认使用的顺序,这就是为什么如果我们要显示死角,我们必须以EFbeade启动二进制文件的原因
当然,还要插入一些常见的警告,即如果您正在创建GUID/UniqueIdentifier,但没有使用其中一种指定的方法来生成它们,那么就不能假设任何关于唯一性的常见保证。GUID不应该基于某个值创建。如果需要,可以基于该值生成哈希,但不要调用它。@Lucasz建议的映射表是在testenv和prod env上执行此操作的方法。执行此操作时要非常小心。如果这成为聚集索引,则会出现一些非常严重的性能问题。不应基于某个值创建GUID。如果需要,可以基于该值生成哈希,但不要调用它。@Lucasz建议的映射表是在testenv和prod env上执行此操作的方法。执行此操作时要非常小心。如果这成为聚集索引,则会出现一些非常严重的性能问题。虽然这有点帮助,但它忽略了我的要点——具有确定性GUID。请记住,这仅适用于测试数据,我想证明我的查询仍按预期工作。对于生产,我们将从全新的数据开始。虽然这有点帮助,但它忽略了我的要点——具有确定性GUID。请记住,这仅适用于测试数据,我想证明我的查询仍按预期工作。对于生产,我们将从全新的数据开始。这是一个很好的答案,我接受它。对我来说,在我的应用程序中,在GUID中使用逐字id值非常方便,我将实现我的解决方案。但同样,这仅用于测试数据目的!这是一个 回答得很好,我接受了。对我来说,在我的应用程序中,在GUID中使用逐字id值非常方便,我将实现我的解决方案。但同样,这仅用于测试数据目的!