Sql server 主键类型的选择

Sql server 主键类型的选择,sql-server,primary-key,scalability,Sql Server,Primary Key,Scalability,我有一个表,它可能每秒有大量的插入,我正在尝试选择一种我想要使用的主键类型。为了便于说明,假设它是users表。我试图在整个应用程序中选择使用GUID和BIGINT作为主键,最终作为UserID。若我使用GUID,我会保存到数据库的行程以生成一个新ID,但GUID并不是“用户友好的”,并且不可能按此ID对表进行分区(我正计划这样做)。使用BIGINT更方便,但是生成它是一个问题-我不能使用IDENTITY(这是有原因的),所以我唯一的选择是使用一些包含上次使用的ID的helper表,然后我调用这

我有一个表,它可能每秒有大量的插入,我正在尝试选择一种我想要使用的主键类型。为了便于说明,假设它是users表。我试图在整个应用程序中选择使用GUID和BIGINT作为主键,最终作为UserID。若我使用GUID,我会保存到数据库的行程以生成一个新ID,但GUID并不是“用户友好的”,并且不可能按此ID对表进行分区(我正计划这样做)。使用BIGINT更方便,但是生成它是一个问题-我不能使用IDENTITY(这是有原因的),所以我唯一的选择是使用一些包含上次使用的ID的helper表,然后我调用这个存储过程:

create proc GetNewID @ID BIGINT OUTPUT
as
begin
update HelperIDTable set @ID=id, id = id + 1 
end
但是这个helper表是一个明显的瓶颈,我关心的是它每秒能做多少次更新

我真的很喜欢使用BIGINT作为pk的想法,但是瓶颈问题让我担心——有没有办法粗略估计一下它每秒可以生成多少个id?我意识到这在很大程度上取决于硬件,但是否存在任何物理限制以及我们考虑的程度?100秒/秒?1000秒/秒

任何关于如何解决问题的想法都将受到高度赞赏!这个问题让我睡不着好几个晚上了

谢谢!
Andrey

尝试使用脚本命中数据库,也许可以使用jmeter模拟并发命中。也许你可以测量一下自己能承受多大的负荷。此外,您的数据库可能会导致瓶颈。是哪一个?我希望PostgreSQL能够承受重载,就像雅虎和skype一样,我也会尝试用脚本攻击数据库,也许可以使用jmeter来模拟并发攻击。也许你可以测量一下自己能承受多大的负荷。此外,您的数据库可能会导致瓶颈。是哪一个?对于重载,我会优先使用PostgreSQL,就像yahoo和skype一样

我尝试对所有表使用GUID PKs,除了小型查找表。GUID概念确保可以在Memory中安全地创建对象的标识,而无需往返数据库,并且在以后保存时无需更改标识


当您需要“人类可读”的id时,可以在保存时使用自动增量int。对于分区,您也可以稍后通过数据库计划一次性为多个用户创建bigint。

我尝试对所有表使用guidpks,但小型查找表除外。GUID概念确保可以在Memory中安全地创建对象的标识,而无需往返数据库,并且在以后保存时无需更改标识


当您需要“人类可读”的id时,可以在保存时使用自动增量int。对于分区,您也可以稍后通过数据库计划一次为多个用户创建bigint。

GUID似乎是一个自然的选择—如果您确实必须这样做,您可能会争论将其用作表的主键—唯一标识数据库中行的单个值

我强烈建议不要使用GUID列作为集群键,SQL Server默认情况下会这样做,除非您明确告诉它不要这样做

正如《索引女王》和其他人多次指出的那样,作为集群键的GUID并不是最优的,因为由于其随机性,它将导致大量页面和索引碎片,并导致总体性能不佳

是的,我知道-在SQL Server 2005和更高版本中有
newsequentialid()
-但即使是这样也不是真正的完全顺序的,因此也会遇到与GUID相同的问题-只是不太明显而已

然后还有另一个需要考虑的问题:表上的集群键也将添加到表中每个非集群索引的每个条目中——因此您确实希望确保它尽可能小。通常,对于绝大多数表来说,一个20多亿行的INT就足够了——与作为集群键的GUID相比,您可以在磁盘和服务器内存中节省数百兆的存储空间

所以总结一下:除非你有很好的理由,否则我总是推荐一个
INT-IDENTITY
字段作为表中的主键/聚集键


Marc

GUID似乎是一个自然的选择——如果您真的必须这样做,您可能会争论将其用于表的主键——唯一标识数据库中行的单个值

我强烈建议不要使用GUID列作为集群键,SQL Server默认情况下会这样做,除非您明确告诉它不要这样做

正如《索引女王》和其他人多次指出的那样,作为集群键的GUID并不是最优的,因为由于其随机性,它将导致大量页面和索引碎片,并导致总体性能不佳

是的,我知道-在SQL Server 2005和更高版本中有
newsequentialid()
-但即使是这样也不是真正的完全顺序的,因此也会遇到与GUID相同的问题-只是不太明显而已

然后还有另一个需要考虑的问题:表上的集群键也将添加到表中每个非集群索引的每个条目中——因此您确实希望确保它尽可能小。通常,对于绝大多数表来说,一个20多亿行的INT就足够了——与作为集群键的GUID相比,您可以在磁盘和服务器内存中节省数百兆的存储空间

所以总结一下:除非你有很好的理由,否则我总是推荐一个
INT-IDENTITY
字段作为表中的主键/聚集键


Marc

出于业务原因,您需要主键,还是出于存储考虑,需要群集键? 有关PK与聚集键的主题,请参阅更详细的帖子

你真的必须详细说明为什么你不能
 select min(id) where (name = '')