Sql server 有没有一种方法可以缩短存储为字符串的GUID的长度,但它仍然是随机的?

Sql server 有没有一种方法可以缩短存储为字符串的GUID的长度,但它仍然是随机的?,sql-server,Sql Server,我正在创建普通的guid,然后将它们作为字符串存储在表中。它们非常长,我不需要它们那么长,因为我的表最多只能有10000行,如果碰巧创建了两次值,我可以安排第二次尝试插入 我正在为创建包含随机值及其默认值的列,如下所示: ALTER TABLE [dbo].[Question] ADD GlobalId VARCHAR (50) DEFAULT(NEWID()); 是否有某种方法可以缩短GUID并保留一些随机性,例如百万次重复值中的1?请注意,行的插入时间不是一个大问题。对我来说最重要的是,每

我正在创建普通的guid,然后将它们作为字符串存储在表中。它们非常长,我不需要它们那么长,因为我的表最多只能有10000行,如果碰巧创建了两次值,我可以安排第二次尝试插入

我正在为创建包含随机值及其默认值的列,如下所示:

ALTER TABLE [dbo].[Question] ADD GlobalId VARCHAR (50) DEFAULT(NEWID());
是否有某种方法可以缩短GUID并保留一些随机性,例如百万次重复值中的1?请注意,行的插入时间不是一个大问题。对我来说最重要的是,每次插入时,我都希望将一个随机字符串放入GlobalId中

更新:


有人建议我使用一个4字节的整数,我对此没有意见,但我不确定如何生成一个适合SQL Server中默认的4字节整数的数字。

我猜您只是在使用GUID作为快速随机生成器

如果你想让quid短一点。。照办

LEFT(NEWID(),10) -- You don't have to use 10.. i've just decided to test with 10.
你可以用这个来测试它。我已经用前100万个插入测试了它,有6个重复

set nocount on;

if object_id('tempdb..#tmp') is not null
    drop table #tmp
create table #tmp (val varchar(10) primary key)

declare @i int, @new varchar(10)
set @i = 0

while @i < 1000000
begin

    select @new = left(newid(),10)
    begin try 
        insert into #tmp (val) values (@new)
    end try
    begin catch
        print @i
    end catch

    set @i = @i + 1
end
设置不计数;
如果对象id('tempdb..#tmp')不为空
升降台#tmp
创建表#tmp(val varchar(10)主键)
声明@i int、@new varchar(10)
设置@i=0
而@i<1000000
开始
选择@new=left(newid(),10)
开始尝试
插入#tmp(val)值(@new)
结束尝试
开始捕捉
打印@i
端接
设置@i=@i+1
结束
显然,如果你使用更长的字符串,你会得到更少的点击率。。。如果你去掉“-”,你会得到更多的“随机”


如果你有时间。。您应该查找随机数生成器并实现它。这里是一个快速链接

这不是对你问题的具体回答,而是一个使用不同方法的建议(如果可以的话)

如果您真的不需要GUID的唯一性,那么就不要使用GUID—虽然存储开销可能不大(根据您的问题,只有~10K行),但存储不需要存储的内容是没有意义的

如果只需要随行存储随机值,可以尝试使用TSQL函数生成随机数。它适用于
int
-s。如果您只有几千行,重复编号的几率不是很高,但是您可能仍然需要检查以确保没有重复编号(假设您需要一个唯一的编号)。以下是有关可用值范围的参考


但是,如果您确实需要唯一的值,我只会在自动生成的数字列上使用唯一约束。或者继续使用GUID(存储为
uniqueidentifier
binary(16)
而不是
varchar
)-10K行实际上没有那么多,GUID确实非常唯一(如果生成正确)。

首先,如果将字段存储为uniqueidentifier而不是字符串,则存储大小将只有16个字节。如果您正在将其转换为varchar,则每个记录的存储大小将为36字节(32个字符和4个破折号)。因此,在您的示例中,varchar(50)每行也占用36字节的空间。如果只想缩短字符串,可以执行以下操作:

select left(convert(varchar(36), newid()), 8)

这将为您提供NEWID的前8个字符,这将产生2^32或超过40亿个可能性。我想,尝试次数少于10k的情况下发生冲突的可能性不大,但您可能应该处理这种情况以防万一。

那么为什么要使用GUID呢?为什么不使用一个简单的
int
?它只有4个字节,而原始GUID只有16个字节。如果缩短GUID值,重复的机会将开始增加。我不需要使用GUID。对于SQL Server,有没有一种简单的方法可以生成可以存储在这4个字节中的随机数?如果我使用4个字节,那么可以存储的最大数量是多少?即使使用十六进制值。。。即每字节16个字符。对于4个字节,您所说的是16^4=65536个不同的值。您还可以使用校验和返回一个4字节的整数。例如:
SELECT BINARY\u CHECKSUM(NEWID())
,但有时会出现重复(冲突),这只是一个旁注:如果您的globalId被索引,请注意索引碎片,您需要定期重建索引。我希望索引尽可能短的原因是因为我的代码包含多行。例如50。然后它从这些行中获取ID,并将这些ID作为JSON字符串放到另一行中。所以行长对我来说很重要。我非常喜欢你的想法。我认为它满足了我的需要。@SamanthaJ如果您担心长度,请不要使用字符串作为值-使用
int
-s,并将它们作为十六进制值发送到JSON数据中。平均来说,这样的字符串值会更短。我认为“右边”的字符串值更随机。改为做正确的(newid(),10)。我同意xxbbcc。根据您上面的评论,您可以使用十六进制在4个字节中拥有65k个唯一值。如果你把它打开给其他角色看。。。即使只是字母数字。。。36 (26+10)... 你看到的是1.67mm独特的代表性值。噢,哇,山姆比我快了。我更喜欢他的,因为你实际上不需要转换部分。我想补充一点,用右键代替左键可以让你在冲刺前最多12个字符,但山姆也补充了这一点。好像我总是落后一分钟。