使用INT或GUID作为主键

时间:2014-02-20 02:20:12

标签: sql-server vb.net

我试图在SQL服务器VB.net中创建一个ID列,它将为数据库中创建的每个新行提供一系列数字。所以我使用以下技术来创建ID列。

select * from T_Users
ALTER TABLE T_Users     
ADD User_ID INT NOT NULL IDENTITY(1,1) Primary Key

然后我在数据库中注册了几个用户名,它运行得很好。例如,前六行是1,2,3,4,5,6。然后我在NEXT日注册了4个用户,但这次ID号从6跳到了非常大的数字,例如:1,2,3,4,5,6,1002,1003,1004,1005。然后两天后,我又注册了两个用户,新行读取3002,3004。所以我的问题是为什么我每隔一天就注册用户就跳过如此大的数字。我用来创建序列的技术是错误的吗?如果有问题,请有人告诉我该怎么做对吗?现在,由于我对上面使用的技术感到沮丧,或者我尝试使用顺序生成的GUID值。生成GUID值序列。然而,唯一的缺点是,它产生一个非常长的数字(INT大小的4倍)。我的问题是,使用GUID有没有比INT更重要的优势?

此致

2 个答案:

答案 0 :(得分:4)

GUID的优势:

如果您希望脱机客户端能够创建新记录,那么GUID很好,因为当新记录同步回主数据库时,您永远不会遇到主键冲突。

GUID的缺点:

GUID作为主键可能会影响数据库的性能,因为对于群集主键,数​​据库将希望按键值的顺序保留行。但这意味着现有记录之间存在大量插入,因为GUID将是随机的。

使用IDENTITY列不会受此影响,因为保证下一条记录具有最高值,因此每次都会在最后添加该行。不需要重新洗牌。

有一个折衷方案是生成一个伪GUID,这意味着你会期望每隔70年左右发生一次密钥冲突,但却极大地帮助了索引。

其他缺点是:a)他们确实占用了更多的存储空间,而b)编写SQL是一件非常痛苦的事,比UPDATE TABLE SET FIELD = 'value' where KEY = 50003更容易输入UPDATE TABLE SET FIELD = 'value' where KEY = '{F820094C-A2A2-49cb-BDA7-549543BB4B2C}'

您对IDENTITY列的声明对我来说很好。键值中的间隙可能是由于尝试添加行失败。 IDENTITY值将递增但行永远不会被提交。不要让它打扰你,它几乎发生在每张桌子上。

编辑:

这个问题涵盖了伪GUID的含义。 INSERTs with sequential GUID key on clustered index not significantly faster

在SQL Server 2005+中,您可以使用NEWSEQUENTIALID()来获取应该大于先前值的随机值。有关详细信息,请参阅此处http://technet.microsoft.com/en-us/library/ms189786%28v=sql.90%29.aspx

答案 1 :(得分:0)

  

我用来创建序列的技术是错误的吗?

没有。如果你有任何谷歌技能不存在。对“Sql server身份跳过值”的简短介绍将为您提供一系列的回报,包括:

SQL Server 2012 column identity increment jumping from 6 to 1000+ on 7th entry

和规范:

Why are there gaps in my IDENTITY column values?

你基本上错误地认为sql server不会优化它对性能的访问。身份证号码是标记,没有别的,也没有假设没有差距。

特别是:SQL Server在1000个块中预分配数字 - 如果重新启动服务器(如在工作站上),其余部分将丢失。

http://www.sqlserver-training.com/sequence-breaks-gap-in-numbers-after-restart-sql-server-gap-between-numbers-after-restarting-server/-

如果您使用手动sqyuence(new nin sql server 2012),您可以为此定义缓存大小(预生成)并将其设置为1 - 当您执行大量插入时,性能略低。< / p>

  

我的问题是,使用GUID与INT相比有什么明显优势吗?

是。你可以拥有GUID比使用int更多的行。例如,int32限制为大约20亿行。对于我们中的一些人来说太低(我有100亿范围内的表),甚至64大的int是有限的。一个真正的zetabyte数据库,你必须按顺序使用guid,自己生成。

任何正常的人都没有看到差异,因为我们都没有真正处理那么多行。较大的尺寸使得很多东西变慢(较大的键大小=索引中较大的空间=较大的索引=相同操作的更多内存/ io)。甚至你的连续ID也会跳跃。

为什么不把你的期望调整到现实 - 身份并不意味着没有差距 - 或者使用带缓存1的序列。