

# `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\_invoker가 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은 이러한 언어 확장을 지원합니다.