SQL Server是否支持跨所有表全局唯一主键的模式?
跨表全局唯一主键的实现方案(SQL Server)
存在这种模式,以下是两种在SQL Server中实现跨表全局唯一主键的实用方案,完全适配你的测试需求:
1. 使用全局序列(SQL Server 2012+)
SQL Server 2012及以上版本支持序列对象,你可以创建一个全局序列,让所有表的主键都从这个序列取值,天然保证跨表主键唯一。
-- 创建全局递增序列 CREATE SEQUENCE GlobalPrimaryKeySequence AS BIGINT START WITH 1 INCREMENT BY 1 NO CYCLE; -- 避免循环,防止ID重复 -- 给表指定主键默认值为序列的下一个值 CREATE TABLE Order ( Id BIGINT PRIMARY KEY DEFAULT NEXT VALUE FOR GlobalPrimaryKeySequence, OrderNumber VARCHAR(20) NOT NULL ); CREATE TABLE Customer ( Id BIGINT PRIMARY KEY DEFAULT NEXT VALUE FOR GlobalPrimaryKeySequence, Name NVARCHAR(50) NOT NULL );
插入记录时无需手动指定ID,数据库会自动从全局序列分配唯一值,不同表的主键绝不会重复。
2. 自定义全局计数器表(兼容旧版SQL Server)
如果使用的是2008及以前的旧版本SQL Server,可以通过计数器表+事务锁的方式实现全局唯一ID:
-- 创建全局计数器表 CREATE TABLE GlobalIdCounter ( CounterKey VARCHAR(30) PRIMARY KEY, CurrentValue BIGINT NOT NULL DEFAULT 0 ); -- 初始化主键计数器 INSERT INTO GlobalIdCounter (CounterKey) VALUES ('PrimaryKey'); -- 创建取号存储过程,保证原子性 CREATE PROCEDURE GetNextGlobalId @NextId BIGINT OUTPUT AS BEGIN SET NOCOUNT ON; BEGIN TRANSACTION; UPDATE GlobalIdCounter SET CurrentValue = CurrentValue + 1 WHERE CounterKey = 'PrimaryKey'; SELECT @NextId = CurrentValue FROM GlobalIdCounter WHERE CounterKey = 'PrimaryKey'; COMMIT TRANSACTION; END; -- 插入记录时调用存储过程获取ID DECLARE @NewCustomerId BIGINT; EXEC GetNextGlobalId @NewCustomerId OUTPUT; INSERT INTO Customer (Id, Name) VALUES (@NewCustomerId, '张三');
通过事务锁确保每次取号都是原子操作,不会出现并发冲突,同样能实现跨表主键唯一。
针对测试场景的价值
这种全局唯一主键模式刚好能解决你遇到的测试漏洞:不同表的主键值完全不重叠,当你错误引用其他表的外键时,要么目标ID不存在触发约束错误,要么能通过业务逻辑快速发现引用对象类型不符,彻底避免因ID巧合相同导致的测试漏过问题。
内容的提问来源于stack exchange,提问作者David Thielen
相关产品推荐
相关产品推荐

