我想在我现有的SQL Server 2012数据库中添加一个CorrelationId列。
CorrelationId是一个标识符,它指示实体之间的关系,而不进一步描述该关系。通常这意味着记录是在相同的事务中创建的,或者以某种方式与相同的工作流相关。关联id也可以跨边界使用。因此,它将在其他系统中使用,以关联到相同的工作流。新的关联id应该是跨边界的全局唯一的。这并不是要替换外键。它适用于比外键描述的更松散的关系。如果你愿意的话,更多的是时间关系。
Anywho。我正在考虑如何发布这些correlationid。一种方法是只使用guid。但我也希望能够对它们进行索引。
另一种方法是创建一个CorrelationId Pool,它本质上是一个包含单行和单个BIG INT列的表。这个数字应该是下一个可用的数字,当我请求这个数字时,它会增加计数器。如果我想确保在请求数字时没有竞争条件,那么这个查询应该是什么样子的呢?
相关id应该是"免费的",意思是你只需要一个,然后分发出去,永远不会再使用。如果你决定不使用它(例如,如果一个事务回滚),你可以把它扔掉,不用担心它永远不会再被使用。
尽管CorrelationId不会被视为外键,但它将在需要时用于在查询中连接表。出于这个原因,我认为我更喜欢BigInt,所以如果我需要它,我可以创建索引。
你的建议是什么?我会使用GUID。您可以在guid上创建索引(尽管它们会比BIGINT列大)。
GUID的另一个主要优点是它们可以由第三方系统生成,并且仍然由您的系统使用。
好的,你基本上是在问如何创建一个bigint(一个标识列,但在多个表之间共享)。
有许多可行的方法,最好的方法取决于你如何使用它。最近在SQL 2012中添加的序列功能可能很有用,特别是如果你已经习惯了Oracle生成器等。
如果您有许多可能的调用者,它们都抓取单个(或几个)值,您可能会遇到严重的锁/资源争用。但是,如果您可以在调用者内部保留至少最小的状态,则以下策略非常有用。
创建一个ID"块分配"存储过程。你可以在请求的块中传递ID的数量。一个很少进行分配的调用者可以使用块大小为1来分配,一个大量使用的调用者可以使用单个调用分配1000(或更多)块大小。
add—样例进程—未测试
create table SharedID
(
ID bigint not null
)
create proc GetBlock(@BlockSize int) as
begin
declare @dummy table
(
ID bigint
)
UPDATE SharedID
SET ID = ID + @blocksize
OUTPUT INSERT.ID
into @dummy
-- or put into output parm if you prefer
select @dummy - @blocksize as IDBlockStart
end
如果您分配了一个1000的块,那么在再次调用存储过程分配器之前,您将在该块内部满足1000个调用。如果你的程序崩溃了,你失去的只是在那个块中分配的"未使用的"id。
同样,如果你的所有调用者都被有效地分配了1000个块,只需使用一个增量为1000的序列来分配id块。