

# `CREATE SEQUENCE`
<a name="create-sequence-syntax-support"></a>

`CREATE SEQUENCE`：定义新的序列生成器。

**重要**  
在 PostgreSQL 中，指定 `CACHE` 是可选的，默认为 1。在 Amazon Aurora DSQL 等分布式系统中，序列操作涉及协调，在高并发情况下，缓存大小为 1 可能会增加协调开销。虽然较大的缓存值支持从本地预分配的范围中提供序列号，从而提高吞吐量，但未使用的保留值可能会丢失，从而使间隙和排序效果更加明显。由于应用程序对分配顺序与吞吐量的敏感度不同，因此 Amazon Aurora DSQL 要求显式指定 `CACHE` 并且目前支持 `CACHE = 1` 或 `CACHE >= 65536`，并明确区分和严格顺序生成更密切的分配行为与针对高度并发工作负载进行优化的分配。  
当使用 `CACHE >= 65536` 时，序列值仍能保证唯一性，但在不同会话间可能不会按严格的递增顺序生成，并且可能会出现间隙，尤其是在缓存的值未被充分使用的情况下。这些特征与在并发使用情况下缓存序列的 PostgreSQL 语义一致，其中两个系统都保证不同的值，但不保证在会话间采用严格顺序排序。  
在单个客户端会话中，序列值可能并非始终严格增加，尤其是在显式事务之外。此行为类似于使用连接池的 PostgreSQL 部署。通过使用 `CACHE = 1` 或在显式事务内获取序列值，可以实现更接近单会话 PostgreSQL 环境的分配行为。  
使用 `CACHE = 1`，序列分配遵循 PostgreSQL 的非缓存序列行为。  
有关如何根据工作负载模式以最佳方式使用序列的指导，请参阅[使用序列和标识列](sequences-identity-columns-working-with.md)。

## 支持的语法
<a name="create-sequence-supported-syntax"></a>

```
CREATE SEQUENCE [ IF NOT EXISTS ] name CACHE cache
    [ AS data_type ]
    [ INCREMENT [ BY ] increment ]
    [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
    [ [ NO ] CYCLE ]
    [ START [ WITH ] start ]
    [ OWNED BY { table_name.column_name | NONE } ]

where data_type is BIGINT
      and cache = 1 or cache >= 65536
```

## 说明
<a name="create-sequence-description"></a>

`CREATE SEQUENCE` 创建新的序列号生成器。这涉及创建并初始化一个新的名为 *name* 的特殊单行表。生成器将归发出命令的用户所有。

如果提供了架构名称，则在指定的架构中创建序列。否则，将在当前架构中创建序列。序列名称必须与同一架构中的任何其它关系（表、序列、索引、视图、实体化视图或外部表）的名称不同。

创建序列后，您可以使用函数 `nextval`、`currval` 和 `setval` 对序列进行操作。[序列操作函数](sequence-functions-syntax-support.md)中介绍了这些函数。

尽管您无法直接更新序列，但您可以使用如下查询：

```
SELECT * FROM name;
```

来检查序列的某些参数和当前状态。尤其是，序列的 `last_value` 字段显示任何会话分配的最后一个值。（当然，如果其它会话正在积极地进行 `nextval` 调用，则此值在打印时可能已经过时了。） 可以在 `pg_sequences` 视图中观察其它参数，例如 *increment* 和 *maxvalue*。

## 参数
<a name="create-sequence-parameters"></a>

**`IF NOT EXISTS`**  
如果同名的关系已存在，不引发错误。在这种情况下，将发出通知。请注意，不能保证现有关系与应已创建的序列有任何相似之处 — 它甚至可能不是序列。

***name***  
要创建的序列的名称（可选择架构限定）。

***data\$1type***  
可选子句 `AS data_type` 指定序列的数据类型。有效值为 `bigint`。`bigint` 为默认值。数据类型决定序列的默认最小值和最大值。

***INCREMENT***  
可选子句 `INCREMENT BY increment` 指定将哪个值添加到当前序列值以创建新值。正值将生成升序序列，负值将生成降序序列。默认值是 1。

***minvalue*/`NO MINVALUE`**  
可选子句 `MINVALUE minvalue` 确定序列可以生成的最小值。如果未提供此子句或指定了 `NO MINVALUE`，将使用默认值。升序序列的默认值为 1。降序序列的默认值是数据类型的最小值。

