我应该如何在 SQL Server 2005 中实现“自动编号”字段?
Posted
技术标签:
【中文标题】我应该如何在 SQL Server 2005 中实现“自动编号”字段?【英文标题】:How should I go about implementing an "autonumber" field in SQL Server 2005? 【发布时间】:2010-10-15 02:14:47 【问题描述】:我知道 IDENTITY 字段,但我感觉无法使用 IDENTITY 字段来解决我的问题。
假设我有多个客户。每个客户都有多个订单。每个客户都需要为他们的订单按顺序编号,具体到他们自己。
示例表结构:
Orders:
OrderID | ClientID | ClientOrderID | etc...
此表的一些示例行是:
OrderID | ClientID | ClientOrderID | etc...
1 | 1 | 1 | ...
2 | 1 | 2 | ...
3 | 2 | 1 | ...
4 | 3 | 1 | ...
5 | 1 | 3 | ...
6 | 2 | 2 | ...
我知道天真的方法是为任何客户端获取 MAX ClientOrderID 并将该值用于 INSERT,但这会受到并发问题的影响。我正在考虑使用事务,但我不太确定可用于此的最广泛的隔离范围。我将使用 LINQ to SQL,但我觉得这无关紧要。
【问题讨论】:
所以,我不得不问...你为什么要这样做? 这感觉就像是不习惯数据存储的人要求您这样做。创建日期是一种更自然的方式。 我可能只是为每个订单分配一个时间戳,然后执行一次 COUNT 以获得客户的订单#。这不应该是性能问题,因为该表不会超过 1000 条记录。 虽然按日期甚至 orderID 列排序会给您相同的结果,但当有人决定删除订单时,整个序列编号系统将会崩溃......即使不是在规范中。我认为他为客户提供他们所要求的东西是正确的。 【参考方案1】:您可以使用存储库模式来处理您的订单,并让它控制每个特定客户订单号的数量。如果您正确实施 OrderRepository,它可以在将订单保存到数据库之前控制并发和编号(让存储库而不是数据库设置编号)。
存储库模式:http://martinfowler.com/eaaCatalog/repository.html
【讨论】:
【参考方案2】:一种可能性(尽管我不喜欢这样做)是有一个查找表,它会告诉您为每个供应商提供的最大订单号。在事务内部,您将从 VendorOrderNumber 获取最新的订单,保存新订单,增加 VendorOrderNumber 中的值,提交事务。
【讨论】:
【参考方案3】:如果我错了,请有人纠正我,但是只要您的 MAX() 调用与您的插入在同一步骤中,您就不会遇到并发问题。
所以,你可以不做
select @newOrderID=max(ClientOrderID) + 1
from orders
where clientid=@myClientID;
insert into ( ClientID, ClientOrderID, ...)
values( @myClientID, @newOrderID, ...);
但是你可以做到
insert into ( ClientID, ClientOrderID, ...)
select @myClientID, max(ClientOrderID) + 1, ...
from orders
where clientid=@myClientID;
我假设 OrderID 是一个标识列。
再一次,如果我对此有误,请告诉我。最好有网址
【讨论】:
【参考方案4】:这是一种奇怪的数据存储方式,但假设您需要它,则没有可以使用的内置内容。
您对 Max(ClientOrderID) 的建议直截了当,而且很容易实施(遵循 John MacIntyre 的建议)。它在有几千个订单的桌子上可能会很好地工作。随着表的增长,这种方法当然会变慢。
Nick DeVore 的查找表建议实施起来有点麻烦,但不会受到数据增长的实质性影响。
根据您实际需要 ClientOrderID 的位置/时间,您可以在需要时计算 id,如下所示:
SELECT *,
ROW_NUMBER() OVER(ORDER BY OrderID) AS ClientOrderID
FROM Orders
WHERE ClientID = 1
这假定 ClientOrderID 与 OrderID 的顺序相同。如果不实际保留 ID,则将其用作其他任何内容的键是很尴尬的。这种方法不应受到数据增长的影响。
【讨论】:
以上是关于我应该如何在 SQL Server 2005 中实现“自动编号”字段?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 sql server 2005 中编写 sql server 数据库图表脚本?
如何在 SQL Server 2005 中回滚 UPDATE 查询?