

# Aurora DSQL 和 PostgreSQL
<a name="working-with"></a>

Aurora DSQL 是与 PostgreSQL 兼容的分布式关系数据库，专为事务性工作负载而设计。Aurora DSQL 使用核心 PostgreSQL 组件，例如解析器、规划器、优化器和类型系统。

Aurora DSQL 的设计可确保所有受支持的 PostgreSQL 语法都提供兼容的行为并生成完全相同的查询结果。例如，Aurora DSQL 提供与 PostgreSQL 完全相同的类型转换、算术运算以及数值精度和小数位数。任何偏差都记录在案。

Aurora DSQL 还引入了高级功能，例如乐观并发控制和分布式架构管理。借助这些功能，您可以利用 PostgreSQL 的熟悉的工具，同时受益于现代、云原生、分布式应用程序的性能和可扩展性。

## PostgreSQL 兼容性亮点
<a name="dsql-pg-overview-compat"></a>

Aurora DSQL 目前基于 PostgreSQL 版本 16。关键亮点包括以下各项：

**线路协议**  
Aurora DSQL 使用标准 PostgreSQL v3 线路协议。这样就可以与标准 PostgreSQL 客户端、驱动程序和工具集成。例如，Aurora DSQL 与 `psql`、`pgjdbc` 和 `psycopg` 兼容。

**SQL 语法**  
Aurora DSQL 支持事务性工作负载中常用的各种标准 PostgreSQL 表达式和函数。支持的 SQL 表达式与 PostgreSQL 生成完全相同的结果，包括以下各项：  
+ 空值的处理
+ 排序顺序行为
+ 数值运算的小数位数和精度
+ 字符串操作的等效性
有关更多信息，请参阅 [Aurora DSQL 中的 SQL 功能兼容性](working-with-postgresql-compatibility.md)。

**事务管理**  
Aurora DSQL 保留了 PostgreSQL 的主要特征，例如 ACID 事务和等同于 PostgreSQL 可重复读取的隔离级别。有关更多信息，请参阅 [Aurora DSQL 中的并发控制](working-with-concurrency-control.md)。

## 分布式架构优势
<a name="dsql-pg-overview-arch"></a>

Aurora DSQL 的分布式、无共享设计提供了超越传统单节点数据库的性能和可扩展性优势。主要功能包括以下各项：

**乐观并发控制（OCC）**  
Aurora DSQL 使用乐观并发控制模型。这种无锁方法可防止事务相互阻塞，消除死锁，并支持高吞吐量的并行执行。这些功能使得 Aurora DSQL 对于需要大规模一致性能的应用程序特别有价值。有关更多示例，请参阅 [Aurora DSQL 中的并发控制](working-with-concurrency-control.md)。

**异步 DDL 操作**  
Aurora DSQL 异步运行 DDL 操作，从而支持在架构更改期间不间断地读取和写入。其分布式架构可让 Aurora DSQL 执行以下操作：  
+ 将 DDL 操作作为后台任务运行，从而最大限度地减少中断。
+ 将目录更改协调为强一致性分布式事务。这可以确保跨所有节点的原子可见性，即使在故障或并发操作期间也是如此。
+ 跨多个可用区以完全分布式、无中心节点的方式运行，且计算层和存储层已分离。
有关在 PostgreSQL 中使用 EXPLAIN 命令的更多信息，请参阅 [Aurora DSQL 中的 DDL 和分布式事务](working-with-ddl.md)。

# Aurora DSQL 中的 SQL 功能兼容性
<a name="working-with-postgresql-compatibility"></a>

在以下各节中，了解 Aurora DSQL 对 PostgreSQL 数据类型和 SQL 命令的支持。

**Topics**
+ [Aurora DSQL 中支持的数据类型](working-with-postgresql-compatibility-supported-data-types.md)
+ [Aurora DSQL 支持的 SQL](working-with-postgresql-compatibility-supported-sql-features.md)
+ [Aurora DSQL 中支持的 SQL 命令子集](working-with-postgresql-compatibility-supported-sql-subsets.md)
+ [从 PostgreSQL 迁移到 Aurora DSQL](working-with-postgresql-compatibility-migration-guide.md)

# Aurora DSQL 中支持的数据类型
<a name="working-with-postgresql-compatibility-supported-data-types"></a>

Aurora DSQL 支持常用 PostgreSQL 类型的子集。