***maxvalue*/`NO MAXVALUE`**  
可选子句 `MAXVALUE maxvalue` 确定序列的最大值。如果未提供此子句或指定了 `NO MAXVALUE`，将使用默认值。升序序列的默认值是数据类型的最大值。降序序列的默认值为 -1。

**`CYCLE` / `NO CYCLE`**  
当升序序列或降序序列分别达到 *maxvalue* 或 *minvalue* 时，`CYCLE` 选项支持序列进行循环。如果达到限制，则生成的下一个数字将分别是 *minvalue* 或 *maxvalue*。  
如果指定了 `NO CYCLE`，则在序列达到其最大值之后对 `nextval` 的任何调用都将返回错误。如果 `CYCLE` 或 `NO CYCLE` 都未指定，则 `NO CYCLE` 为默认值。

***开启***  
可选子句 `START WITH start` 支持序列从任何地方开始。升序序列的默认起始值为 *minvalue*，降序序列的默认起始值为 *maxvalue*。

***cache***  
子句 `CACHE cache` 指定要预分配多少个序列号并将其存储在内存中，以便更快地进行访问。Aurora DSQL 中 `CACHE` 的可接受值为 1 或任何 >= 65536 的数字。最小值为 1（一次只能生成一个值，这意味着没有缓存）。

**`OWNED BY table_name.column_name` / `OWNED BY NONE`**  
`OWNED BY` 选项使序列与特定的表列相关联，这样，如果删除该列（或其整个表），也将自动删除该序列。指定的表必须与序列具有相同的所有者且位于相同架构中。默认值 `OWNED BY NONE` 指定不存在此类关联。

## 备注
<a name="create-sequence-notes"></a>

使用 [`DROP SEQUENCE`](drop-sequence-syntax-support.md) 移除序列。

序列基于 `bigint` 算法，因此范围不能超过八字节整数的范围（-9223372036854775808 到 9223372036854775807）。

由于 `nextval` 和 `setval` 调用从不会回滚，因此，如果需要“无间隙”分配序列号，则无法使用序列对象。

在一次访问序列对象期间，每个会话都会分配和缓存连续的序列值，并相应地增加序列对象的 `last_value`。然后，在该会话中下一个 *cache*-1 使用 `nextval` 时，只返回预分配的值，而不涉及序列对象。因此，当会话结束时，任何已分配但未在该会话中使用的数字都将丢失，从而导致序列中出现“空洞”。

此外，尽管可以保证多个会话分配不同的序列值，但在考虑所有会话时，这些值可能会以非顺序方式生成。例如，如果 *cache* 设置为 10，则会话 A 可能会保留值 1..10 并返回 `nextval`=1，然后会话 B 可能会在会话 A 生成 `nextval`=2 之前保留值 11..20 并返回 `nextval`=11。因此，如果 *cache* 设置为 1，则可以安全地假设 `nextval` 值是按顺序生成的；如果 *cache* 设置大于 1，则只应假设 `nextval` 值都是不同的，而不是纯粹按顺序生成的。此外，`last_value` 将反映任何会话保留的最新值，无论 `nextval` 是否已返回该值。

另一个注意事项是，在其它会话用完它们已缓存的任何预分配值之前，这些会话将不会注意到对此类序列执行的 `setval`。

## 示例
<a name="create-sequence-examples"></a>

创建一个名为 `serial` 的升序序列，从 101 开始：

```
CREATE SEQUENCE serial CACHE 65536 START 101;
```

从此序列中选择下一个数字：

```
SELECT nextval('serial');

 nextval
---------
     101
```

从此序列中选择下一个数字：

```
SELECT nextval('serial');

 nextval
---------
     102
```

在 `INSERT` 命令中使用此序列：

```
INSERT INTO distributors VALUES (nextval('serial'), 'nothing');
```

使用 `setval` 将序列重置为特定值：

```
SELECT setval('serial', 200);
SELECT nextval('serial');

 nextval
---------
     201
```

## 兼容性
<a name="create-sequence-compatibility"></a>

除以下例外情况之外，`CREATE SEQUENCE` 符合 SQL 标准：
+ 获取下一个值是使用 `nextval()` 函数而不是标准的 `NEXT VALUE FOR` 表达式完成的。
+ `OWNED BY` 子句是 PostgreSQL 扩展。