提问人:kermit 提问时间:6/28/2022 最后编辑:kermit 更新时间:6/29/2022 访问量:494
如何在多个SQL Server数据库之间共享单个序列?
How to share a single sequence between multiple SQL Server databases?
问:
我需要在两个不同的 SQL Server 数据库中的表之间共享一个 SQL Server 序列。此示例适用于两个现有表和在同一数据库上定义的序列:
USE DatabaseA ;
GO
CREATE SEQUENCE dbo.TransactionSequence START WITH 1 INCREMENT BY 1 ;
GO
ALTER TABLE Table1 ADD TransactionSequenceID int NOT NULL
CONSTRAINT DF_Table1_TransactionSequence DEFAULT (NEXT VALUE FOR dbo.TransactionSequence) ;
ALTER TABLE Table2 ADD TransactionSequenceID int NOT NULL
CONSTRAINT DF_Table2_TransactionSequence DEFAULT (NEXT VALUE FOR dbo.TransactionSequence) ;
GO
但是,对于其他数据库中的表,此命令失败:
USE DatabaseB ;
GO
ALTER TABLE Table3 ADD TransactionSequenceID int NOT NULL
CONSTRAINT DF_Table3_TransactionSequence DEFAULT (NEXT VALUE FOR DatabaseA.dbo.TransactionSequence) ;
GO
它失败,因为 SQL Server 不允许 DEFAULT 约束引用另一个数据库中的序列。
在此上下文中,序列不能通过同义词间接引用,并且不允许在函数或其他几个可能有用的构造中引用。不同数据库中的表是否可以共享一个序列?如果是这样,那如何?NEXT VALUE FOR <sequence>
答:
1赞
Ben Thul
6/29/2022
#1
我过去曾实现过类似的东西,根据您的需求/用例,它可能适合您。假设您需要一个在多个数据库中生成 WidgetID 值的序列。你可以这样做:
use [Widgets_001];
create sequence SQ_WidgetID
as int
start with 1
minvalue 1
maxvalue 1000000
increment by 1;
use [Widgets_002];
create sequence SQ_WidgetID
as int
start with 1000001
minvalue 1000001
maxvalue 2000000
increment by 1;
创建序列后,您可以在所需的任何默认约束中使用它们。
这里的想法是它们从不相交的范围内分配。由于序列是独立分配的,因此数据库甚至可以位于不同的服务器上。这确实伴随着需要监控范围耗尽的成本(例如,当Widget_001中的序列超过 950,000 时,可能是时候开始考虑分配新范围了)并注意重新设定序列的种子以从新范围分配(如果您有办法查看数据库中的所有序列并始终分配新范围以严格大于所有现有 s 的最大值)。minvalue
maxvalue
我个人抵制将任何意义归因于这些相应序列生成的值的诱惑。也就是说,很容易说“嗯......这就是 WidgetID 1234。因此,它在Widgets_001。这有其自身的问题。
评论
0赞
kermit
6/29/2022
非常感谢您提出的解决方案。不幸的是,我的要求是让表共享相同的序列。
0赞
Ben Thul
6/29/2022
为什么?该技术要求满足的业务需求是什么?
0赞
kermit
6/29/2022
我们需要知道记录插入到表中的顺序。
0赞
Ben Thul
6/29/2022
一般来说,将任何含义赋予这些类型的标识符是一个坏主意。它们的作用是为您提供一种方法,通过它唯一地标识数据库中的行,并相关地引用它。任何过去的事情最终都会导致违规行为。但是,即使有能够对记录进行排序的要求,最终也会有人问“它们是什么时候插入的?”或“它们之间的时差是什么?”。添加某种 DateCreated 列可以同时回答这两个问题(并且仍然提供您正在寻找的排序)。过你的生活,但是⚠️.
0赞
kermit
6/30/2022
谢谢!!!您的评论让我重新考虑使用 DateCreated 列。考虑到交易量,datetime 不起作用,这是我首先想到的。直到现在,我才想到使用具有亚微秒精度的 datetime2 数据类型列来对记录进行排序。我不能将您的回答标记为所述技术问题的解决方案,但您的评论非常有帮助!!
评论
INSERT
SEQUENCE
SEQUENCE
SEQUENCE
INSTEAD OF INSERT
Table3
NEXT VALUE FOR DatabaseA.dbo.TransactionSequence
INSTEAD OF