适用于:SQL Server
Azure SQL 数据库
Azure SQL 托管实例
创建一个序列对象并指定其属性。 序列是用户定义的绑定到架构的对象,该对象可根据创建序列所依据的规范来生成数值序列。 这组数值以定义的间隔按升序或降序生成,并且可配置为用尽时重新启动(循环)。
序列与标识列不同,不与特定表相关联。 应用程序将引用某一序列对象以便检索其下一个值。 序列与表之间的关系由应用程序控制。 用户应用程序可以引用一个序列对象,并跨多个行和表协调值。
与插入行时生成的标识列值不同,应用程序可以通过调用 NEXT VALUE FOR 来获取下一个序列号,而无需插入该行。 使用 sp_sequence_get_range 同时获取多个序列号。
有关同时使用和 CREATE SEQUENCE 函数的信息和 NEXT VALUE FOR 方案,请参阅 序列号。
语法
CREATE SEQUENCE [ schema_name . ] sequence_name
[ AS [ built_in_integer_type | user-defined_integer_type ] ]
[ START WITH <constant> ]
[ INCREMENT BY <constant> ]
[ { MINVALUE [ <constant> ] } | { NO MINVALUE } ]
[ { MAXVALUE [ <constant> ] } | { NO MAXVALUE } ]
[ CYCLE | { NO CYCLE } ]
[ { CACHE [ <constant> ] } | { NO CACHE } ]
[ ; ]
参数
sequence_name
指定数据库中标识序列的唯一名称。 类型为 sysname。
[ built_in_integer_type | user-defined_integer_type ]
序列可定义为任何整数类型。 允许使用下面的类型。
- tinyint - 范围为 0 到 255
- smallint - 范围为 -32,768 到 32,767
- int - 范围为 -2,147,483,648 到 2,147,483,647
- bigint - 范围为 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
- decimal 或 numeric,小数位数为 0。
- 基于这些允许类型之一的任何用户定义数据类型(别名类型)。
如果未提供任何数据类型,则将 bigint 数据类型用作默认数据类型。
START WITH <常量>
序列对象返回的第一个值。 该值 START 必须是小于或等于最大值且大于或等于序列对象的最小值的值。 新序列对象的默认起始值是升序序列对象的最小值和降序序列对象的最大值。
INCREMENT BY <常量>
用于递增(如果为负数)的序列对象值(如果为负值),以便每次调用 NEXT VALUE FOR 函数。 如果增量为负值,则序列对象为降序;否则,它会升序。 增量不能为 0。 新序列对象的默认增量为 1。
[ MINVALUE <常量> |NO MINVALUE ]
指定序列对象的边界。 一个新序列对象的默认最小值是该序列对象的数据类型的最小值。 对于 tinyint 数据类型,此值为零,对于所有其他数据类型则为负数。
[ MAXVALUE <常量> |NO MAXVALUE
指定序列对象的边界。 一个新序列对象的默认最大值是该序列对象的数据类型的最大值。
[ CYCLE |NO CYCLE ]
此属性指定当超过序列对象的最小值或最大值时,序列对象是应从最小值(对于降序序列对象,则为最大值)重新开始,还是应引发异常。 新序列对象的默认周期选项为 NO CYCLE。
注意
SEQUENCE从最小值或最大值而不是从起始值循环重启。
[ CACHE [ <常量> ] |NO CACHE ]
通过最大限度地减少生成序列编号所需的磁盘 IO 数,可以提高使用序列对象的应用程序的性能。 默认为 CACHE。
例如,如果选择缓存大小为 50,SQL Server 不会保留 50 个缓存值。 它只缓存当前值和缓存中剩余的值量。 这意味着,存储缓存所需的内存量始终为序列对象的数据类型的两个实例。
注意
如果在未指定缓存大小的情况下启用缓存选项,数据库引擎将选择大小。 但是,用户不应依赖于选择是一致的。 Microsoft 可能会更改计算缓存大小的方法而不另行通知。
使用 CACHE 选项创建时,意外关闭(如电源故障)可能会导致缓存中剩余的序列号丢失。
注解
序列号在当前事务的作用域之外生成。 无论使用序列号的事务是提交还是回滚,都使用它们。 只有在记录被完全填充后,才会发生重复验证。 在某些情况下,这可能会导致在创建过程中将相同数字用于多个记录,但随后被识别为重复。 如果发生这种情况并且其他自动编号值已应用于后续记录,则可能会导致自动编号值与预期行为之间存在差距。
缓存管理
为了提高性能,SQL Server 预分配参数 CACHE 指定的序列号数。
例如,用起始值 1 和缓存大小 15 创建一个新序列。 在需要第一个值时,便可从内存中使用值 1 到 15。 最后缓存的值 (15) 将写入磁盘上的系统表中。 使用完所有的 15 个数字后,下一个请求(数字 16)将导致重新分配缓存。 新的最后一个缓存值 (30) 将写入系统表。
如果数据库引擎在使用了 22 个数字后停止,则会将内存中的下一个预期序列号 (23) 写入系统表,替换以前存储的数字。
在 SQL Server 重新启动并且需要一个序列号之后,将从系统表中读取起始编号 (23)。 会为内存分配 15 个数字 (23-38) 的缓存量,并将下一个非缓存编号 (39) 写入到系统表。
如果因某事件(如电源故障)异常停止,序列将使用从系统表中读取的编号 (39) 重新开始。 分配给内存(但用户或应用程序永远不会请求)的任何序列号都将丢失。 此功能可能会留下空白,但保证单个序列对象永远不会为同一个序列对象发出两次相同的值,除非它被定义为 CYCLE 或手动重启。
缓存通过跟踪当前值(发出的最后一个值)和缓存中剩余的值量来保留在内存中。 因此,缓存所使用的内存量始终为序列对象的数据类型的两个实例。
设置缓存参数,以便 NO CACHE 每次使用序列时将当前序列值写入系统表。 这样会增加磁盘访问,从而降低性能,但可以减少出现意外间隙的机会。 如果使用或sp_sequence_get_range函数请求NEXT VALUE FOR数字,但未使用或未提交的事务中使用数字,则仍可能出现差距。
当序列对象使用 CACHE 此选项时,如果重新启动序列对象或更改 INCREMENT、 CYCLE、 MINVALUE、 MAXVALUE或缓存大小属性,则会导致在发生更改之前将缓存写入系统表。 然后,从当前值开始重新加载缓存(也就是说,不会跳过任何数字)。 更改缓存大小将立即生效。
缓存值可用时的 CACHE 选项
如果序列对象内存中存在可用的值,则每次请求序列对象生成选项的下一个值 CACHE 时,都会发生以下过程。
- 计算序列对象的下一个值。
- 在内存中更新该序列对象的新当前值。
- 将计算的值返回给调用语句。
缓存耗尽时的 CACHE 选项
如果缓存已用尽,则每次请求序列对象生成选项的下一个值 CACHE 时,都会发生以下过程:
计算序列对象的下一个值。
计算新缓存的最后一个值。
锁定序列对象的系统表行,将在步骤 2 中计算的值(最后一个值)写入系统 表。 将触发缓存耗尽的扩展事件,以通知用户新的持久化值。
NO CACHE 选项
每次请求序列对象生成选项的下一个值 NO CACHE 时,都会发生以下过程:
- 计算序列对象的下一个值。
- 将序列对象的新当前值写入系统表。
- 将计算的值返回给调用语句。
元数据
有关序列的信息,请查询 sys.sequences。
安全性
权限
需要CREATE SEQUENCE或ALTERCONTROL权限SCHEMA。
- db_owner和db_ddladmin固定数据库角色的成员可以创建、更改和删除序列对象。
- db_owner和db_datawriter固定数据库角色的成员可以通过生成数字来更新序列对象。
以下示例授予用户 AdventureWorks\Larry 在架构中创建 Test 序列的权限。
GRANT CREATE SEQUENCE
ON SCHEMA::Test TO [AdventureWorks\Larry];
可以使用语句传输 ALTER AUTHORIZATION 序列对象的所有权。
如果序列使用用户定义的数据类型,则序列的创建者必须对类型具有 REFERENCES 权限。
审核
若要审核CREATE SEQUENCE,请监视 .SCHEMA_OBJECT_CHANGE_GROUP
示例
有关创建序列和使用 NEXT VALUE FOR 函数生成序列号的示例,请参阅 序列号。
下面的大多数示例都在名为 Test 的架构中创建序列对象。
若要创建 Test 架构,请执行以下语句。
CREATE SCHEMA Test;
GO
A. 创建增加 1 的序列
在以下示例中,Thierry 创建一个名为 CountBy1 的序列,该序列每次使用时都会增加一个。
CREATE SEQUENCE Test.CountBy1
START WITH 1
INCREMENT BY 1;
GO
B. 创建减少 1 的序列
以下示例从 0 开始,每次使用负数时按一个计数。
CREATE SEQUENCE Test.CountByNeg1
START WITH 0
INCREMENT BY -1;
GO
C. 创建增加 5 的序列
以下示例创建一个每次使用序列时增加 5 个序列。
CREATE SEQUENCE Test.CountBy1
START WITH 5
INCREMENT BY 5;
GO
D. 创建以指定数字开头的序列
在导入表后,Thierry 注意到所使用的最高 ID 号是 24,328。 Thierry 需要一个序列,该序列从 24,329 开始生成数字。 下面的代码将创建一个从 24,329 开始、增量为 1 的序列。
CREATE SEQUENCE Test.ID_Seq
START WITH 24329
INCREMENT BY 1;
GO
E. 使用默认值创建序列
以下示例将使用默认值创建一个序列。
CREATE SEQUENCE Test.TestSequence;
执行以下语句可查看序列的属性。
SELECT *
FROM sys.sequences
WHERE name = 'TestSequence';
输出的部分列表演示了默认值。
| 输出 | 默认值 |
|---|---|
start_value |
-9223372036854775808 |
increment |
1 |
minimum_value |
-9223372036854775808 |
maximum_value |
9223372036854775807 |
is_cycling |
0 |
is_cached |
1 |
current_value |
-9223372036854775808 |
F. 创建具有特定数据类型的序列
以下示例使用 smallint 数据类型(范围为 -32,768 到 32,767)创建一个序列。
CREATE SEQUENCE SmallSeq
AS SMALLINT;
G. 使用所有参数创建序列
以下示例使用 decimal 数据类型(范围为 0 到 255)创建一个名为 DecSeq 的序列。 序列以 125 开始,每次生成数字时递增 25。 因为该序列配置为可循环,所以,当值超过最大值 200 时,序列将从最小值 100 重新开始。
CREATE SEQUENCE Test.DecSeq
AS DECIMAL (3, 0)
START WITH 125
INCREMENT BY 25
MINVALUE 100
MAXVALUE 200
CYCLE
CACHE 3;
执行以下语句可查看第一个值;START WITH 选项为 125。
SELECT NEXT VALUE FOR Test.DecSeq;
将该语句再执行三次,以返回 150、175 和 200。
再次执行该语句,以查看起始值如何循环回到 MINVALUE 选项值 100。
执行以下代码,以确认缓存大小并查看当前值。
SELECT cache_size, current_value
FROM sys.sequences
WHERE name = 'DecSeq';