Sql 使用所有62个字符的唯一随机Id

Sql 使用所有62个字符的唯一随机Id,sql,sql-server,random,guid,newid,Sql,Sql Server,Random,Guid,Newid,我正在寻找一种方法来生成唯一的随机ID,该ID将尽可能短,类似于url缩短器,通过代码或使用MSSQL 我知道这可以使用NEWID或CRYPT_GEN_RANDOM来完成,但这些方法只使用A-F和0-9,而我正在寻找一个解决方案,它将使用所有62个字符A-Z、A-Z、0-9,因此获得一个更短的id。我不能说这是一个适合SQL Server的任务,但它是可以实现的 首先,您需要创建一个映射表,其中包含您希望在URL中看到的所有字符: declare @charmap table ( Id ti

我正在寻找一种方法来生成唯一的随机ID,该ID将尽可能短,类似于url缩短器,通过代码或使用MSSQL


我知道这可以使用NEWID或CRYPT_GEN_RANDOM来完成,但这些方法只使用A-F和0-9,而我正在寻找一个解决方案,它将使用所有62个字符A-Z、A-Z、0-9,因此获得一个更短的id。

我不能说这是一个适合SQL Server的任务,但它是可以实现的

首先,您需要创建一个映射表,其中包含您希望在URL中看到的所有字符:

declare @charmap table (
  Id tinyint identity(0,1) primary key,
  Letter char(1) collate Latin1_General_BIN not null unique
);

insert into @charmap (Letter)
select top (26) char(row_number() over(order by (select null)) - 1 + ascii('A'))
from sys.all_objects ao
union all
select top (26) char(row_number() over(order by (select null)) - 1 + ascii('a'))
from sys.all_objects ao
union all
select top (10) char(row_number() over(order by (select null)) - 1 + ascii('0'))
from sys.all_objects ao;
在这个例子中,我使用了一个表变量来最小化影响。当然,您可以将其转换为静态表;在这种情况下,只需要填充一次

现在,下面的查询将生成指定数量的代码,所有代码都具有相同的所需长度。前两个变量控制:

declare @BatchSize int = 1000,
  @Length int = 7;

select h.RndHex,
  replace(
    (select cm.Letter as [data()] from (
      select top (datalength(h.RndHex)) row_number() over(order by (select null)) as [RN]
      from sys.all_objects ao
    ) ca
    inner join @charmap cm on cm.Id = cast(substring(h.RndHex, ca.RN, 1) as tinyint) % 62
    order by ca.RN
    for xml path('')
    ), ' ', ''
  ) as [ShortURL]
from (
  select top (@BatchSize) crypt_gen_random(@Length) as [RndHex]
  from sys.all_objects a, sys.all_objects o
) h;
从技术上讲,5个字符将为您提供62,5~=9.16亿个唯一组合。但是,您可能希望增加代码长度,以使它们更难猜测。这就是为什么我的示例生成7个字符的代码——对于使用的1亿个组合,它将为每个实际生成的组合提供大约35000个可能的组合


另一方面,如果可猜测性不是您的问题,您可以将代码长度保持在最小值,在您的情况下为5个字符。

NEWID和CRYPT\u GEN\u RANDOM都不会返回任何字符。它们分别返回uniqueidentifier和varbinary8000数据类型。我们还需要知道需要生成多少这些唯一标识符,因为这实际上决定了它们的长度。稍微扩大的射程比你确定的62更合适吗?或者其他标准编码?使用UUID有什么问题?它只有16个字节长。ID需要用作URL的一部分,因此不能使用Base64编码,因为它使用了一些非标准字符。我需要生成大约1亿个唯一的代码,这些代码将是唯一的和随机的。所以Base64,包括专门设计用于URL的变体,是不合适的,因为您正在URL中使用它们?