2012-03-28 64 views
5

我们有一个系统,客户在先到先得的基础上分配产品。针对一个数据库表上大量请求的最佳解决方案

我们的产品表包含开始于零,我们用它来跟踪有多少产品已分配即用户保留一个产品,并得到分配1递增的主键,接下来用户将获得2等

问题在于,潜在成千上万的用户会在任何给定的小时内访问系统。所有的人都会打这张桌子。

由于我们需要确保每个客户只分配一个产品并跟踪有多少产品已分配,因此我们对每个访问该系统的客户使用一个行锁,以确保他们在下一个客户之前写入表中击中系统 - 即执行先来先服务的规则。

我们关注的是每个请求进入SQL Server 2008企业版和行锁的处理时间的瓶颈。

因为我们需要确保primay关键的完整性,因此任何需要复制行不通的,我们不能使用多台服务器。

有谁知道有什么好的解决方案,在处理上一个数据库表的请求数量庞大的特别有效的?

多一点信息: 有问题的表基本上只包含两个字段 - ID和客户ID。解决方案是免费赠送一百万件产品 - 因此对高需求的预期以及为什么使用增量主钥匙作为关键对我们有意义 - 一旦关键点击数百万,则不再有客户可以注册。而且,这些产品都是不同的,因此分配正确的密钥是重要的,例如,前100名顾客进入receieve更高​​价值的产品比下100等

感谢您的帮助。

+1

能否请您重新标签,包括[SQLSERVER]你能告诉我的版本及版本,如果您编辑您的问题,并告诉我们你有'SQL2008企业Edition'例如,我们也许能够提供量身定做的解决方案如表分区可在SQL 2008 EE – 2012-03-28 03:16:18

+0

谢谢Jeremy。增加了额外的信息。 – 2012-03-28 03:22:03

+0

明显的第一个问题;你是否剥夺了获得密钥的事务中的所有其他内容?例如。在尝试获得关键所需知道的一切之前,你知道吗?去桌子上拿钥匙,然后再做其他的事情? – Karl 2012-03-28 03:40:56

回答

5

首先,为了消除密钥生成的问题,我会提前生成它们。它只有100万行,这意味着您不必担心管理密钥生成过程。这也意味着您不必担心会意外地生成太多的行,因为一旦填满了表,您将只执行UPDATE,而不执行INSERT。

这里的一个重要问题是,所有1m项目是否相同?如果他们是,那么它是什么顺序的钥匙(或者即使他们有一个订单)无关紧要,因此,当客户提交请求时,您只需'尝试'更新表格,大致如下:

UPDATE TOP(1) dbo.Giveaway -- you can use OUTPUT to return the key value here 
SET CustomerID = @CurrentCustomerID 
WHERE CustomerID IS NULL 

IF @@ROWCOUNT = 0 -- no free items left 
PRINT 'Bad luck' 
ELSE 
PRINT 'Winner' 

另一方面,如果1米物品不同,那么您需要另一种解决方案,例如第1项是X,第2-10项是Y,第11-50项是Z等。在这种情况下,按照提交请求的顺序为客户分配密钥很重要,因此您应该查看某种排队系统,也许使用Service Broker。每个客户向队列添加一个请求,然后一个存储过程一次处理一个请求,并为它们分配最大空闲密钥,然后返回他们赢得的细节。

+0

SQL 2008中不建议使用SET ROWCOUNT。使用'UPDATE TOP(1)'代替? http://msdn.microsoft.com/en-us/library/ms188774%28v=sql.100%29.aspx – 2012-03-28 07:21:39

+0

@EdHarper是的,这是一个很好的观点,我已经更新了我的示例。虽然OP的关键信息当然是,只要您只更新一行,更新哪一行并不重要。 – Pondlife 2012-03-28 08:59:58

+0

感谢Pondlife。这些项目是不同的,所以听起来像排队是要走的路,只是接受在高峰时间处理每个请求会有一些延迟。 我在想的另一个解决方案是将所有的奇数放在一个数据库中,甚至在另一个数据库中放入一个负载均衡器,然后用一个简单的位开关将交替的客户发送给数据库 - 对此作为解决方案的任何想法?我猜我可能会将瓶颈转移到负载平衡器上,而这可能最终需要一个队列呢? 感谢您的帮助,非常感谢。 – 2012-03-28 13:33:08

相关问题