**Topics**
+ [数值数据类型](#numeric-data-types)
+ [字符数据类型](#character-data-types)
+ [日期和时间数据类型](#date-time-data-types)
+ [其它数据类型](#miscellaneous-data-types)
+ [查询运行时数据类型](#working-with-postgresql-compatibility-query-runtime)

## 数值数据类型
<a name="numeric-data-types"></a>

Aurora DSQL 支持以下 PostgreSQL 数值数据类型。


| 名称 | 别名 | 范围和精度 | 存储大小 | 索引支持 | 
| --- | --- | --- | --- | --- | 
| smallint | int2 | -32768 到 \$132767 | 2 字节 | 是 | 
|  `integer`  |  `int`, `int4`  |  -2147483648 到 \$12147483647  |  4 字节  | 是 | 
|  `bigint`  |  `int8`  |  -9223372036854775808 到 \$19223372036854775807  |  8 字节  | 是 | 
|  `real`  |  `float4`  |  6 位十进制精度  |  4 字节  | 是 | 
|  `double precision`  |  `float8`  |  15 位十进制精度  |  8 字节  | 是 | 
|  `numeric` [ `(`*p*, *s*`)` ]  |  `decimal` [ `(`*p*, *s*`)` ] `dec`[ `(`*p*,*s*`)`]  |  可选择的精度的精确数字。最大精度为 38，最大小数位数为 37。1 默认值为 `numeric (18,6)`。  |  8 字节 \$1 每个精度位 2 字节。最大大小为 27 字节。  | 是 | 

1：如果您在运行 `CREATE TABLE` 或 `ALTER TABLE ADD COLUMN` 时没有显式指定大小，Aurora DSQL 会强制使用默认值。Aurora DSQL 在您运行 `INSERT` 或 `UPDATE` 语句时会应用限制。

## 字符数据类型
<a name="character-data-types"></a>

Aurora DSQL 支持以下 PostgreSQL 字符数据类型。


| 名称 | 别名 | 说明 | Aurora DSQL 限制 | 存储大小 | 索引支持 | 
| --- | --- | --- | --- | --- | --- | 
|  `character` [ `(`*n*`)` ]  |  `char` [ `(`*n*`)` ]  |  固定长度字符串  |  4096 字节1   |  可变，最大可达 4100 字节  | 是 | 
|  `character varying` [ `(`*n*`)` ]  |  `varchar` [ `(`*n*`)` ]  |  长度可变的字符串  |  65535 字节1   |  可变，最大可达 65539 字节  | 是 | 
|  `bpchar` [ `(`*n*`)` ]  |    |  如果长度固定，则这是 `char` 的别名。如果长度可变，则这是 `varchar` 的别名，其中尾随空格在语义上微不足道。  |  4096 字节1   |  可变，最大可达 4100 字节  | 是 | 
|  `text`  |    |  长度可变的字符串  |  1 MiB1   |  可变，最大可达 1 MiB  | 是 | 

1：如果您在运行 `CREATE TABLE` 或 `ALTER TABLE ADD COLUMN` 时没有显式指定大小，则 Aurora DSQL 会强制使用默认值。Aurora DSQL 在您运行 `INSERT` 或 `UPDATE` 语句时会应用限制。

## 日期和时间数据类型
<a name="date-time-data-types"></a>

Aurora DSQL 支持以下 PostgreSQL 日期和时间数据类型。


| 名称 | 别名 | 说明 | Range | 解析 | 存储大小 | 索引支持 | 
| --- | --- | --- | --- | --- | --- | --- | 
|  `date`  |    |  日历日期（年、月、日）  |  4713 BC – 5874897 AD  | 1 天 |  4 字节  | 是 | 
|  `time` [ `(`*p*`)` ] [ `without time zone` ]  |  `timestamp`  |  一天中的时间，不包括时区  | 0 – 1 | 1 微秒 |  8 字节  | 是 | 
|  `time` [ `(`*p*`)` ] `with time zone`  |  `timetz`  |  一天中的时间，包括时区  |  00:00:00\$11559 – 24:00:00 –1559  | 1 微秒 |  12 字节  | 否 | 
|  `timestamp` [ `(`*p*`)` ] [ `without time zone` ]  |    |  日期和时间，不包括时区  | 4713 BC – 294276 AD | 1 微秒 |  8 字节  | 是 | 
|  `timestamp` [ `(`*p*`)` ] `with time zone`  |  `timestamptz`  |  日期和时间，包括时区  | 4713 BC – 294276 AD | 1 微秒 |  8 字节  | 是 | 
|  `interval` [ `fields` ] [ `(`*p*`)` ]  |    |  时间跨度  | -178000000 年 – 178000000 年 | 1 微秒 |  16 字节  | 否 | 

## 其它数据类型
<a name="miscellaneous-data-types"></a>

Aurora DSQL 支持以下其它 PostgreSQL 数据类型。


| 名称 | 别名 | 说明 | Aurora DSQL 限制 | 存储大小 | 索引支持 | 
| --- | --- | --- | --- | --- | --- | 
|  `boolean`  |  `bool`  |  逻辑布尔值 (true/false)  |    |  1 字节  | 是 | 
|  `bytea`  |    |  二进制数据（“字节数组”）  |  1 MiB1   |  可变，最大可达 1 MiB 限制  | 否 | 
|  `UUID`  |    |  通用唯一标识符  |    |  16 字节  | 是 | 

1：如果您在运行 `CREATE TABLE` 或 `ALTER TABLE ADD COLUMN` 时没有显式指定大小，则 Aurora DSQL 会强制使用默认值。Aurora DSQL 在您运行 `INSERT` 或 `UPDATE` 语句时会应用限制。

## 查询运行时数据类型
<a name="working-with-postgresql-compatibility-query-runtime"></a>

查询运行时数据类型是在查询执行时使用的内部数据类型。这些类型不同于您在架构中定义的 PostgreSQL 兼容类型，如 `varchar` 和 `integer`。相反，这些类型是 Aurora DSQL 在处理查询时使用的运行时表示形式。

仅在查询运行时期间才支持以下数据类型：

**数组类型**  
Aurora DSQL 支持所支持数据类型的数组。例如，您可能具有一个整数数组。函数 `string_to_array` 使用逗号分隔符 (`,`) 将字符串拆分为 PostgreSQL 样式的数组，如以下示例所示。在查询执行期间，可以在表达式、函数输出或临时计算中使用数组。  

```
SELECT string_to_array('1,2', ',');
```
该函数返回类似于以下内容的响应：  

```
 string_to_array 
-----------------
 {1,2}
(1 row)
```

****inet 类型****  
此数据类型表示 IPv4、IPv6 主机地址及其子网。此类型在解析日志、根据 IP 子网进行筛选或在查询中进行网络计算时很有用。有关更多信息，请参阅 PostgreSQL 文档中的 [inet](https://www.PostgreSQL.org/docs/16/datatype-net-types.html#DATATYPE-INET)。

**JSON 运行时函数**  
Aurora DSQL 支持将 JSON 和 JSONB 作为运行时数据类型来进行查询处理。将 JSON 数据存储为 `text` 列，然后在查询执行期间强制转换为 JSON，以便使用 PostgreSQL JSON 函数和运算符。  
Aurora DSQL 支持 [section 9.1.6 JSON Functions and Operators](https://www.postgresql.org/docs/current/functions-json.html) 中的大多数 PostgreSQL 函数，并且具有相同的行为。  
返回 JSON 或 JSONB 类型的函数可能需要进一步转换为 `text` 才能正确显示。  

```
SELECT json_build_array(1, 2, 'foo', 4, 5)::text;
```
该函数返回类似于以下内容的响应：  

```
     json_build_array
 ---------------------
   [1, 2, "foo", 4, 5]
 (1 row)
```

# Aurora DSQL 支持的 SQL
<a name="working-with-postgresql-compatibility-supported-sql-features"></a>

Aurora DSQL 支持各种核心 PostgreSQL SQL 功能。在以下各节中，您可以了解有关 PostgreSQL 表达式的一般支持。此列表并不详尽。

## `SELECT` 命令
<a name="dsql-select"></a>

Aurora DSQL 支持 `SELECT` 命令的以下子句。


| 主要子句 | 支持的子句 | 
| --- | --- | 
|  `FROM`  |    | 
|  `GROUP BY`  |  `ALL`, `DISTINCT`  | 
|  `ORDER BY`  |  `ASC`, `DESC`, `NULLS`  | 
|  `LIMIT`  |    | 
|  `DISTINCT`  |    | 
|  `HAVING`  |    | 
|  `USING`  |    | 
|  `WITH`（公用表表达式）  |    | 
|  `INNER JOIN`  |  `ON`  | 
|  `OUTER JOIN`  |  `LEFT`, `RIGHT`, `FULL`, `ON`  | 
|  `CROSS JOIN`  |  `ON`  | 
|  `UNION`  |  `ALL`  | 
|  `INTERSECT`  |  `ALL`  | 
|  `EXCEPT`  |  `ALL`  | 
|  `OVER`  |  `RANK ()`, `PARTITION BY`  | 
|  `FOR UPDATE`  |    | 

## 数据定义语言 (DDL)
<a name="dsql-ddl"></a>

Aurora DSQL 支持以下 PostgreSQL DDL 命令。


| 命令 | 主要子句 | 支持的子句 | 
| --- | --- | --- | 
|  `CREATE`  |  `TABLE`  |  有关 `CREATE TABLE` 命令支持的语法的信息，请参阅 [`CREATE TABLE`](create-table-syntax-support.md)。  | 
|  `ALTER`  |  `TABLE`  |  有关 `ALTER TABLE` 命令支持的语法的信息，请参阅 [`ALTER TABLE`](alter-table-syntax-support.md)。  | 
|  `DROP`  |  `TABLE`  |    | 
|  `CREATE`  |  `[UNIQUE] INDEX ASYNC`  |  您可以将此命令与以下参数结合使用：`ON`、`NULLS FIRST`、`NULLS LAST`。 有关 `CREATE INDEX ASYNC` 命令支持的语法的信息，请参阅 [Aurora DSQL 中的异步索引](working-with-create-index-async.md)。  | 
|  `DROP`  |  `INDEX`  |    | 
|  `CREATE`  |  `VIEW`  |  有关 `CREATE VIEW` 命令支持的语法的更多信息，请参阅 [`CREATE VIEW`](create-view.md)。  | 
| ALTER | VIEW |  有关 `ALTER VIEW` 命令支持的语法的信息，请参阅 [`ALTER VIEW`](alter-view-syntax-support.md)。  | 
| DROP | VIEW | 有关 DROP VIEW 命令支持的语法的信息，请参阅 [`DROP VIEW`](drop-view-overview.md)。 | 
|  `CREATE`  |  `SEQUENCE`  |  有关 `CREATE SEQUENCE` 命令支持的语法的信息，请参阅 [`CREATE SEQUENCE`](create-sequence-syntax-support.md)。  | 
|  `ALTER`  |  `SEQUENCE`  |  有关 `ALTER SEQUENCE` 命令支持的语法的信息，请参阅 [`ALTER SEQUENCE`](alter-sequence-syntax-support.md)。  | 
|  `DROP`  |  `SEQUENCE`  |  有关 `DROP SEQUENCE` 命令支持的语法的信息，请参阅 [`DROP SEQUENCE`](drop-sequence-syntax-support.md)。  | 
|  `CREATE`  |  `ROLE`, `WITH`  |    | 
|  `CREATE`  |  `FUNCTION`  |  `LANGUAGE SQL`  | 
|  `CREATE`  |  `DOMAIN`  |    | 

## 数据操作语言 (DML)
<a name="dsql-dml"></a>

Aurora DSQL 支持以下 PostgreSQL DML 命令。


| 命令 | 主要子句 | 支持的子句 | 
| --- | --- | --- | 
|  `INSERT`  |  `INTO`  | `VALUES`SELECT | 
|  `UPDATE`  |  `SET`  |  `WHERE (SELECT)` `FROM, WITH`  | 
| DELETE | FROM | USING, WHERE | 

## 数据控制语言（DCL）
<a name="dsql-dcl"></a>

Aurora DSQL 支持以下 PostgreSQL DCL 命令。


| 命令 | 支持的子句 | 
| --- | --- | 
|  `GRANT`  |  `ON`, `TO`  | 
|  `REVOKE`  |  `ON`, `FROM`, `CASCADE`, `RESTRICT`  | 

## 事务控制语言（TCL）
<a name="dsql-tcl"></a>

Aurora DSQL 支持以下 PostgreSQL TCL 命令。


| 命令 | 支持的子句 | 别名 | 
| --- | --- | --- | 
|  `COMMIT`  |  [`WORK` \$1 `TRANSACTION`] [`AND NO CHAIN`]  |  `END`  | 
|  `BEGIN`  |  [`WORK` \$1 `TRANSACTION`] [`ISOLATION LEVEL REPEATABLE READ`] [`READ WRITE` \$1 `READ ONLY`]  |    | 
|  `START TRANSACTION`  |  [`ISOLATION LEVEL REPEATABLE READ`] [`READ WRITE` \$1 `READ ONLY`]  |    | 
|  `ROLLBACK`  |  [`WORK` \$1 `TRANSACTION`] [`AND NO CHAIN`]  |  `ABORT`  | 

## 实用程序命令
<a name="dsql-utility"></a>

Aurora DSQL 支持以下 PostgreSQL 实用程序命令：
+ `EXPLAIN`
+ `ANALYZE`（仅限关系名称）

# Aurora DSQL 中支持的 SQL 命令子集
<a name="working-with-postgresql-compatibility-supported-sql-subsets"></a>

本节提供有关支持的 SQL 命令的详细信息，重点介绍具有大量参数集和子命令的命令。例如，PostgreSQL 中的 CREATE TABLE 提供了许多子句和参数，Aurora DSQL 支持其中的一个子集。本节介绍使用 Aurora DSQL 支持的熟悉的 PostgreSQL 语法元素支持的常见 SQL 命令的子集。

**Topics**
+ [`CREATE TABLE`](create-table-syntax-support.md)
+ [`ALTER TABLE`](alter-table-syntax-support.md)
+ [`CREATE SEQUENCE`](create-sequence-syntax-support.md)
+ [`ALTER SEQUENCE`](alter-sequence-syntax-support.md)
+ [`DROP SEQUENCE`](drop-sequence-syntax-support.md)
+ [`CREATE VIEW`](create-view.md)
+ [`ALTER VIEW`](alter-view-syntax-support.md)
+ [`DROP VIEW`](drop-view-overview.md)

# `CREATE TABLE`
<a name="create-table-syntax-support"></a>

`CREATE TABLE` 定义一个新表。

```
CREATE TABLE [ IF NOT EXISTS ] table_name ( [
  { column_name data_type [ column_constraint [ ... ] ]
    | table_constraint
    | LIKE source_table [ like_option ... ] }
    [, ... ]
] )

where column_constraint is:

[ CONSTRAINT constraint_name ]
{ NOT NULL |
  NULL |
  CHECK ( expression )|
  DEFAULT default_expr |
  GENERATED ALWAYS AS ( generation_expr ) STORED |
  GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY ( sequence_options ) |
  UNIQUE [ NULLS [ NOT ] DISTINCT ] index_parameters |
  PRIMARY KEY index_parameters |

and table_constraint is:

[ CONSTRAINT constraint_name ]
{ CHECK ( expression ) |
  UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] ) index_parameters |
  PRIMARY KEY ( column_name [, ... ] ) index_parameters |

and like_option is:

{ INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | ALL }

index_parameters in UNIQUE, and PRIMARY KEY constraints are:
[ INCLUDE ( column_name [, ... ] ) ]
```

## 标识列
<a name="create-table-identity-columns"></a>

**注意**  
使用标识列时，应谨慎考虑缓存值。有关更多信息，请参阅 [`CREATE SEQUENCE`](create-sequence-syntax-support.md) 页面上的“重要提示”标注。  
有关如何根据工作负载模式以最佳方式使用标识列的指导，请参阅[使用序列和标识列](sequences-identity-columns-working-with.md)。

`GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY ( sequence_options )` 子句将列创建为*标识列*。它将附加一个隐式序列，在新插入的行中，该列将自动具有序列中分配给它的值。这样的列隐式为 `NOT NULL`。

子句 `ALWAYS` 和 `BY DEFAULT` 决定了在 `INSERT` 和 `UPDATE` 命令中如何显式处理用户指定的值。

在 `INSERT` 命令中，如果选择了 `ALWAYS`，则只有在 `INSERT` 语句指定 `OVERRIDING SYSTEM VALUE` 时才接受用户指定的值。如果选择了 `BY DEFAULT`，则优先使用用户指定的值。

在 `UPDATE` 命令中，如果选择 `ALWAYS`，则将列更新为除 `DEFAULT` 以外的任何值都将遭到拒绝。如果选择 `BY DEFAULT`，则可以正常更新该列。（`UPDATE` 命令没有 `OVERRIDING` 子句。）

*sequence\$1options* 子句可用于覆盖序列的参数。可用的选项包括为 [`CREATE SEQUENCE`](create-sequence-syntax-support.md) 显示的选项，另加 `SEQUENCE NAME name`。如果没有 `SEQUENCE NAME`，则系统会为序列选择一个未使用的名称。

# `ALTER TABLE`
<a name="alter-table-syntax-support"></a>

`ALTER TABLE` 更改表的定义。

```
ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
    action [, ... ]
ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
    RENAME [ COLUMN ] column_name TO new_column_name
ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
    RENAME CONSTRAINT constraint_name TO new_constraint_name
ALTER TABLE [ IF EXISTS ] name
    RENAME TO new_name
ALTER TABLE [ IF EXISTS ] name
    SET SCHEMA new_schema

where action is one of:

    ADD [ COLUMN ] [ IF NOT EXISTS ] column_name data_type
    ALTER [ COLUMN ] column_name { SET GENERATED { ALWAYS | BY DEFAULT } | SET sequence_option | RESTART [ [ WITH ] restart ] } [...]
    ALTER [ COLUMN ] column_name DROP IDENTITY [ IF EXISTS ]
    OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
```

## 标识列操作
<a name="alter-table-identity-columns"></a>

**`SET GENERATED { ALWAYS | BY DEFAULT }` / `SET sequence_option` / `RESTART`**  
这些格式更改列是否为标识列，或更改现有标识列的生成属性。有关详细信息，请参阅 [`CREATE TABLE`](create-table-syntax-support.md)。比如 `SET DEFAULT`，这些格式只影响后续 `INSERT` 和 `UPDATE` 命令的行为；它们不会导致表中已有的行发生变化。  
*sequence\$1option* 是 [`ALTER SEQUENCE`](alter-sequence-syntax-support.md)（如 `INCREMENT BY`）支持的选项。这些格式更改现有标识列所基于的序列。

**`DROP IDENTITY [ IF EXISTS ]`**  
此格式从列中移除标识属性。如果指定了 `DROP IDENTITY IF EXISTS` 并且该列不是标识列，则不会引发任何错误。在这种情况下，将改为发出通知。

# `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 扩展。

# `ALTER SEQUENCE`
<a name="alter-sequence-syntax-support"></a>

`ALTER SEQUENCE`：更改序列生成器的定义。

**重要**  
使用序列时，应谨慎考虑缓存值。有关更多信息，请参阅 [`CREATE SEQUENCE`](create-sequence-syntax-support.md) 页面上的“重要提示”标注。  
有关如何根据工作负载模式以最佳方式使用序列的指导，请参阅[使用序列和标识列](sequences-identity-columns-working-with.md)。

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

```
ALTER SEQUENCE [ IF EXISTS ] name
    [ INCREMENT [ BY ] increment ]
    [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
    [ [ NO ] CYCLE ]
    [ START [ WITH ] start ]
    [ RESTART [ [ WITH ] restart ] ]
    [ CACHE cache ]
    [ OWNED BY { table_name.column_name | NONE } ]
ALTER SEQUENCE [ IF EXISTS ] name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
ALTER SEQUENCE [ IF EXISTS ] name RENAME TO new_name
ALTER SEQUENCE [ IF EXISTS ] name SET SCHEMA new_schema

where cache is 1 or cache >= 65536
```

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

`ALTER SEQUENCE` 更改现有序列生成器的参数。`ALTER SEQUENCE` 命令中未特别设置的任何参数都将保留其先前的设置。

您必须拥有该序列的所有权才能使用 `ALTER SEQUENCE`。要更改序列的架构，您还必须对新架构具有 `CREATE` 权限。要更改所有者，您必须能够 `SET ROLE` 以使用新的拥有角色，并且该角色必须对序列的架构拥有 `CREATE` 权限。（这些限制强制要求：更改所有者不会执行任何您无法通过删除并重新创建序列来完成的事情。但是，无论如何，超级用户都可以更改任何序列的所有权。）

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

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

**`IF EXISTS`**  
如果序列不存在，不引发错误。在这种情况下，将发出通知。

***INCREMENT***  
子句 `INCREMENT BY increment` 是可选的。正值将生成升序序列，负值将生成降序序列。如果未指定，将保留旧的增量值。

***minvalue*/`NO MINVALUE`**  
可选子句 `MINVALUE minvalue` 确定序列可以生成的最小值。如果指定了 `NO MINVALUE`，则将分别对升序序列和降序序列使用默认值 1 和数据类型的最小值。如果两个选项都未指定，则将保持当前的最小值。

***maxvalue*/`NO MAXVALUE`**  
可选子句 `MAXVALUE maxvalue` 确定序列的最大值。如果指定了 `NO MAXVALUE`，则将分别使用数据类型的最大值（对于升序序列）和 -1（对于降序序列）作为默认值。如果两个选项都未指定，则将保持当前的最大值。

**`CYCLE`**  
当升序降序或降序序列分别达到 *maxvalue* 或 *minvalue* 时，可以使用可选的 `CYCLE` 关键字来使序列循环。如果达到限制，则生成的下一个数字将分别是 *minvalue* 或 *maxvalue*。

**`NO CYCLE`**  
如果指定了可选的 `NO CYCLE` 关键字，则在序列达到其最大值之后对 `nextval` 的任何调用都将返回错误。如果 `CYCLE` 或 `NO CYCLE` 都未指定，则将保持旧的循环行为。

***开启***  
可选子句 `START WITH start` 更改序列的已记录的起始值。这对当前序列值没有影响；它只是设置将来的 `ALTER SEQUENCE RESTART` 命令将使用的值。

***重新开始***  
可选子句 `RESTART [ WITH restart ]` 更改序列的当前值。这类似于通过 `is_called` = `false` 调用 `setval` 函数：下次调用 `nextval` 将返回指定的值。在没有 *restart* 值的情况下编写 `RESTART` 等同于提供由 `CREATE SEQUENCE` 记录或由 `ALTER SEQUENCE START WITH` 上次设置的起始值。  
与 `setval` 调用相比，针对序列的 `RESTART` 操作是事务性的，它会阻止并发事务从同一序列中获取数字。如果这不是所需的操作模式，则应使用 `setval`。

***cache***  
子句 `CACHE cache` 支持预分配序列号并将其存储在内存中，以便更快地进行访问。该值必须为 1 或某个 >= 65536 的值。如果未指定，将保留旧的缓存值。有关缓存行为的更多信息，请参阅 [`CREATE SEQUENCE`](create-sequence-syntax-support.md) 下的指南。

**`OWNED BY table_name.column_name` / `OWNED BY NONE`**  
`OWNED BY` 选项使序列与特定的表列相关联，这样，如果删除该列（或其整个表），也将自动删除该序列。如果指定，则此关联将替换先前为序列指定的任何关联。指定的表必须与序列具有相同的所有者，并且与序列处于相同的架构中。指定 `OWNED BY NONE` 会移除任何现有的关联，使序列变为“独立的”。

***new\$1owner***  
序列的新所有者的用户名。

***new\$1name***  
序列的新名称。

***new\$1schema***  
序列的新架构。

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

`ALTER SEQUENCE` 不会立即影响具有预分配（缓存）序列值的后端（当前后端除外）中的 `nextval` 结果。在注意到更改的序列生成参数之前，它们将用完所有缓存的值。当前后端将立即受到影响。

`ALTER SEQUENCE` 不会影响序列的 `currval` 状态。

`ALTER SEQUENCE` 可能会导致 OCC 发生其它事务。

出于历史原因，`ALTER TABLE` 也可以与序列一起使用；但仅支持与上述格式等效的 `ALTER TABLE` 变体用于序列。

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

在 105 处重新启动一个名为 `serial` 的序列：

```
ALTER SEQUENCE serial RESTART WITH 105;
```

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

`ALTER SEQUENCE` 符合 SQL 标准，但 `AS`、`START WITH`、`OWNED BY`、`OWNER TO`、`RENAME TO` 和 `SET SCHEMA` 子句除外，它们是 PostgreSQL 扩展。

# `DROP SEQUENCE`
<a name="drop-sequence-syntax-support"></a>

`DROP SEQUENCE`：移除序列。

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

```
DROP SEQUENCE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
```

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

`DROP SEQUENCE` 移除序列号生成器。序列只能由其所有者或超级用户删除。

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

**`IF EXISTS`**  
如果序列不存在，不引发错误。在这种情况下，将发出通知。

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

**`CASCADE`**  
自动删除依赖于序列的对象，进而删除依赖于这些对象的所有对象。

**`RESTRICT`**  
如果任何对象依赖于该序列，则拒绝删除该序列。这是默认值。

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

要移除序列 `seq`：

```
DROP SEQUENCE seq;
```

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

`DROP SEQUENCE` 符合 SQL 标准，但该标准仅允许每个命令删除一个序列，并且 `IF EXISTS` 选项是一个 PostgreSQL 扩展，不在此标准之列。

# `CREATE VIEW`
<a name="create-view"></a>

`CREATE VIEW` 定义新的持久视图。Aurora DSQL 不支持临时视图；仅支持持久视图。

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

```
CREATE [ OR REPLACE ] [ RECURSIVE ] VIEW name [ ( column_name [, ...] ) ]
    [ WITH ( view_option_name [= view_option_value] [, ... ] ) ]
    AS query
    [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
```

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

`CREATE VIEW` 定义查询的视图。此视图并未实际实现。相反，每次在查询中引用视图时，都会运行查询。

`CREATE or REPLACE VIEW` 与之类似，但如果同名的视图已经存在，则将替换该视图。新查询生成的列必须与现有视图查询生成的列相同（即顺序相同且数据类型相同的列名），但它可能会在列表末尾添加其它列。产生输出列的计算方法可能有所不同。

如果提供架构名称（例如 `CREATE VIEW myschema.myview ...`），则在指定的架构中创建视图。否则，将在当前架构中创建该视图。

视图的名称必须与同一架构中任何其它关系（表、索引、视图）的名称不同。

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

`CREATE VIEW` 支持各种参数来控制可自动更新的视图的行为。

**`RECURSIVE`**  
创建递归视图。语法：`CREATE RECURSIVE VIEW [ schema . ] view_name (column_names) AS SELECT ...;` 等同于 `CREATE VIEW [ schema . ] view_name AS WITH RECURSIVE view_name (column_names) AS (SELECT ...) SELECT column_names FROM view_name;`。  
必须为递归视图指定视图列名列表。

**`name`**  
要创建的视图的名称，可以选择使用架构进行限定。必须为递归视图指定列名列表。

**`column_name`**  
要用于视图中各列的名称的可选列表。如果未提供，则从查询中推断出列名。

**`WITH ( view_option_name [= view_option_value] [, ... ] )`**  
此子句为视图指定可选参数；支持以下参数。  
+ `check_option (enum)`：此参数可以为 `local` 或 `cascaded`，等同于指定 `WITH [ CASCADED | LOCAL ] CHECK OPTION`。
+ `security_barrier (boolean)`：如果视图旨在提供行级安全性，则应使用此参数。Aurora DSQL 目前不支持行级安全性，但此选项仍会强制首先评估视图的 `WHERE` 条件（以及任何使用标记为 `LEAKPROOF` 的运算符的条件）。
+ `security_invoker (boolean)`：此选项会导致根据视图用户而不是视图所有者的权限来检查底层基本关系。有关完整详细信息，请参阅下面的备注。
可以使用 `ALTER VIEW` 在现有视图上更改上述所有选项。

**`query`**  
`SELECT` 或 `VALUES` 命令，它们将提供视图的列和行。

**`WITH [ CASCADED | LOCAL ] CHECK OPTION`**  
此选项控制可自动更新的视图的行为。指定此选项后，将检查视图上的 `INSERT` 和 `UPDATE` 命令，以确保新行满足视图定义条件（也就是说，检查新行以确保它们在视图中可见）。否则，将拒绝更新。如果未指定 `CHECK OPTION`，则支持视图上的 `INSERT` 和 `UPDATE` 命令创建在视图中不可见的行。  
`LOCAL`：仅根据在视图本身中直接定义的条件来检查新行。不检查在底层基本视图上定义的任何条件（除非它们也指定了 `CHECK OPTION`）。  
`CASCADED`：根据视图和所有底层基本视图的条件检查新行。如果指定了 `CHECK OPTION`，但既未指定 `LOCAL` 也未指定 `CASCADED`，则假定为 `CASCADED`。  
`CHECK OPTION` 不得与 `RECURSIVE` 视图一起使用。仅在可自动更新的视图上才支持 `CHECK OPTION`。

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

使用 `DROP VIEW` 语句可删除视图。

应仔细考虑视图列的名称和数据类型。例如，不建议使用 CREATE VIEW vista AS SELECT 'Hello World';，因为列名称默认为 `?column?;`。此外，列的数据类型默认为 `text`，这可能不是您想要的。

更好的方法是显式指定列名和数据类型，例如：`CREATE VIEW vista AS SELECT text 'Hello World' AS hello;`。

默认情况下，对视图中引用的底层基本关系的访问权限由视图所有者的权限决定。在某些情况下，这可用于提供对底层表的安全但受限的访问。但是，并非所有视图都能防止篡改。
+ 如果视图的 `security_invoker` 属性设置为 true，则对底层基本关系的访问权限取决于执行查询的用户的权限，而不是视图所有者的权限。因此，安全调用程序视图的用户必须对该视图及其底层基本关系拥有相关权限。
+ 如果任何底层基本关系是安全调用程序视图，则会被视为直接从原始查询访问了该视图。因此，安全调用程序视图将始终使用当前用户的权限来检查其底层基本关系，即使从没有 `security_invoker` 属性的视图访问该视图也是如此。
+ 视图中调用的函数的处理方式与使用视图直接从查询中调用函数的处理方式相同。因此，视图的用户必须具有权限来调用该视图使用的所有函数。视图中的函数是以执行查询的用户或函数所有者的权限来执行的，具体取决于函数是定义为 `SECURITY INVOKER` 还是 `SECURITY DEFINER`。
+ 创建或替换视图的用户必须对视图查询中引用的任何架构具有 `USAGE` 权限，才能在这些架构中查找引用的对象。
+ 在现有视图上使用 `CREATE OR REPLACE VIEW` 时，仅更改视图的定义 `SELECT` 规则以及任何 `WITH ( ... )`参数及其 `CHECK OPTION`。其它视图属性（包括所有权、权限和非 SELECT 规则）保持不变。您必须拥有视图才能替换它（这包括成为拥有角色的成员）。

## 可更新视图
<a name="create-view-updatable-view"></a>

简单视图可自动更新：系统将支持在视图上使用 `INSERT`、`UPDATE` 和 `DELETE` 语句，其方式与在常规表上相同。如果视图满足以下所有条件，则该视图可自动更新：
+ 视图在其 `FROM` 列表中必须确切只有一个条目，该条目必须是一个表或另一个可更新的视图。
+ 视图定义不得在顶层包含 `WITH`、`DISTINCT`、`GROUP BY`、`HAVING`、`LIMIT` 或 `OFFSET` 子句。
+ 视图定义不得在顶层包含集合操作（`UNION`、`INTERSECT` 或 `EXCEPT`）。
+ 视图的选择列表不得包含任何聚合、窗口函数或返回集合的函数。

可自动更新的视图可能包含可更新和不可更新的列的组合。如果列是对底层基本关系的可更新列的简单引用，则该列是可更新的。否则，该列是只读的，如果 `INSERT` 或 `UPDATE` 语句尝试为其赋值，则会发生错误。

默认情况下，未满足所有这些条件的更复杂的视图是只读的：系统不支持在视图上执行插入、更新或删除操作。

**注意**  
在视图上执行插入、更新或删除操作的用户必须对该视图具有相应的插入、更新或删除权限。默认情况下，视图的所有者必须对底层基本关系拥有相关的权限，而执行更新的用户不需要对底层基本关系拥有任何权限。但是，如果视图将 security\$1invoker 设置为 true，则执行更新的用户（而不是视图所有者）必须对底层基本关系拥有相关权限。

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

创建由所有喜剧电影组成的视图。

```
CREATE VIEW comedies AS
    SELECT *
    FROM films
    WHERE kind = 'Comedy';
```

使用 `LOCAL CHECK OPTION` 创建视图。

```
CREATE VIEW pg_comedies AS
    SELECT *
    FROM comedies
    WHERE classification = 'PG'
    WITH CASCADED CHECK OPTION;
```

创建递归视图。

```
CREATE RECURSIVE VIEW public.nums_1_100 (n) AS
    VALUES (1)
UNION ALL
    SELECT n+1 FROM nums_1_100 WHERE n < 100;
```

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

`CREATE OR REPLACE VIEW` 是 PostgreSQL 语言扩展。`WITH ( ... )` 子句也是扩展，安全屏障视图和安全调用程序视图也是如此。Aurora DSQL 支持这些语言扩展。

# `ALTER VIEW`
<a name="alter-view-syntax-support"></a>

`ALTER VIEW` 语句支持更改现有视图的各种属性，并且 Aurora DSQL 支持此命令的所有 PostgreSQL 语法。

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

```
ALTER VIEW [ IF EXISTS ] name ALTER [ COLUMN ] column_name SET DEFAULT expression
ALTER VIEW [ IF EXISTS ] name ALTER [ COLUMN ] column_name DROP DEFAULT
ALTER VIEW [ IF EXISTS ] name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
ALTER VIEW [ IF EXISTS ] name RENAME [ COLUMN ] column_name TO new_column_name
ALTER VIEW [ IF EXISTS ] name RENAME TO new_name
ALTER VIEW [ IF EXISTS ] name SET SCHEMA new_schema
ALTER VIEW [ IF EXISTS ] name SET ( view_option_name [= view_option_value] [, ... ] )
ALTER VIEW [ IF EXISTS ] name RESET ( view_option_name [, ... ] )
```

## 说明
<a name="alter-view-description"></a>

`ALTER VIEW` 更改视图的各种辅助属性。（如果要修改视图的定义查询，请使用 `CREATE OR REPLACE VIEW`。） 您必须拥有该视图的所有权才能使用 `ALTER VIEW`。要更改视图的架构，您还必须对新架构具有 `CREATE` 权限。要更改所有者，您必须能够 `SET ROLE` 以使用新的拥有角色，并且该角色必须对视图的架构拥有 `CREATE` 权限。

## 参数
<a name="alter-view-parameters"></a>

**`name`**  
现有视图的名称（可选择架构限定）。

**`column_name`**  
现有列的名称，或现有列的新名称。

**`IF EXISTS`**  
如果视图不存在，不引发错误。在这种情况下，将发出通知。

**`SET/DROP DEFAULT`**  
这些表单为列设置或移除默认值。视图列的默认值会替换为任何以视图为目标的 `INSERT` 或 `UPDATE` 命令。

**`new_owner`**  
视图的新所有者的用户名。

**`new_name`**  
视图的新名称。

**`new_schema`**  
视图的新架构。

**`SET ( view_option_name [= view_option_value] [, ... ] )`**  
设置视图选项。以下是支持的选项：  
+ `check_option (enum)`：更改视图的检查选项。值必须为 `local` 或 `cascaded`。
+ `security_barrier (boolean)`：更改视图的 security-barrier 属性。
+ `security_invoker (boolean)`：更改视图的 security-invoker 属性。

**`RESET ( view_option_name [, ... ] )`**  
将视图选项重置为其默认值。

## 示例
<a name="alter-view-examples"></a>

将视图 `foo` 重命名为 `bar`：

```
ALTER VIEW foo RENAME TO bar;
```

将默认列值附加到可更新的视图：

```
CREATE TABLE base_table (id int, ts timestamptz);
CREATE VIEW a_view AS SELECT * FROM base_table;
ALTER VIEW a_view ALTER COLUMN ts SET DEFAULT now();
INSERT INTO base_table(id) VALUES(1);  -- ts will receive a NULL
INSERT INTO a_view(id) VALUES(2);  -- ts will receive the current time
```

## 兼容性
<a name="alter-view-compatibility"></a>

`ALTER VIEW` 是 Aurora DSQL 支持的 SQL 标准的 PostgreSQL 扩展。

# `DROP VIEW`
<a name="drop-view-overview"></a>

`DROP VIEW` 语句移除现有视图。Aurora DSQL 支持此命令的完整 PostgreSQL 语法。

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

```
DROP VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
```

## 说明
<a name="drop-view-description"></a>

`DROP VIEW` 删除现有视图。要执行此命令，您必须是视图的所有者。

## 参数
<a name="drop-view-parameters"></a>

**`IF EXISTS`**  
如果视图不存在，不引发错误。在这种情况下，将发出通知。

**`name`**  
要移除的视图的名称（可选择架构限定）。

**`CASCADE`**  
自动删除依赖于视图的对象（如其它视图），进而删除依赖于这些对象的所有对象。

**`RESTRICT`**  
如果任何对象依赖于该视图，则拒绝删除该视图。这是默认值。

## 示例
<a name="drop-view-examples"></a>

```
DROP VIEW kinds;
```

## 兼容性
<a name="drop-view-compatibility"></a>

此命令符合 SQL 标准，除了该标准只支持每个命令删除一个视图，并且 `IF EXISTS` 选项除外（这是 Aurora DSQL 支持的 PostgreSQL 扩展）。

# 从 PostgreSQL 迁移到 Aurora DSQL
<a name="working-with-postgresql-compatibility-migration-guide"></a>

Aurora DSQL 设计为[与 PostgreSQL 兼容](working-with-postgresql-compatibility.md)，支持诸如 ACID 事务、辅助索引、联接和标准 DML 操作等核心关系功能。大多数现有 PostgreSQL 应用程序只需进行极少的更改，即可迁移到 Aurora DSQL。

本节提供将应用程序迁移到 Aurora DSQL 的实用指南，包括框架兼容性、迁移模式和架构注意事项。

## 框架和 ORM 兼容性
<a name="dsql-framework-compatibility"></a>

 Aurora DSQL 使用标准 PostgreSQL 线路协议，同时确保与 PostgreSQL 驱动程序和框架的兼容性。大多数流行的 ORM 与 Aurora DSQL 一起工作，而只需进行极少的更改或不需要更改。有关参考实现和可用的 ORM 集成，请参阅 [Aurora DSQL 适配器和方言](aws-sdks.md#aurora-dsql-adapters)。

## 常见迁移模式
<a name="working-with-postgresql-compatibility-migration-considerations"></a>

 从 PostgreSQL 迁移到 Aurora DSQL 时，某些功能的工作原理会有所不同或具有其它语法。本节提供有关常见迁移场景的指导。

### DDL 操作替代方案
<a name="dsql-ddl-alternatives"></a>

Aurora DSQL 为传统的 PostgreSQL DDL 操作提供了现代替代方案：

**索引创建**  
使用 `CREATE INDEX ASYNC` 而非 `CREATE INDEX` 来创建非阻止索引。  
**优势：**在大型表上创建零停机时间索引。

**数据移除**  
使用 `DELETE FROM table_name`，而不使用 `TRUNCATE`。  
**替代方案：**要完全重新创建表，请使用 `DROP TABLE`，后跟 `CREATE TABLE`。

**系统配置**  
Aurora DSQL 是完全托管式的，因此，配置是根据工作负载模式自动处理的。使用 AWS 管理控制台或 API 来管理集群设置。  
**优点：**无需进行数据库调整或参数管理。

### 架构设计模式
<a name="dsql-schema-design-patterns"></a>

调整以下常见的 PostgreSQL 模式以实现 Aurora DSQL 兼容性：

**引用完整性模式**  
Aurora DSQL 支持表关系和 `JOIN` 操作。为实现引用完整性，请在应用程序层中实现验证。这种设计与现代分布式数据库模式保持一致，在这种模式中，应用程序层验证可提供更大的灵活性，并可避免级联操作带来的性能瓶颈。  
**模式：**使用一致的命名约定、验证逻辑和事务边界，在应用程序层中实施引用完整性检查。许多大规模应用程序更喜欢这种方法，以便更好地控制错误处理和性能。

**临时数据处理**  
使用带有清理逻辑的 CTE、子查询或常规表，而不是临时表。  
**替代方案：**使用会话特定的名称创建表，然后在应用程序中对其进行清理。

## 了解架构差异
<a name="working-with-postgresql-compatibility-architectural-differences"></a>

Aurora DSQL 的分布式无服务器架构在若干方面有意与传统 PostgreSQL 有所不同。这些差异使 Aurora DSQL 具有简单性和可扩展性等主要优势。

### 简化的数据库模型
<a name="dsql-simplified-database-model"></a>

**每个集群单个数据库**  
Aurora DSQL 为每个集群提供一个名为 `postgres` 的内置数据库。  
**迁移提示：**如果应用程序使用多个数据库，请创建单独的 Aurora DSQL 集群来进行逻辑分离，或者在单个集群中使用架构。

**无临时表**  
 对于临时数据处理，应使用公用表表达式（CTE）和子查询，它们可为复杂查询提供灵活的替代方案。  
 **替代方案：**将带有 `WITH` 子句的 CTE 用于临时结果集，或者使用带有唯一命名的常规表来存储会话特定的数据。

**自动存储管理**  
Aurora DSQL 消除了表空间和手动存储管理。存储空间会根据数据模式自动扩展和优化。  
**优势：**无需监控磁盘空间、规划存储分配或管理表空间配置。

### 现代应用程序模式
<a name="dsql-modern-application-patterns"></a>

Aurora DSQL 鼓励采用可提高可维护性和性能的现代应用程序开发模式：

**应用程序级逻辑，而不是数据库触发器**  
要获得类似触发器的功能，请在应用程序层中实现事件驱动的逻辑。  
**迁移策略：**将触发逻辑移至应用程序代码，将事件驱动架构与 EventBridge 等 AWS 服务结合使用，或者使用应用程序日志记录来实现审计跟踪记录。

**用于处理数据的 SQL 函数**  
Aurora DSQL 支持基于 SQL 的函数，但不支持像 PL/pgSQL 这样的程序性语言。  
**替代方案：**使用 SQL 函数进行数据转换，或者将复杂逻辑移至应用程序层或 AWS Lambda 函数。

**乐观并发控制，而不是悲观锁定**  
Aurora DSQL 使用乐观并发控制（OCC），这是一种不同于传统数据库锁定机制的无锁方法。Aurora DSQL 不是获取用于阻止其它事务的锁，而是支持事务在不阻止的情况下继续进行，并在提交时检测冲突。这样可以消除死锁，并防止慢速事务阻止其它操作。  
**主要区别：**发生冲突时，Aurora DSQL 返回序列化错误，而不是让事务等待锁定。这要求应用程序实现重试逻辑，类似于处理传统数据库中的锁定超时，但冲突可以立即得到解决，而不是导致阻止等待。  
**设计模式：**使用重试机制实现幂等事务逻辑。设计架构，通过使用随机主键并在键范围内分布更新，最大限度地减少争用。有关更多信息，请参阅 [Aurora DSQL 中的并发控制](working-with-concurrency-control.md)。

**关系和引用完整性**  
 Aurora DSQL 支持表之间的外键关系，包括 ` JOIN ` 操作。为实现引用完整性，请在应用程序层中实现验证。尽管强制执行引用完整性可能很有价值，但级联操作（如级联删除）可能会造成意想不到的性能问题，例如，删除包含 1000 个订单项的订单会变成一个 1001 行的事务。出于这个原因，许多客户避免使用外键限制。  
**设计模式：**在应用程序层中实施引用完整性检查，使用最终一致性模式，或利用 AWS 服务进行数据验证。

### 操作简化
<a name="dsql-operational-simplifications"></a>

Aurora DSQL 消除了许多传统的数据库维护任务，从而减少了操作开销：

**无需手动维护**  
Aurora DSQL 自动管理存储优化、统计数据收集和性能调整。诸如 `VACUUM` 等传统维护命令由系统处理。  
**优点：**不需要数据库维护时段、vacuum 调度和系统参数调整。

**自动分区和扩展**  
Aurora DSQL 会根据访问模式自动对您的数据进行分区和分配。使用 UUID 或应用程序生成的 ID，以实现最佳分配。  
**迁移提示：**移除手动分区逻辑，让 Aurora DSQL 处理数据分配。使用 UUID 或应用程序生成的 ID，以实现最佳分配。如果您的应用程序需要序列标识符，请参阅[序列和标识列](sequences-identity-columns.md)。

# 使用人工智能工具进行代理式迁移
<a name="dsql-agentic-migration"></a>

人工智能编码代理可以通过分析架构、转换代码以及使用内置安全检查执行 DDL 迁移，来加快向 Aurora DSQL 迁移。

## 使用 Kiro 进行迁移
<a name="dsql-kiro-migration"></a>

像 [Kiro](https://kiro.dev/) 这样的编码代理有助于您分析 PostgreSQL 代码并将其迁移到 Aurora DSQL：
+ **架构分析：**上传您现有的架构文件，并要求 Kiro 确定潜在的兼容性问题和提出替代方案
+ **代码转换：**提供您的应用程序代码，并要求 Kiro 协助重构触发逻辑、将序列替换为 UUID 或修改事务模式
+ **迁移规划：**要求 Kiro 根据您的特定应用程序架构制定分步迁移计划
+ **DDL 迁移：**使用带有内置安全检查和用户验证功能的表重新创建模式执行架构修改

**提示示例：**

```
"Analyze this PostgreSQL schema for DSQL compatibility and suggest alternatives for any unsupported features"

"Help me refactor this trigger function into application-level logic for DSQL migration"

"Create a migration checklist for moving my Django application from PostgreSQL to DSQL"

"Drop the legacy_status column from the orders table"

"Change the price column from VARCHAR to DECIMAL in the products table"
```

## 使用表重新创建进行 DDL 迁移
<a name="dsql-ddl-migration-pattern"></a>

将人工智能代理与 Aurora DSQL MCP 服务器结合使用时，某些 ALTER TABLE 操作使用可安全迁移数据的*表重新创建模式*。代理处理复杂性，同时让您随时了解每个步骤的情况。

以下操作使用表重新创建模式：


| 操作 | 方法 | 
| --- | --- | 
| DROP COLUMN | 从新表中排除列 | 
| ALTER COLUMN TYPE | 在迁移期间强制转换数据类型 | 
| ALTER COLUMN SET/DROP NOT NULL | 在新表定义中更改约束 | 
| ALTER COLUMN SET/DROP DEFAULT | 在新表定义中定义默认值 | 
| ADD/DROP CONSTRAINT | 在新表中包含或移除约束 | 
| MODIFY PRIMARY KEY | 使用唯一性验证定义新 PK | 
| 拆分/合并列 | 使用 SPLIT\$1PART、SUBSTRING 或 CONCAT | 

无需重新创建表，即可直接支持以下 ALTER TABLE 操作：
+ `ALTER TABLE ... RENAME COLUMN`：重命名列
+ `ALTER TABLE ... RENAME TO`：重命名表
+ `ALTER TABLE ... ADD COLUMN`：添加新列

**安全功能：**在执行 DDL 迁移时，人工智能代理会在任何破坏性操作（例如 DROP TABLE）之前，提供迁移计划、验证数据兼容性、确认行计数并请求明确批准。

**批量迁移：**对于超过 3000 行的表，代理会自动以 500-1000 行的增量进行批量迁移，以保持在事务限制范围内。

## Aurora DSQL MCP 服务器
<a name="dsql-mcp-tools"></a>

借助 Aurora DSQL 模型上下文协议（MCP）服务器，人工智能助手能够直接连接到 Aurora DSQL 集群并搜索 Aurora DSQL 文档。这样，人工智能就能够：
+ 分析您的现有架构并提出迁移更改建议
+ 使用表重新创建模式执行 DDL 迁移
+ 在迁移期间测试查询并验证兼容性
+ 根据最新的 Aurora DSQL 文档提供准确、最新的指导

 要将 Aurora DSQL MCP 服务器与其它人工智能助手一起使用，请参阅 [Aurora DSQL MCP 服务器](SECTION_aurora-dsql-mcp-server.md)的设置说明。

## Aurora DSQL 有关 PostgreSQL 兼容性的注意事项
<a name="working-with-postgresql-compatibility-unsupported-limitations"></a>

Aurora DSQL 的功能支持与自行管理的 PostgreSQL 有所不同，后者支持其分布式架构、无服务器操作和自动扩展。大多数应用程序无需修改，即可在这些差异范围内运行。

有关一般注意事项，请参阅[使用 Amazon Aurora DSQL 的注意事项](considerations.md)。有关配额和限制，请参阅 [Amazon Aurora DSQL 中的集群配额和数据库限制](CHAP_quotas.md)。
+ Aurora DSQL 对于每个集群使用单个名为 `postgres` 的内置数据库。为了进行逻辑分离，请创建单独的 Aurora DSQL 集群或在单个集群中使用架构。
+ `postgres` 数据库使用 UTF-8 字符编码，该编码提供广泛的国际字符支持。
+ 数据库仅使用 `C` 排序规则。
+ Aurora DSQL 使用 `UTC` 作为系统时区。Postgres 在内部以 UTC 格式存储所有可识别时区的日期和时间。您可以设置 `TimeZone` 配置参数来转换它向客户端显示的方式，并将其作为客户端输入的默认值，服务器将使用该默认值在内部转换为 UTC。
+ PostgreSQL `Repeatable Read` 的事务隔离级别是固定的。
+ 事务具有以下约束：
  + DDL 和 DML 操作需要单独的事务
  + 一个事务只能包含 1 条 DDL 语句
  + 一个事务最多可以修改 3000 行，而无论二级索引的数量如何
  + 3000 行的限制适用于所有 DML 语句（`INSERT`、`UPDATE`、`DELETE`）
+ 数据库连接在 1 小时后超时。
+ Aurora DSQL 通过架构级别的授权来管理权限。管理员用户使用 `CREATE SCHEMA` 创建架构，并使用 `GRANT USAGE ON SCHEMA` 授予访问权限。管理员用户管理公有架构中的对象，而非管理员用户则在用户创建的架构中创建对象以明确所有权边界。有关更多信息，请参阅 [授权数据库角色在数据库中使用 SQL](using-database-and-iam-roles.md#using-database-and-iam-roles-custom-database-roles-sql)。

## 需要迁移方面的帮助吗？
<a name="dsql-migration-feedback-link"></a>

如果您遇到对迁移至关重要但 Aurora DSQL 目前不支持的功能，请参阅[提供有关 Amazon Aurora DSQL 的反馈](providing-feedback.md)，以了解有关如何与 AWS 分享反馈的信息。

# Aurora DSQL 中的并发控制
<a name="working-with-concurrency-control"></a>

并发可让多个会话同时访问和修改数据，而不会损害数据完整性和一致性。Aurora DSQL 在实施现代、无锁并发控制机制的同时提供 [PostgreSQL 兼容性](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/working-with-postgresql-compatibility.html)。它通过快照隔离来保持完全的 ACID 合规性，同时确保数据一致性和可靠性。

Aurora DSQL 的一个关键优势是其无锁架构，这消除了常见的数据库性能瓶颈。Aurora DSQL 可防止慢速事务阻塞其它操作，并消除死锁风险。这种方法使 Aurora DSQL 对于性能和可扩展性至关重要的高吞吐量应用程序特别有价值。

## 事务冲突
<a name="dsql-transaction-conflicts"></a>

Aurora DSQL 使用乐观并发控制（OCC），其工作原理与传统的基于锁的系统不同。OCC 不使用锁，而是在提交时评估冲突。如果多个事务在更新同一行时发生冲突，Aurora DSQL 会按如下方式管理事务：
+ 提交时间最早的事务由 Aurora DSQL 处理。
+ 冲突的事务会收到 PostgreSQL 序列化错误，指示需要重试。

设计应用程序以实施重试逻辑来处理冲突。理想的设计模式是幂等的，尽可能将事务重试作为第一选择。建议采用的逻辑类似于标准 PostgreSQL 锁定超时或死锁情况下的中止和重试逻辑。然而，OCC 要求您的应用程序更频繁地实施此逻辑。

## 优化事务性能的准则
<a name="dsql-perf-guidelines"></a>

要优化性能，请尽量减少对单个键或小键范围的高度争用。要实现此目标，请按照以下准则设计架构，使其在集群键范围内分散更新：
+ 为表选择一个随机主键。
+ 避免使用会增加单个键争用的模式。即使在事务量增长的情况下，这种方法也能确保最佳性能。

# Aurora DSQL 中的 DDL 和分布式事务
<a name="working-with-ddl"></a>

数据定义语言（DDL）在 Aurora DSQL 中的行为与在 PostgreSQL 中不同。Aurora DSQL 具有一个多可用区分布式和无共享数据库层，该数据库层在多租户计算和存储实例集的基础之上构建。由于不存在单个主数据库节点或中心节点，因此数据库目录是分布式的。这样，Aurora DSQL 将 DDL 架构更改作为分布式事务进行管理。

具体而言，DDL 在 Aurora DSQL 中的行为有所不同，如下所示：

**并发控制错误**  
如果您运行一个事务，而另一个事务更新资源，则 Aurora DSQL 会返回并发控制违规错误。例如，请考虑以下操作序列：  

1. 在会话 1 中，用户向表 `mytable` 中添加一列。

1. 在会话 2 中，用户尝试向 `mytable` 中插入一行。

   Aurora DSQL 返回错误 `SQL Error [40001]: ERROR: schema has been updated by another transaction, please retry: (OC001).`

**DDL 和 DML 在同一个事务中**  
Aurora DSQL 中的事务只能包含一个 DDL 语句，而不能同时拥有 DDL 和 DML 语句。此限制意味着您无法在同一个事务中创建表并将数据插入到同一个表中。例如，Aurora DSQL 支持以下顺序事务。  

```
BEGIN;
  CREATE TABLE mytable (ID_col integer);
COMMIT;

BEGIN;
  INSERT into FOO VALUES (1);
COMMIT;
```
Aurora DSQL 不支持以下事务，其中同时包括 `CREATE` 和 `INSERT` 语句。  

```
BEGIN;
  CREATE TABLE FOO (ID_col integer);
  INSERT into FOO VALUES (1);
COMMIT;
```

**异步 DDL**  
在标准 PostgreSQL 中，诸如 `CREATE INDEX` 之类的 DDL 操作会锁定受影响的表，使其不可用于从其它会话中读取和写入。在 Aurora DSQL 中，这些 DDL 语句使用后台管理器异步运行。对受影响表的访问不受阻止。因此，大型表上的 DDL 可以在不停机或不影响性能的情况下运行。有关 Aurora DSQL 中异步作业管理器的更多信息，请参阅 [Aurora DSQL 中的异步索引](working-with-create-index-async.md)。

# Aurora DSQL 中的主键
<a name="working-with-primary-keys"></a>

在 Aurora DSQL 中，主键是一种在物理上组织表数据的功能。它类似于 PostgreSQL 中的 `CLUSTER` 操作或其它数据库中的聚集索引。在定义主键时，Aurora DSQL 会创建一个包含表中所有列的索引。Aurora DSQL 中的主键结构可确保高效的数据访问和管理。

## 数据结构和存储
<a name="dsql-primary-key-storage"></a>

在定义主键时，Aurora DSQL 会按主键顺序存储表数据。这种按索引组织的结构支持主键查找来直接检索所有列值，而不是像传统 B 树索引那样跟随指向数据的指针。与 PostgreSQL 中仅对数据进行一次重组的 `CLUSTER` 操作不同，Aurora DSQL 会自动并持续保持这种顺序。这种方法可提高依赖于主键访问的查询的性能。

Aurora DSQL 还使用主键来为表和索引中的每一行生成集群范围的唯一键。此唯一键也构成了分布式数据管理的基础。它支持跨多个节点对数据进行自动分区，并支持可扩展存储和高并发性。因此，主键结构有助于 Aurora DSQL 自动扩展并高效地管理并发工作负载。

## 选择主键的准则
<a name="dsql-primary-key-guidelines"></a>

在 Aurora DSQL 中选择和使用主键时，请考虑以下准则：
+ 创建表时定义主键。以后您无法更改此键或添加新的主键。主键成为用于数据分区和自动扩展写入吞吐量的集群范围键的一部分。如果未指定主键，Aurora DSQL 将分配一个合成的隐藏 ID。
+ 对于写入量较高的表，请避免使用单调递增的整数作为主键。这可能会由于将所有新的插入内容定向到单个分区而导致性能问题。相反，应将主键与随机分布结合使用，以确保写入操作在各存储分区之间均匀分布。
+ 对于不经常更改或只读的表，可以使用升序键。升序键的示例包括时间戳或序列号。密集键有许多紧密间隔或重复的值。您可以使用升序键，即使它是密集键，因为写入性能并不那么重要。
+ 如果全表扫描不能满足您的性能要求，请选择更高效的访问方法。在大多数情况下，这意味着使用与查询中最常用的联接和查找键相匹配的主键。
+ 主键中各列的最大组合大小为 1 KiB。有关更多信息，请参阅 [Aurora DSQL 中的数据库限制](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/CHAP_quotas.html#SECTION_database-limits)和 [Aurora DSQL 中支持的数据类型](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/working-with-postgresql-compatibility-supported-data-types)。
+ 主键或二级索引中最多可以包含 8 列。有关更多信息，请参阅 [Aurora DSQL 中的数据库限制](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/CHAP_quotas.html#SECTION_database-limits)和 [Aurora DSQL 中支持的数据类型](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/working-with-postgresql-compatibility-supported-data-types)。

# 序列和标识列
<a name="sequences-identity-columns"></a>

序列和标识列生成整数值，在需要紧凑或用户可读的标识符时非常有用。这些值涉及在 [`CREATE SEQUENCE`](create-sequence-syntax-support.md) 文档中描述的分配和缓存行为。

**Topics**
+ [序列操作函数](sequence-functions-syntax-support.md)
+ [标识列](sequences-identity-columns-overview.md)
+ [使用序列和标识列](sequences-identity-columns-working-with.md)

# 序列操作函数
<a name="sequence-functions-syntax-support"></a>

本节介绍用于操作序列对象的函数，也称为序列生成器或就称为序列。序列对象是使用 [`CREATE SEQUENCE`](create-sequence-syntax-support.md) 创建的特殊单行表。序列对象常用于为表的行生成唯一标识符。序列函数提供了简单、多用户安全的方法，用于从序列对象中获取连续的序列值。

**重要**  
使用序列时，应谨慎考虑缓存值。有关更多信息，请参阅 [`CREATE SEQUENCE`](create-sequence-syntax-support.md) 页面上的“重要提示”标注。  
有关如何根据工作负载模式以最佳方式使用序列的指导，请参阅[使用序列和标识列](sequences-identity-columns-working-with.md)。


| 函数 | 说明 | 
| --- | --- | 
| nextval ( regclass ) → bigint | 使序列对象前进到其下一个值并返回该值。这是以原子方式完成的：即使多个会话同时运行 nextval，每个会话也会安全地接收一个不同的序列值。如果序列对象是使用默认参数创建的，则后续的 nextval 调用将返回从 1 开始递增的值。其它行为可以通过在 [`CREATE SEQUENCE`](create-sequence-syntax-support.md) 命令中使用适当的参数来获得。此函数需要针对序列的 USAGE 或 UPDATE 权限。 | 
| setval ( regclass, bigint [, boolean ] ) → bigint | 设置序列对象的当前值，并可选设置其 is\$1called 标志。双参数格式将序列的 last\$1value 字段设置为指定的值，并将其 is\$1called 字段设置为 true，这意味着下一个 nextval 将在返回值之前使序列前进。currval 将报告的值也会设置为指定的值。在三参数格式中，is\$1called 可以设置为 true 或 false。true 与双参数格式效果相同。如果将其设置为 false，则下一个 nextval 将确切返回指定的值，并且序列前进从后一个 nextval 开始。此外，此处并未更改 currval 报告的值。例如：<pre>SELECT setval('myseq', 42);           -- Next nextval will return 43<br />SELECT setval('myseq', 42, true);     -- Same as above<br />SELECT setval('myseq', 42, false);    -- Next nextval will return 42</pre> setval 返回的结果只是其第二个参数的值。此函数需要针对序列的 UPDATE 权限。 | 
| currval ( regclass ) → bigint | 返回当前会话中此序列的 nextval 最近获得的值。（如果在此会话中从未为此序列调用过 nextval，则会报告错误。） 由于这会返回会话本地值，因此，无论其它会话是否因为当前会话运行 nextval 而运行了它，都会给出一个可预测的答案。此函数需要针对序列的 USAGE 或 SELECT 权限。 | 
| lastval () → bigint | 返回 nextval 在当前事务中最近返回的值。此函数与 currval 相同（除了它不是将序列名称作为参数），它引用在当前事务中最近应用了 nextval 的任何序列。如果在当前事务中尚未调用 nextval，则调用 lastval 是错误的。此函数需要针对上次使用的序列的 USAGE 或 SELECT 权限。 | 

**警告**  
如果发出调用的事务稍后中止，则不会回收 `nextval` 获得的值以供重用。这意味着，事务中止或数据库崩溃可能会导致已分配值的序列中出现间隙。在不中止事务的情况下，也可能出现这种情况。例如，带有 `ON CONFLICT` 子句的 `INSERT` 将计算要插入的元组（包括执行任何必需的 `nextval` 调用），然后再检测到任何可能导致其遵循 `ON CONFLICT` 规则的冲突。因此，Aurora DSQL 的序列对象*不能用于获取“无间隙”序列*。  
同样，由 `setval` 所做的序列状态更改会立即对其它事务可见，并且在发出调用的事务回滚时不会撤消。

序列函数要执行操作的序列由 `regclass` 参数指定，该参数只是序列在 `pg_class` 系统目录中的 OID。但是，您不必手动查找 OID，因为 `regclass` 数据类型的输入转换器将为您完成此项工作。有关详细信息，请参阅有关 [Object Identifier Types](https://www.postgresql.org/docs/current/datatype-oid.html) 的 PostgreSQL 文档。

# 标识列
<a name="sequences-identity-columns-overview"></a>

**重要**  
使用标识列时，应谨慎考虑缓存值。有关更多信息，请参阅 [`CREATE SEQUENCE`](create-sequence-syntax-support.md) 页面上的“重要提示”标注。  
有关如何根据工作负载模式以最佳方式使用标识列的指导，请参阅[使用序列和标识列](sequences-identity-columns-working-with.md)。

标识列是根据隐式序列自动生成的特殊列。它可以用来生成键值。要创建标识列，请在 [`CREATE TABLE`](create-table-syntax-support.md) 中使用 `GENERATED ... AS IDENTITY` 子句，例如：

```
CREATE TABLE people (
    id bigint GENERATED ALWAYS AS IDENTITY (CACHE 70000),
    ...
);
```

或者：

```
CREATE TABLE people (
    id bigint GENERATED BY DEFAULT AS IDENTITY (CACHE 70000),
    ...
);
```

有关更多信息，请参阅[`CREATE TABLE`](create-table-syntax-support.md)。

如果对带有标识列的表执行 `INSERT` 命令，但没有为标识列显式指定任何值，则会插入由隐式序列生成的值。例如，使用前面的定义并假设其它适当的列，编写：

```
INSERT INTO people (name, address) VALUES ('A', 'foo');
INSERT INTO people (name, address) VALUES ('B', 'bar');
```

将为从 1 开始的 `id` 列生成值并生成下面的表数据：

```
 id | name | address
----+------+---------
  1 | A    | foo
  2 | B    | bar
```

或者，可以指定关键字 `DEFAULT` 来代替值，以显式请求序列生成的值：

```
INSERT INTO people (id, name, address) VALUES (DEFAULT, 'C', 'baz');
```

同样，可以在 `UPDATE` 命令中使用关键字 `DEFAULT`。

这样，在许多方面，标识列的行为类似于具有默认值的列。

列定义中的子句 `ALWAYS` 和 `BY DEFAULT` 决定了在 `INSERT` 和 `UPDATE` 命令中如何显式处理用户指定的值。在 `INSERT` 命令中，如果选择了 `ALWAYS`，则只有在 `INSERT` 语句指定 `OVERRIDING SYSTEM VALUE` 时才接受用户指定的值。如果选择了 `BY DEFAULT`，则优先使用用户指定的值。因此，使用 `BY DEFAULT` 会产生更类似于使用默认值时的行为，其中，默认值可以由显式值覆盖，而 `ALWAYS` 可提供更多保护，以防止意外插入显式值。

标识列的数据类型必须为序列支持的数据类型之一。（请参见 [`CREATE SEQUENCE`](create-sequence-syntax-support.md)。） 关联序列的属性可以在创建标识列时指定（请参阅 [`CREATE TABLE`](create-table-syntax-support.md)），也可以在之后更改（请参阅 [`ALTER TABLE`](alter-table-syntax-support.md)）。

标识列会自动标记为 `NOT NULL`。但是，身份列并不能保证唯一性。（序列通常返回唯一值，但可以重置序列，也可以手动将值插入标识列中，如前面所述。） 需要使用 `PRIMARY KEY` 或 `UNIQUE` 约束来强制实施唯一性。

# 使用序列和标识列
<a name="sequences-identity-columns-working-with"></a>

本节有助于您了解如何根据工作负载模式以最佳方式使用序列和标识列。

**重要**  
有关分配和缓存行为的更多详细信息，请参阅 [`CREATE SEQUENCE`](create-sequence-syntax-support.md) 页面上的“重要提示”标注。

## 选择标识符类型
<a name="sequences-identity-columns-choosing-identifier-types"></a>

Amazon Aurora DSQL 既支持基于 UUID 的标识符，也支持使用序列或身份列生成的整数值。这些选项的不同之处在于分配值的方式以及值在负载下的扩展方式。

UUID 值无需协调即可生成，非常适合频繁或跨许多会话创建标识符的工作负载。由于 Amazon Aurora DSQL 专为分布式操作而设计，因此避免协调通常是有益的。因此，建议将 UUID 作为默认标识符类型，尤其是对于可扩展性很重要且不需要对标识符进行严格排序的工作负载中的主键。

序列和标识列生成紧凑的整数值，方便用于用户可读的标识符、报告和外部接口。当出于可用性或集成原因而首选数字标识符时，可以考虑将序列或标识列与基于 UUID 的标识符结合使用。当需要整数序列或标识值时，选择合适的缓存大小将成为工作负载设计的重要部分。有关选择缓存大小的指导，请参阅以下章节。

## 选择缓存大小
<a name="sequences-identity-columns-choosing-cache-size"></a>

选择适当的缓存值是有效地使用序列和标识列的重要部分。缓存设置决定了标识符分配在负载下的行为方式，从而影响系统吞吐量以及值反映分配顺序的紧密程度。

**在以下情况下，较大的缓存大小 `CACHE >= 65536` 非常适合：**
+ 标识符以高频率生成
+ 许多会话并发插入
+ 工作负载可以容忍间隙和明显的排序效果

例如，大容量事件摄取工作负载（例如 IoT 或遥测）以及诸如作业运行 ID、支持案例参考或内部订单号等操作标识符通常会受益于较大的缓存大小，其中标识符频繁生成且不要求严格的排序。

**在以下情况下，缓存大小为 1 将更好地保持一致：**
+ 分配率相对较低
+ 随着时间推移，预计标识符将更紧密地遵循分配顺序
+ 使间隙最小化比最大吞吐量更重要

诸如分配账户或参考编号之类的工作负载会与缓存大小为 1 更好地保持一致，在这些工作负载中，标识符生成频率较低，并且需要更紧密的排序。

# Aurora DSQL 中的异步索引
<a name="working-with-create-index-async"></a>

`CREATE INDEX ASYNC` 命令在指定表的一列或多列上创建索引。此命令是一种异步 DDL 操作，不会阻止其它事务。当您运行 `CREATE INDEX ASYNC` 时，Aurora DSQL 立即返回 `job_id`。

您可以使用 `sys.jobs` 系统视图来监控此异步作业的状态。当索引创建作业正在进行时，您可以使用以下过程和命令：

**`sys.wait_for_job(job_id)'your_index_creation_job_id'`**  
阻止当前会话，直到指定的作业完成或失败。返回一个布尔值，指示成功或失败。

**`DROP INDEX`**  
取消正在进行的索引构建作业。  
异步索引创建过程完成后，Aurora DSQL 更新系统目录以将索引标记为活动状态。  
 请注意，在此更新期间访问同一命名空间中的对象的并发事务可能会遇到并发错误。

当 Aurora DSQL 完成异步索引任务时，它会更新系统目录以显示该索引处于活动状态。如果此时其它事务引用同一命名空间中的对象，则您可能会看到并发错误。

## 语法
<a name="working-with-create-index-syntax"></a>

`CREATE INDEX ASYNC` 使用下面的语法。

```
CREATE [ UNIQUE ] INDEX ASYNC [ IF NOT EXISTS ] name ON table_name 
     ( { column_name } [ NULLS { FIRST | LAST } ] ) 
     [ INCLUDE ( column_name [, ...] ) ] 
     [ NULLS [ NOT ] DISTINCT ]
```

## 参数
<a name="working-with-create-index-parameters"></a>

**`UNIQUE`**  
指示 Aurora DSQL 在它创建索引时和您每次添加数据时，检查表中是否存在重复值。如果指定此参数，则会导致重复条目的插入和更新操作会生成错误。

**`IF NOT EXISTS`**  
指示如果已存在同名的索引，则 Aurora DSQL 不应引发异常。在这种情况下，Aurora DSQL 不会创建新索引。请注意，您尝试创建的索引的结构可能与现有的索引截然不同。如果您指定此参数，则需要索引名称。

**`name`**  
索引的名称。您不能在此参数中包含架构的名称。  
Aurora DSQL 在与其父表相同的架构中创建索引。索引的名称必须与架构中任何其它对象（例如表或索引）的名称不同。  
如果您未指定名称，Aurora DSQL 将根据父表和索引列的名称自动生成名称。例如，如果您运行 `CREATE INDEX ASYNC on table1 (col1, col2)`，Aurora DSQL 会自动将索引命名为 `table1_col1_col2_idx`。

**`NULLS FIRST | LAST`**  
空列和非空列的排序顺序。`FIRST` 表示 Aurora DSQL 应先对空列进行排序，然后再对非空列进行排序。`LAST` 表示 Aurora DSQL 应先对非空列进行排序，之后再对空列进行排序。

**`INCLUDE`**  
要作为非键列包含在索引中的列的列表。您不能在索引扫描搜索限定条件中使用非键列。就索引的唯一性而言，Aurora DSQL 会忽略该列。

**`NULLS DISTINCT | NULLS NOT DISTINCT`**  
指定 Aurora DSQL 是否应将空值视为唯一索引中的不同值。默认值为 `DISTINCT`，这意味着唯一索引可以在一列中包含多个空值。`NOT DISTINCT` 表示索引不能在一列中包含多个空值。

## 使用说明
<a name="working-with-create-index-usage-notes"></a>

请考虑以下准则：
+ `CREATE INDEX ASYNC` 命令不引入锁。它也不会影响 Aurora DSQL 用来创建索引的基表。
+ 在架构迁移操作期间，`sys.wait_for_job(job_id)'your_index_creation_job_id'` 过程很有用。它可确保后续的 DDL 和 DML 操作以新创建的索引为目标。
+ 每当 Aurora DSQL 运行新的异步任务时，它都会检查 `sys.jobs` 视图，并删除状态为 `completed` 或 `failed` 超过 30 分钟的任务。这样，`sys.jobs` 主要显示正在进行的任务，而不包含有关旧任务的信息。
+ 如果 Aurora DSQL 无法构建异步索引，则索引将保持 `INVALID`。对于唯一索引，DML 操作受唯一性约束所制约，直至您删除索引。我们建议您删除无效的索引并重新创建它们。

## 创建索引：示例
<a name="working-with-create-index-example"></a>

以下示例演示如何创建架构、表和索引。

1. 创建名为 `test.departments` 的文件。

   ```
   CREATE SCHEMA test;
   
   CREATE TABLE test.departments (name varchar(255) primary key NOT null, 
        manager varchar(255), 
        size varchar(4));
   ```

1. 在表中插入一行。

   ```
   INSERT INTO test.departments VALUES ('Human Resources', 'John Doe', '10')
   ```

1. 创建异步索引。

   ```
   CREATE INDEX ASYNC test_index on test.departments(name, manager, size);
   ```

   `CREATE INDEX` 命令返回作业 ID，如下所示。

   ```
   job_id 
   -------------------------- 
   jh2gbtx4mzhgfkbimtgwn5j45y
   ```

   `job_id` 表示 Aurora DSQL 已经提交了新作业来创建索引。可以使用过程 `sys.wait_for_job(job_id)'your_index_creation_job_id'` 来阻止会话中的其它工作，直到作业完成或超时。

## 查询索引创建的状态：示例
<a name="dsql-index-status-example"></a>

查询 `sys.jobs` 系统视图以查看索引的创建状态，如以下示例所示。

```
SELECT * FROM sys.jobs where job_id = 'wqhu6ewifze5xitg3umt24h5ua';
```

Aurora DSQL 返回与下面类似的响应。

```
           job_id           |  status   | details |  job_type   | class_id | object_id |    object_name    |       start_time       |      update_time
----------------------------+-----------+---------+-------------+----------+-----------+-------------------+------------------------+------------------------
 wqhu6ewifze5xitg3umt24h5ua | completed |         | INDEX_BUILD |     1259 |     26433 | public.nt2_c1_idx | 2025-09-25 22:07:31+00 | 2025-09-25 22:07:46+00
```

状态列可以是以下值之一。


| Status | 说明 | 
| --- | --- | 
| submitted | 任务已提交，但是 Aurora DSQL 尚未开始处理该任务。 | 
| processing | Aurora DSQL 正在处理该任务。 | 
| failed | 任务失败。有关更多信息，请参阅详细信息列。如果 Aurora DSQL 未能构建索引，Aurora DSQL 不会自动移除索引定义。您必须使用 DROP INDEX 命令手动移除索引。 | 
| completed | Aurora DSQL 已成功完成任务。 | 

也可以通过目录表 `pg_index` 和 `pg_class` 查询索引的状态。具体而言，属性 `indisvalid` 和 `indisimmediate` 可以告诉您索引处于什么状态。当 Aurora DSQL 创建索引时，索引的初始状态为 `INVALID`。索引的 `indisvalid` 标志返回 `FALSE` 或 `f`，表示该索引无效。如果标志返回 `TRUE` 或 `t`，则索引已就绪。

```
SELECT relname AS index_name, indisvalid as is_valid, pg_get_indexdef(indexrelid) AS index_definition
from pg_index, pg_class
WHERE pg_class.oid = indexrelid AND indrelid = 'test.departments'::regclass;
```

```
    index_name    | is_valid |                                                 index_definition                                                  
------------------+----------+-------------------------------------------------------------------------------------------------------------------
 department_pkey  |     t    | CREATE UNIQUE INDEX department_pkey ON test.departments USING btree_index (title) INCLUDE (name, manager, size)
 test_index1      |     t    | CREATE INDEX test_index1 ON test.departments USING btree_index (name, manager, size)
```

## 唯一索引构建失败
<a name="unique-index-failures"></a>

如果异步唯一索引构建作业显示失败状态以及详细信息 `Found duplicate key while validating index for UCVs`，这表示由于违反唯一性约束而无法构建唯一索引。

**解决唯一索引构建失败**

1. 移除主表中与在唯一二级索引中指定的键有重复条目的所有行。

1. 删除失败的索引。

1. 发出新的创建索引命令。

## 检测主表中的唯一性违规
<a name="detect-uniqueness-violation"></a>

以下 SQL 查询有助于您识别表的指定列中的重复值。当您需要对当前未设置为主键或没有唯一约束的列（例如用户表中的电子邮件地址）强制实施唯一性时，这特别有用。

 以下示例演示如何创建示例用户表，在其中填充包含已知重复项的测试数据，然后运行检测查询。

**定义表架构**

```
-- Drop the table if it exists
DROP TABLE IF EXISTS users;

-- Create the users table with a simple integer primary key
CREATE TABLE users (
    user_id INTEGER PRIMARY KEY,
    email VARCHAR(255),
    first_name VARCHAR(100),
    last_name VARCHAR(100),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```

**插入包含一组重复电子邮件地址的示例数据**

```
-- Insert sample data with explicit IDs
INSERT INTO users (user_id, email, first_name, last_name) VALUES
    (1, 'john.doe@example.com', 'John', 'Doe'),
    (2, 'jane.smith@example.com', 'Jane', 'Smith'),
    (3, 'john.doe@example.com', 'Johnny', 'Doe'),
    (4, 'alice.wong@example.com', 'Alice', 'Wong'),
    (5, 'bob.jones@example.com', 'Bob', 'Jones'),
    (6, 'alice.wong@example.com', 'Alicia', 'Wong'),
    (7, 'bob.jones@example.com', 'Robert', 'Jones');
```

**运行重复项检测查询**

```
-- Query to find duplicates
WITH duplicates AS (
    SELECT email, COUNT(*) as duplicate_count
    FROM users
    GROUP BY email
    HAVING COUNT(*) > 1
)
SELECT u.*, d.duplicate_count
FROM users u
INNER JOIN duplicates d ON u.email = d.email
ORDER BY u.email, u.user_id;
```

**查看所有包含重复电子邮件地址的记录**

```
 user_id |         email          | first_name | last_name |         created_at         | duplicate_count 
---------+------------------------+------------+-----------+----------------------------+-----------------
       4 | akua.mansa@example.com | Akua       | Mansa     | 2025-05-21 20:55:53.714432 |               2
       6 | akua.mansa@example.com | Akua       | Mansa     | 2025-05-21 20:55:53.714432 |               2
       1 | john.doe@example.com   | John       | Doe       | 2025-05-21 20:55:53.714432 |               2
       3 | john.doe@example.com   | Johnny     | Doe       | 2025-05-21 20:55:53.714432 |               2
(4 rows)
```

**如果我们现在尝试使用索引创建语句，它就会失败：**

```
postgres=> CREATE UNIQUE INDEX ASYNC idx_users_email ON users(email);
      job_id      
----------------------------
 ve32upmjz5dgdknpbleeca5tri
(1 row)

postgres=> select * from sys.jobs;
           job_id           |  status   |                       details                       |  job_type   | class_id | object_id |      object_name       |       start_time       |      update_time       
----------------------------+-----------+-----------------------------------------------------+-------------+----------+-----------+------------------------+------------------------+------------------------
 qpn6aqlkijgmzilyidcpwrpova | completed |                                                     | DROP        |     1259 |     26384 |                        | 2025-05-20 00:47:10+00 | 2025-05-20 00:47:32+00
 ve32upmjz5dgdknpbleeca5tri | failed    | Found duplicate key while validating index for UCVs | INDEX_BUILD |     1259 |     26396 | public.idx_users_email | 2025-05-20 00:49:49+00 | 2025-05-20 00:49:56+00
(2 rows)
```

# Aurora DSQL 中的系统表和命令
<a name="working-with-systems-tables"></a>

请参阅以下各节来了解 Aurora DSQL 中支持的系统表和目录，以及用于获取有关系统的信息（如版本）的有用查询。

## 系统表
<a name="working-with-system-tables-queries"></a>

Aurora DSQL 与 PostgreSQL 兼容，因此 Aurora DSQL 中还存在许多来自 PostgreSQL 的 [system catalog tables](https://www.PostgreSQL.org/docs/current/catalogs-overview.html) 和 [views](https://www.PostgreSQL.org/docs/current/views.html)。

### 重要的 PostgreSQL 目录表和视图
<a name="dsql-catalog-tables"></a>

下表介绍了您可能在 Aurora DSQL 中使用的最常见的表和视图。


| 名称 | 描述 | 
| --- | --- | 
|  `pg_namespace`  |  有关所有架构的信息  | 
|  `pg_tables`  |  有关所有表的信息  | 
|  `pg_attribute`  |  有关所有属性的信息  | 
|  `pg_views`  |  有关（预）定义视图的信息  | 
|  `pg_class`  |  描述所有表、列、索引和类似对象  | 
|  `pg_stats`  |  有关计划程序统计数据的视图  | 
|  `pg_user`  |  有关用户的信息  | 
|  `pg_roles`  |  有关用户和组的信息  | 
|  `pg_indexes`  |  列出所有索引  | 
|  `pg_constraint`  |  列出对表的约束  | 

### 支持和不支持的目录表
<a name="dsql-catalog-tables-supported"></a>

下表指示在 Aurora DSQL 中支持哪些表和不支持哪些表。


| 名称 | 适用于 Aurora DSQL | 
| --- | --- | 
|  `pg_aggregate`  |  否  | 
|  `pg_am`  |  是  | 
|  `pg_amop`  |  否  | 
|  `pg_amproc`  |  否  | 
|  `pg_attrdef`  |  是  | 
|  `pg_attribute`  |  是  | 
|  `pg_authid`  |  否（使用 `pg_roles`）  | 
|  `pg_auth_members`  |  支持  | 
|  `pg_cast`  |  是  | 
|  `pg_class`  |  是  | 
|  `pg_collation`  |  是  | 
|  `pg_constraint`  |  是  | 
|  `pg_conversion`  |  否  | 
|  `pg_database`  |  否  | 
|  `pg_db_role_setting`  |  是  | 
|  `pg_default_acl`  |  是  | 
|  `pg_depend`  |  是  | 
|  `pg_description`  |  是  | 
|  `pg_enum`  |  否  | 
|  `pg_event_trigger`  |  否  | 
|  `pg_extension`  |  否  | 
|  `pg_foreign_data_wrapper`  |  否  | 
|  `pg_foreign_server`  |  否  | 
|  `pg_foreign_table`  |  否  | 
|  `pg_index`  |  是  | 
|  `pg_inherits`  |  是  | 
|  `pg_init_privs`  |  否  | 
|  `pg_language`  |  否  | 
|  `pg_largeobject`  |  否  | 
|  `pg_largeobject_metadata`  |  是  | 
|  `pg_namespace`  |  是  | 
|  `pg_opclass`  |  否  | 
|  `pg_operator`  |  是  | 
|  `pg_opfamily`  |  否  | 
|  `pg_parameter_acl`  |  是  | 
|  `pg_partitioned_table`  |  否  | 
|  `pg_policy`  |  否  | 
|  `pg_proc`  |  否  | 
|  `pg_publication`  |  否  | 
|  `pg_publication_namespace`  |  否  | 
|  `pg_publication_rel`  |  否  | 
|  `pg_range`  |  是  | 
|  `pg_replication_origin`  |  否  | 
|  `pg_rewrite`  |  否  | 
|  `pg_seclabel`  |  否  | 
|  `pg_sequence`  |  否  | 
|  `pg_shdepend`  |  是  | 
|  `pg_shdescription`  |  是  | 
|  `pg_shseclabel`  |  否  | 
|  `pg_statistic`  |  是  | 
|  `pg_statistic_ext`  |  否  | 
|  `pg_statistic_ext_data`  |  否  | 
|  `pg_subscription`  |  否  | 
|  `pg_subscription_rel`  |  否  | 
|  `pg_tablespace`  |  否  | 
|  `pg_transform`  |  否  | 
|  `pg_trigger`  |  否  | 
|  `pg_ts_config`  |  是  | 
|  `pg_ts_config_map`  |  是  | 
|  `pg_ts_dict`  |  是  | 
|  `pg_ts_parser`  |  是  | 
|  `pg_ts_template`  |  是  | 
|  `pg_type`  |  是  | 
|  `pg_user_mapping`  |  否  | 

### 支持和不支持的系统视图
<a name="dsql-system-tables-supported"></a>

下表指示在 Aurora DSQL 中支持哪些视图和不支持哪些视图。


| 名称 | 适用于 Aurora DSQL | 
| --- | --- | 
|  `pg_available_extensions`  |  否  | 
|  `pg_available_extension_versions`  |  否  | 
|  `pg_backend_memory_contexts`  |  是  | 
|  `pg_config`  |  否  | 
|  `pg_cursors`  |  否  | 
|  `pg_file_settings`  |  否  | 
|  `pg_group`  |  是  | 
|  `pg_hba_file_rules`  |  否  | 
|  `pg_ident_file_mappings`  |  否  | 
|  `pg_indexes`  |  是  | 
|  `pg_locks`  |  否  | 
|  `pg_matviews`  |  否  | 
|  `pg_policies`  |  否  | 
|  `pg_prepared_statements`  |  否  | 
|  `pg_prepared_xacts`  |  否  | 
|  `pg_publication_tables`  |  否  | 
|  `pg_replication_origin_status`  |  否  | 
|  `pg_replication_slots`  |  否  | 
|  `pg_roles`  |  是  | 
|  `pg_rules`  |  否  | 
|  `pg_seclabels`  |  否  | 
|  `pg_sequences`  |  否  | 
|  `pg_settings`  |  是  | 
|  `pg_shadow`  |  是  | 
|  `pg_shmem_allocations`  |  是  | 
|  `pg_stats`  |  是  | 
|  `pg_stats_ext`  |  否  | 
|  `pg_stats_ext_exprs`  |  否  | 
|  `pg_tables`  |  是  | 
|  `pg_timezone_abbrevs`  |  是  | 
|  `pg_timezone_names`  |  是  | 
|  `pg_user`  |  是  | 
|  `pg_user_mappings`  |  否  | 
|  `pg_views`  |  是  | 
|  `pg_stat_activity`  |  否  | 
|  `pg_stat_replication`  |  否  | 
|  `pg_stat_replication_slots`  |  否  | 
|  `pg_stat_wal_receiver`  |  否  | 
|  `pg_stat_recovery_prefetch`  |  否  | 
|  `pg_stat_subscription`  |  否  | 
|  `pg_stat_subscription_stats`  |  否  | 
|  `pg_stat_ssl`  |  是  | 
|  `pg_stat_gssapi`  |  否  | 
|  `pg_stat_archiver`  |  否  | 
|  `pg_stat_io`  |  否  | 
|  `pg_stat_bgwriter`  |  否  | 
|  `pg_stat_wal`  |  否  | 
|  `pg_stat_database`  |  否  | 
|  `pg_stat_database_conflicts`  |  否  | 
|  `pg_stat_all_tables`  |  否  | 
|  `pg_stat_all_indexes`  |  否  | 
|  `pg_statio_all_tables`  |  否  | 
|  `pg_statio_all_indexes`  |  否  | 
|  `pg_statio_all_sequences`  |  否  | 
|  `pg_stat_slru`  |  否  | 
|  `pg_statio_user_tables`  |  否  | 
|  `pg_statio_user_sequences`  |  否  | 
|  `pg_stat_user_functions`  |  否  | 
|  `pg_stat_user_indexes`  |  否  | 
|  `pg_stat_progress_analyze`  |  否  | 
|  `pg_stat_progress_basebackup`  |  否  | 
|  `pg_stat_progress_cluster`  |  否  | 
|  `pg_stat_progress_create_index`  |  否  | 
|  `pg_stat_progress_vacuum`  |  否  | 
|  `pg_stat_sys_indexes`  |  否  | 
|  `pg_stat_sys_tables`  |  否  | 
|  `pg_stat_xact_all_tables`  |  否  | 
|  `pg_stat_xact_sys_tables`  |  否  | 
|  `pg_stat_xact_user_functions`  |  否  | 
|  `pg_stat_xact_user_tables`  |  否  | 
|  `pg_statio_sys_indexes`  |  否  | 
|  `pg_statio_sys_sequences`  |  否  | 
|  `pg_statio_sys_tables`  |  否  | 
|  `pg_statio_user_indexes`  |  否  | 

### sys.jobs 视图
<a name="dsql-sys-jobs"></a>

`sys.jobs` 提供有关异步作业的状态信息。例如，在您[创建异步索引](working-with-create-index-async.md)后，Aurora DSQL 将返回 `job_uuid`。您可以将此 `job_uuid` 与 `sys.jobs` 结合使用来查找作业的状态。

```
SELECT * FROM sys.jobs;
```

Aurora DSQL 返回与下面类似的响应。

```
           job_id           |  status   | details |  job_type   | class_id | object_id |    object_name    |       start_time       |      update_time
----------------------------+-----------+---------+-------------+----------+-----------+-------------------+------------------------+------------------------
 wqhu6ewifze5xitg3umt24h5ua | completed |         | INDEX_BUILD |     1259 |     26433 | public.nt2_c1_idx | 2025-09-25 22:07:31+00 | 2025-09-25 22:07:46+00
 kkngzf33dndl3daacxehpx5eba | completed |         | ANALYZE     |     1259 |     26419 | public.nt         | 2025-09-25 21:57:05+00 | 2025-09-25 21:57:27+00
 fyopxjb6ovdn7po6lrkj63cyea | completed |         | DROP        |     1259 |     26422 |                   | 2025-09-25 22:05:57+00 | 2025-09-25 22:06:03+00
```

下表介绍 `sys.jobs` 视图中的各列。


**sys.jobs 视图列**  

| 列 | 类型 | 说明 | 
| --- | --- | --- | 
| job\$1id | text | 一个 32 位的 UUID，表示作业。 | 
| status | text | 作业的当前状态。可能的值为 submitted、processing、completed 和 failed。有关更多信息，请参阅 [sys.jobs 状态值](#dsql-sys-jobs-status-values)。 | 
| details | text | 有关作业的任何相关详细信息。如果任务失败，则会提供详细原因。 | 
| job\$1type | text | 异步作业的类型。可能的值为：INDEX\$1BUILD – 异步索引构建。ANALYZE – 系统提交的自动分析作业。DROP – 在 DROP TABLE 或 DROP INDEX 操作后移除物理数据。 | 
| class\$1id | oid | 包含该对象的目录表的 OID。 | 
| object\$1id | oid | 对象的 OID。 | 
| object\$1name | text | 对象的完全限定名称。DROP 作业无法引用已经删除的对象。如果已经删除引用的对象，则 object\$1name 可能为 NULL。 | 
| start\$1time | timestamp with time zone | 提交作业的时间戳。 | 
| update\$1time | timestamp with time zone | 上次更新作业行的时间戳。 | 


**sys.jobs 状态值**  

| Status | 说明 | 
| --- | --- | 
| submitted | 任务已提交，但是 Aurora DSQL 尚未开始处理该任务。 | 
| processing | Aurora DSQL 正在处理该任务。 | 
| failed | 任务失败。有关更多信息，请参阅 details 列。 | 
| completed | Aurora DSQL 已成功完成任务。 | 

### sys.iam\$1pg\$1role\$1mappings 视图
<a name="dsql-sys-iam-pg-role-mappings"></a>

视图 `sys.iam_pg_role_mappings` 提供有关授予 IAM 用户的权限的信息。例如，如果 `DQSLDBConnect` 是一个 IAM 角色，该角色为非管理员提供 Aurora DSQL 访问权限，并且向名为 `testuser` 的用户授予了 `DQSLDBConnect` 角色和相应的权限，则您可以查询 `sys.iam_pg_role_mappings` 视图来查看向哪些用户授予了哪些权限。

```
SELECT * FROM sys.iam_pg_role_mappings;
```

## 有用的系统元数据查询
<a name="dsql-useful-system-queries"></a>

使用这些查询可以获取表统计数据和系统元数据，而无需执行诸如全表扫描之类的高代价操作。

### 获取表的估计行计数
<a name="dsql-get-row-count"></a>

要在不执行全表扫描的情况下获取表中的大致行计数，请使用以下查询：

```
SELECT reltuples FROM pg_class WHERE relname = 'table_name';
```

该命令返回的输出类似于下方内容：

```
  reltuples
--------------
 9.993836e+08
```

对于 Aurora DSQL 中的大型表，这种方法比 `SELECT COUNT(*)` 更高效。

### 获取当前 Aurora DSQL 主要版本
<a name="dsql-get-major-version"></a>

要获取 Aurora DSQL 集群的当前主要版本，请使用以下查询：

```
SELECT * FROM sys.dsql_major_version();
```

该命令返回的输出类似于下方内容：

```
 dsql_major_version
--------------------
                  1
```

这将返回 Aurora DSQL 中 SQL 连接处于开启状态的主要版本。

### 获取当前 PostgreSQL 版本
<a name="dsql-get-pg-version"></a>

要获取 Aurora DSQL 集群的当前 PostgreSQL 版本，请使用以下查询：

```
SHOW server_version;
```

该命令返回的输出类似于下方内容：

```
 server_version
----------------
 16.13
```

这将返回 Aurora DSQL 中 SQL 连接处于开启状态的 PostgreSQL 版本。

## `ANALYZE` 命令
<a name="working-with-system-tables-analyze"></a>

 `ANALYZE ` 命令收集有关数据库中表内容的统计数据，并将结果存储在 `pg_stats` 系统视图中。随后，查询计划程序使用这些统计数据来帮助确定最有效的查询执行计划。

 在 Aurora DSQL 中，您无法在显式事务中运行 `ANALYZE` 命令。`ANALYZE` 不受数据库事务超时限制的约束。

 为了减少手动干预的需要并将统计数据始终保持为最新，Aurora DSQL 会自动将 `ANALYZE` 作为后台进程运行。此后台作业会根据在表中观察到的变化率自动触发。它与自上次分析以来已插入、更新或删除的行（元组）数相关联。

 `ANALYZE` 在后台异步运行，可以通过以下查询在系统视图 sys.jobs 中监控其活动：

```
SELECT * FROM sys.jobs WHERE job_type = 'ANALYZE';
```

**重要注意事项**

**注意**  
 `ANALYZE` 作业的计费方式与 Aurora DSQL 中的其它异步作业相同。修改表时，这可能会间接触发自动后台统计数据收集作业，这可能会因关联的系统级活动而产生计量费用。

 自动触发的后台 `ANALYZE` 作业收集的统计数据类型与手动 `ANALYZE` 相同，默认情况下会将其应用于用户表。系统表和目录表不包括在此自动化流程中。

# 使用 Aurora DSQL EXPLAIN 解释计划
<a name="working-with-explain-plans"></a>

Aurora DSQL 使用与 PostgreSQL 类似的 EXPLAIN 计划结构，但增加了一些反映其分布式架构和执行模型的关键内容。

在本文档中，我们将概述 Aurora DSQL EXPLAIN 计划，重点介绍与 PostgreSQL 相比的相似之处和不同之处。我们将介绍 Aurora DSQL 中可用的各种类型的扫描操作，并协助您了解运行查询的成本。

## PostgreSQL 与 Aurora DSQL EXPLAIN 计划
<a name="postgresql-explain-plans"></a>

 Aurora DSQL 建立在 PostgreSQL 数据库基础之上，与 PostgreSQL 共享大多数计划结构，但存在影响查询执行和优化的关键架构差异：


| 功能 | PostgreSQL | Aurora DSQL | 
| --- | --- | --- | 
|  数据存储  |  堆存储  |  没有堆，所有行都通过唯一标识符编制索引  | 
|  主键  |  主键索引与表数据是分开的  |  主键索引是所有额外列均为 INCLUDE 列的表  | 
|  二级索引  |  标准二级索引  |  工作原理与 PostgreSQL 相同，能够包含非键列  | 
|  筛选功能  |  索引条件、堆筛选条件  |  索引条件、存储筛选条件、查询处理器筛选条件   | 
|  扫描类型  |  顺序扫描、索引扫描、仅限索引扫描  |  全面扫描、仅限索引扫描、索引扫描  | 
|  查询执行  |  对数据库为本地的  |  分布式（计算和存储是分开的）  | 

Aurora DSQL 直接按主键顺序存储表数据，而不是存储在单独的堆中。每行都由一个唯一键（通常是主键）标识，这使数据库能够更高效地优化查找。架构差异解释了为什么 Aurora DSQL 经常在 PostgreSQL 可能选择顺序扫描的情况下使用仅限索引扫描。

另一个关键区别是，Aurora DSQL 将计算与存储分开，从而可以在执行路径中更早地应用筛选条件，以减少数据移动并提高性能。

有关在 PostgreSQL 中使用 EXPLAIN 计划的更多信息，请参阅 [PostgreSQL EXPLAIN 文档](https://www.postgresql.org/docs/current/using-explain.html)。

## Aurora DSQL EXPLAIN 中的关键元素
<a name="explain-plan-elements"></a>

Aurora DSQL EXPLAIN 计划提供有关如何执行查询的详细信息，包括筛选发生的位置以及从存储中检索哪些列。了解此输出有助于优化查询性能。

索引条件  
用于导航索引的条件。效率最高的筛选，可减少扫描的数据。在 Aurora DSQL 中，可以在执行计划的多个层面上应用索引条件。

投影  
从存储中检索的列。预测越少意味着性能越好。

存储筛选条件  
在存储级别上应用的条件。比查询处理器筛选条件更高效。

查询处理器筛选条件  
在查询处理器级别应用的条件。需要在筛选之前传输所有数据，这会导致更高的数据移动和处理开销。

## Aurora DSQL 中的筛选条件
<a name="filtering-and-projection"></a>

Aurora DSQL 将计算与存储分开，这意味着在查询执行期间应用筛选条件的位置会对性能产生重大影响。在传输大量数据之前应用筛选的条件可减少延迟并提高效率。越早应用筛选条件，需要处理、移动和扫描的数据就越少，从而加快查询速度。

Aurora DSQL 可以在查询路径的多个阶段应用筛选条件。了解这些阶段是解释查询计划和优化性能的关键。


| 级别 | 筛选条件类型 | 描述 | 
| --- | --- | --- | 
| 1 | 索引条件 |  在扫描索引时应用。限制从存储中读取的数据量，并减少发送到计算层的数据。  | 
| 2 | 存储筛选条件 | 在从存储中读取数据之后但在将其发送到计算之前应用。这里的一个例子是针对索引的包含列的筛选条件。减少数据传输，但不会减少读取量。 | 
| 3 | 查询处理器筛选条件 | 在数据到达计算层后应用。必须先传输所有数据，这会增加延迟和成本。目前，Aurora DSQL 无法对存储执行所有筛选和投影操作，因此某些查询可能会被迫回退到这种类型的筛选。 | 

# 阅读 Aurora DSQL EXPLAIN 计划
<a name="reading-dsql-explain-plans"></a>

了解如何阅读 EXPLAIN 计划是优化查询性能的关键。在本节中，我们将介绍 Aurora DSQL 查询计划的真实示例，展示不同扫描类型的行为，解释应用筛选条件的位置，并重点介绍优化的机会。

## 这些示例中使用的示例表
<a name="explain-plan-sample-tables"></a>

下面的示例引用两个表：`transaction` 和 `account`。

`transaction` 表没有主键，这将导致 Aurora DSQL 在查询表时执行全表扫描。

`account` 表对 `customer_id` 具有索引。该索引包括 `balance` 和 `status` 作为覆盖列，支持直接从索引中满足某些查询，而无需从基表中读取。但是，索引不包括 `created_at`，因此，引用该列的查询需要额外的表访问权限。

```
CREATE TABLE transaction (
    account_id uuid,
    transaction_date timestamp,
    description text
);

CREATE TABLE account (
    customer_id uuid,
    balance numeric,
    status varchar,
    created_at timestamp
);

CREATE INDEX ASYNC idx1 ON account (customer_id) INCLUDE (balance, status);
```

## 全面扫描示例
<a name="full-scan-example"></a>

Aurora DSQL 既有顺序扫描（功能上与 PostgreSQL 相同），也有全面扫描。这两者之间的唯一区别是，全面扫描可以对存储进行额外的筛选。因此，与顺序扫描相比，几乎始终优先选择全面扫描。由于相似性，我们将只介绍更有趣的全面扫描的示例。

全面扫描将主要用于没有主键的表。由于 Aurora DSQL 主键默认情况下为完全覆盖索引，因此在 PostgreSQL 使用顺序扫描的许多情况下，Aurora DSQL 很可能会对主键使用仅限索引扫描。与大多数其它数据库一样，没有索引的表的扩展性会很差。

```
EXPLAIN SELECT account_id FROM transaction WHERE transaction_date > '2025-01-01' AND description LIKE '%external%';
```

```
                                                   QUERY PLAN
----------------------------------------------------------------------------------------------------------------
 Full Scan (btree-table) on transaction  (cost=125100.05..177933.38 rows=33333 width=16)
   Filter: (description ~~ '%external%'::text)
   -> Storage Scan on transaction (cost=12510.05..17793.38 rows=66666 width=16)
        Projections: account_id, description
        Filters: (transaction_date > '2025-01-01 00:00:00'::timestamp without time zone)
        -> B-Tree Scan on transaction (cost=12510.05..17793.38 rows=100000 width=30)
```

此计划显示了在不同阶段应用的两个筛选条件。`transaction_date > '2025-01-01'` 条件应用于存储层，从而减少返回的数据量。稍后，在数据传输之后，在查询处理器中应用 `description LIKE '%external%'` 条件，这会降低效率。将更具选择性的筛选条件推送到存储层或索引层通常可以提高性能。

## 仅限索引扫描示例
<a name="index-only-scan-example"></a>

仅限索引扫描是 Aurora DSQL 中最优的扫描类型，因为它们可以最大限度地减少到存储层的往返次数，并且可以进行最多的筛选。但仅因为您看到了仅限索引扫描，并不意味着您拥有最好的计划。由于可能发生的筛选级别各不相同，因此仍要注意可能发生筛选的不同位置，这一点至关重要。

```
EXPLAIN SELECT balance FROM account 
WHERE customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb' 
AND balance > 100 
AND status = 'pending';
```

```
                                  QUERY PLAN
-------------------------------------------------------------------------------
 Index Only Scan using idx1 on account  (cost=725.05..1025.08 rows=8 width=18)
   Index Cond: (customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'::uuid)
   Filter: (balance > '100'::numeric)
   -> Storage Scan on idx1 (cost=12510.05..17793.38 rows=9 width=16)
        Projections: balance
        Filters: ((status)::text = 'pending'::text)
        -> B-Tree Scan on idx1 (cost=12510.05..17793.38 rows=10 width=30)
            Index Cond: (customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'::uuid)
```

在此计划中，首先在索引扫描期间评估索引条件 (`customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'`)，这是效率最高的阶段，因为它会限制从存储中读取的数据量。存储筛选条件 `status = 'pending'` 是在读取数据之后但在将数据发送到计算层之前应用的，从而减少了传输的数据量。最后，查询处理器筛选条件 `balance > 100` 在数据移动后最后运行，因此效率最低。其中，索引条件的性能最佳，因为它直接控制扫描的数据量。

## 索引扫描示例
<a name="index-scan-example"></a>

索引扫描与仅限索引扫描类似，不同之处在于前者需要另一个步骤，即调用基表。由于 Aurora DSQL 可以指定存储筛选条件，因此它能够对索引调用和查找调用指定存储筛选条件。

为了明确这一点，Aurora DSQL 将计划呈现为两个节点。这样，您可以清楚地看到添加包含列对从存储返回的行有多大帮助。

```
EXPLAIN SELECT balance FROM account 
WHERE customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'
AND balance > 100 
AND status = 'pending' 
AND created_at > '2025-01-01';
```

```
                                                QUERY PLAN
----------------------------------------------------------------------------------------------------------
 Index Scan using idx1 on account  (cost=728.18..1132.20 rows=3 width=18)
   Filter: (balance > '100'::numeric)
   Index Cond: (customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'::uuid)
   -> Storage Scan on idx1 (cost=12510.05..17793.38 rows=8 width=16)
        Projections: balance
        Filters: ((status)::text = 'pending'::text)
        -> B-Tree Scan on account (cost=12510.05..17793.38 rows=10 width=30)
            Index Cond: (customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'::uuid)
   -> Storage Lookup on account (cost=12510.05..17793.38 rows=4 width=16)
        Filters: (created_at > '2025-01-01 00:00:00'::timestamp without time zone)
        -> B-Tree Lookup on transaction (cost=12510.05..17793.38 rows=8 width=30)
```

 此计划显示了筛选是如何跨多个阶段发生的：
+  有关 `customer_id ` 的索引条件会尽早筛选数据。
+ 有关 `status` 的存储筛选条件会进一步缩小结果范围，然后再将结果发送到计算中。
+ 有关 `balance` 的查询处理器筛选条件将在稍后传输后应用。
+ 从基表中提取其它列时，会评估有关 `created_at` 的查找筛选条件。

将常用列添加为 `INCLUDE` 字段通常可以消除这种查找并提高性能。

## 最佳实践
<a name="best-practices"></a>
+ **将筛选条件与索引列对齐**，以便更早地推送筛选。
+ **使用 INCLUDE 列**以支持仅限索引扫描并避免查找。
+ 在调查性能问题时**验证行估计值**。Aurora DSQL 根据数据更改率在后台运行 `ANALYZE`，从而自动管理统计数据。如果估计值看起来不准确，则可以手动运行 `ANALYZE` 以立即刷新统计数据。
+ **避免对大型表进行未编入索引的查询**，以防止代价高昂的全面扫描。

# 了解 EXPLAIN ANALYZE 中的 DPU
<a name="understanding-dpus-explain-analyze"></a>

Aurora DSQL 在 `EXPLAIN ANALYZE VERBOSE` 计划输出中提供**语句级**分布式处理单元（DPU）信息，以便您能够更深入地了解开发过程中的查询成本。此部分将阐释 DPU 的定义以及如何在 `EXPLAIN ANALYZE VERBOSE` 输出中解读它们。

## 什么是 DPU？
<a name="what-is-dpu"></a>

分布式处理单元（DPU）是 Aurora DSQL 中用于量化工作完成量的标准化度量单位，由以下部分组成：
+ **ComputeDPU** – 执行 SQL 查询所花费的时间
+ **ReadDPU** – 从存储中读取数据所使用的资源
+ **WriteDPU** – 向存储中写入数据所使用的资源
+ **MultiRegionWriteDPU** – 用于在多区域配置中将写入内容复制到对等集群的资源。

## EXPLAIN ANALYZE VERBOSE 中的 DPU 使用量
<a name="dpu-usage-explain-analyze"></a>

Aurora DSQL 对 `EXPLAIN ANALYZE VERBOSE` 进行了扩展，以便在输出末尾包含语句级 DPU 使用量估算值。这可让您即时了解查询成本，并帮助您识别工作负载成本驱动因素、优化查询性能，并更准确地预测资源使用量。

以下示例展示如何解释 EXPLAIN ANALYZE VERBOSE 输出中包含的语句级 DPU 估算值。

### 示例 1：SELECT 查询
<a name="select-query-example"></a>

```
EXPLAIN ANALYZE VERBOSE SELECT * FROM test_table;
```

```
QUERY PLAN
----------------------------------------------------
Index Only Scan using test_table_pkey on public.test_table  (cost=125100.05..171100.05 rows=1000000 width=36) (actual time=2.973..4.482 rows=120 loops=1)
  Output: id, context
  -> Storage Scan on test_table_pkey (cost=125100.05..171100.05 rows=1000000 width=36) (actual rows=120 loops=1)
      Projections: id, context
      -> B-Tree Scan on test_table_pkey (cost=125100.05..171100.05 rows=1000000 width=36) (actual rows=120 loops=1)
Query Identifier: qymgw1m77maoe
Planning Time: 11.415 ms
Execution Time: 4.528 ms
Statement DPU Estimate:
  Compute: 0.01607 DPU
  Read: 0.04312 DPU
  Write: 0.00000 DPU
  Total: 0.05919 DPU
```

在此示例中，SELECT 语句执行了一次仅索引扫描，因此大部分成本来自读取 DPU（0.04312）和计算 DPU（0.01607），前者表示从存储中检索数据所使用的资源，后者反映处理并返回结果所使用的计算资源。由于该查询未修改数据，因此不存在写入 DPU。总 DPU（0.05919）为计算 DPU、读取 DPU 与写入 DPU 的总和。

### 示例 2：INSERT 查询
<a name="insert-query-example"></a>

```
EXPLAIN ANALYZE VERBOSE INSERT INTO test_table VALUES (1, 'name1'), (2, 'name2'), (3, 'name3');
```

```
QUERY PLAN
----------------------------------------------------
Insert on public.test_table  (cost=0.00..0.04 rows=0 width=0) (actual time=0.055..0.056 rows=0 loops=1)
  ->  Values Scan on "*VALUES*"  (cost=0.00..0.04 rows=3 width=122) (actual time=0.003..0.008 rows=3 loops=1)
        Output: "*VALUES*".column1, "*VALUES*".column2
Query Identifier: jtkjkexhjotbo
Planning Time: 0.068 ms
Execution Time: 0.543 ms
Statement DPU Estimate:
  Compute: 0.01550 DPU
  Read: 0.00307 DPU (Transaction minimum: 0.00375)
  Write: 0.01875 DPU (Transaction minimum: 0.05000)
  Total: 0.03732 DPU
```

此语句主要执行写入操作，因此大部分成本与写入 DPU 相关。计算 DPU（0.01550）表示处理并插入值所使用的计算资源。读取 DPU（0.00307）反映系统轻量级读取操作（如目录查询或索引检查）所使用的资源。

请注意读取 DPU 和写入 DPU 旁边显示的事务最低计费标准。这些值代表单次事务的基准成本，*仅在操作涉及数据读取或写入时适用*。这并不意味着每个事务都会自动产生 0.00375 读取 DPU 或 0.05 写入 DPU 的费用。相反，这些最低计费标准仅在事务级别进行成本聚合时适用，且仅当该事务内实际发生读取或写入操作时生效。由于范围差异，`EXPLAIN ANALYZE VERBOSE` 中的语句级估算值可能与 CloudWatch 或计费数据中报告的事务级指标不完全一致。

## 利用 DPU 信息进行优化
<a name="using-dpu-information-optimization"></a>

单语句 DPU 估算为您提供了一种强大的查询优化方式，其价值不仅限于缩短执行时间。常见使用案例包括：
+ **成本感知：**了解某一查询相对于其他查询的成本高低。
+ **架构优化：**比较索引或架构变更对性能与资源效率产生的影响。
+ **预算规划：**基于观测到的 DPU 使用量来估算工作负载成本。
+ **查询比较：**根据相对 DPU 使用量来评估替代查询方法。

## 解释 DPU 信息
<a name="interpreting-dpu-information"></a>

使用 `EXPLAIN ANALYZE VERBOSE` 中的 DPU 数据时，请记住以下最佳实践：
+ **定向地使用 DPU 数据：**将报告的 DPU 值视为了解查询*相对*成本的依据，而非与 CloudWatch 指标或计费数据完全一致的精确值。预计会出现差异，因为 `EXPLAIN ANALYZE VERBOSE` 报告的是语句级成本，而 CloudWatch 聚合的是事务级活动。此外，CloudWatch 还包括 `EXPLAIN ANALYZE VERBOSE` 有意排除的后台操作（例如 ANALYZE 或压缩）和事务开销（`BEGIN`/`COMMIT`）。
+ 在分布式系统中，**DPU 在不同的运行间存在波动是正常现象**，并不表示出现错误。缓存、执行计划更改、并发性或数据分布偏移等因素都可能导致同一查询在不同的运行时消耗的资源量存在差异。
+ **批量处理小型操作：**如果您的工作负载发出许多小型语句，建议将其批量合并为大型操作（不超过 10 MB）。这可减少四舍五入开销，并生成更具参考价值的成本估算值。
+ **用于调优，而非计费：**`EXPLAIN ANALYZE VERBOSE` 中的 DPU 数据专为成本感知、查询调优和优化设计，并非计费级指标。要获取权威的成本和使用量数据，请始终以 CloudWatch 指标或月度账单报告为准。