如何从整数值创建确定性唯一标识符(GUID)

Mar*_*cel 0 sql sql-server guid

注意:这不是关于数据库设计,也不是关于GUID的一般用法.这是关于在Microsoft SQL服务器上确定性地为测试数据创建这样的GUID.

我们正在将数据库从整数标识符迁移到uniqueidentifier数据类型.

出于测试目的,我们希望将测试数据集迁移到已知的GUID值,确定性地基于我们以前的整数值

UPDATE Unit
SET UnitGuid = NEWID(UnitId)
Run Code Online (Sandbox Code Playgroud)

显然这不会马上起作用.如何使用UnitId创建确定性GUID?

Luk*_*zda 5

您可以创建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;
Run Code Online (Sandbox Code Playgroud)

DBFiddle演示

之后,您可以使用简单查询或使用函数包装:

SELECT guid
FROM tab_map
WHERE id_old = ?
Run Code Online (Sandbox Code Playgroud)


Dam*_*ver 5

不要从“字符串”的角度考虑问题。anint由 4 个字节组成。Auniqueidentifier由 16 个字节组成。您可以轻松获取 12 个固定字节并将四个字节从 an 附加到这些字节int的末尾,并获得适用于所有int值的解决方案:

declare @Unit table
(
UniqueColumn UNIQUEIDENTIFIER DEFAULT NEWID(),
Characters VARCHAR(10),
IntegerId int
)

-- Add *3* data rows
INSERT INTO @Unit(Characters, IntegerId) VALUES ('abc', 1111),('def', 2222),('ghi',-17)

-- Deterministically creates a uniqueidentifier value out of an integer value. 
DECLARE @GuidPrefix binary(12) = 0xefbeadde0000000000000000
UPDATE @Unit 
    SET UniqueColumn = CONVERT(uniqueidentifier,@GuidPrefix + CONVERT(binary(4),IntegerId))

-- Check the result
SELECT * FROM @Unit
Run Code Online (Sandbox Code Playgroud)

结果:

UniqueColumn                         Characters IntegerId
------------------------------------ ---------- -----------
DEADBEEF-0000-0000-0000-000000000457 abc        1111
DEADBEEF-0000-0000-0000-0000000008AE def        2222
DEADBEEF-0000-0000-0000-0000FFFFFFEF ghi        -17
Run Code Online (Sandbox Code Playgroud)

(出于各种原因,我们必须以与默认情况下uniqueidentifier将 a显示为字符串时使用的顺序不同的顺序提供前四个字节,这就是为什么如果我们要显示DEADBEEF,我们必须以 开始我们的二进制文件efbeadde

此外,当然,插入通常的警告,如果您正在创建 guids/uniqueidentifiers 但不使用规定的方法之一来生成它们,那么您不能假设任何关于唯一性的通常保证。