

# PostGIS 확장을 사용하여 공간 데이터 관리
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS"></a>

PostGIS는 공간 정보를 저장하고 관리하기 위해 PostgreSQL을 확장한 것입니다. PostGIS에 대한 자세한 내용은 [PostGIS.net](https://postgis.net/)을 참조하세요.

버전 10.5부터 PostgreSQL은 맵 상자 벡터 타일 데이터 작업을 위해 PostGIS에서 사용하는 libprotobuf 1.3.0 라이브러리를 지원합니다.

PostGIS 확장을 설정하려면 `rds_superuser` 권한이 필요합니다. PostGIS 확장 프로그램 및 공간 데이터를 관리할 사용자(역할)를 생성하는 것이 좋습니다. PostGIS 확장 프로그램 및 관련 구성 요소는 PostgreSQL에 수천 개의 함수를 추가합니다. 사용 사례에 적합한 경우 자체 스키마에서 PostGIS 확장 프로그램을 만드는 것이 좋습니다. 다음 예제에서는 자체 데이터베이스에 확장 프로그램을 설치하는 방법을 보여주지만, 필수 사항은 아닙니다.

**Topics**
+ [

## 1단계: PostGIS 확장을 관리할 사용자(역할) 생성
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Connect)
+ [

## 2단계: PostGIS 확장 모듈을 로드합니다.
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.LoadExtensions)
+ [

## 3단계: 확장 스키마 소유권 이전
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferOwnership)
+ [

## 4단계: PostGIS 테이블 소유권 이전
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferObjects)
+ [

## 5단계: 확장 모듈을 테스트합니다.
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Test)
+ [

## 6단계: PostGIS 확장 업그레이드
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Update)
+ [PostGIS 확장 버전](#CHAP_PostgreSQL.Extensions.PostGIS)
+ [PostGIS 2를 PostGIS 3으로 업그레이드](#PostgreSQL.Extensions.PostGIS.versions.upgrading.2-to-3)

## 1단계: PostGIS 확장을 관리할 사용자(역할) 생성
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.Connect"></a>

먼저 `rds_superuser` 권한이 있는 사용자로 RDS for PostgreSQL DB 인스턴스에 연결합니다. 인스턴스를 설정할 때 기본 이름을 유지했다면 `postgres`로 연결합니다.

```
psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
```

PostGIS 확장을 관리하기 위해 별도의 역할(사용자)을 생성합니다.

```
postgres=>  CREATE ROLE gis_admin LOGIN PASSWORD 'change_me';
CREATE ROLE
```

역할이 확장을 설치하도록 허용하려면 이 역할 `rds_superuser` 권한을 부여합니다.

```
postgres=> GRANT rds_superuser TO gis_admin;
GRANT
```

PostGIS 아티팩트에 사용할 데이터베이스를 만듭니다. 이 단계는 선택 사항입니다. 또는 PostGIS 확장을 위해 사용자 데이터베이스에 스키마를 생성할 수 있지만 이 역시 필수 사항은 아닙니다.

```
postgres=> CREATE DATABASE lab_gis;
CREATE DATABASE
```

`gis_admin`에게 `lab_gis` 데이터베이스에 대한 모든 권한을 부여합니다.

```
postgres=> GRANT ALL PRIVILEGES ON DATABASE lab_gis TO gis_admin;
GRANT
```

세션을 종료하고 다음과 같이 RDS for PostgreSQL DB 인스턴스에 `gis_admin`으로 다시 연결합니다.

```
postgres=> psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=gis_admin --password --dbname=lab_gis
Password for user gis_admin:...
lab_gis=>
```

다음 단계에 설명된 대로 확장 프로그램을 계속 설정합니다.

## 2단계: PostGIS 확장 모듈을 로드합니다.
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.LoadExtensions"></a>

PostGIS 확장에는 지리 공간 기능을 제공하기 위해 함께 작동하는 여러 관련 확장이 포함되어 있습니다. 사용 사례에 따라 이 단계에서 만든 확장이 모두 필요하지 않을 수 있습니다.

`CREATE EXTENSION` 문을 사용하여 PostGIS 확장 모듈을 로드합니다.

```
CREATE EXTENSION postgis;
CREATE EXTENSION
CREATE EXTENSION postgis_raster;
CREATE EXTENSION
CREATE EXTENSION fuzzystrmatch;
CREATE EXTENSION
CREATE EXTENSION postgis_tiger_geocoder;
CREATE EXTENSION
CREATE EXTENSION postgis_topology;
CREATE EXTENSION
CREATE EXTENSION address_standardizer_data_us;
CREATE EXTENSION
```

다음 예에 표시된 확장 및 해당 소유자가 나열된 SQL 쿼리를 실행하여 결과를 확인할 수 있습니다.

```
SELECT n.nspname AS "Name",
  pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner"
  FROM pg_catalog.pg_namespace n
  WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'
  ORDER BY 1;
List of schemas
     Name     |   Owner
--------------+-----------
 public       | postgres
 tiger        | rdsadmin
 tiger_data   | rdsadmin
 topology     | rdsadmin
(4 rows)
```

## 3단계: 확장 스키마 소유권 이전
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferOwnership"></a>

ALTER SCHEMA 문을 사용하여 스키마 소유권을 `gis_admin` 역할로 이전합니다.

```
ALTER SCHEMA tiger OWNER TO gis_admin;
ALTER SCHEMA
ALTER SCHEMA tiger_data OWNER TO gis_admin; 
ALTER SCHEMA
ALTER SCHEMA topology OWNER TO gis_admin;
ALTER SCHEMA
```

다음 SQL 쿼리를 실행하여 소유권 변경을 확인할 수 있습니다. 또는 psql 명령줄에서 `\dn` 메타 명령을 사용할 수 있습니다.

```
SELECT n.nspname AS "Name",
  pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner"
  FROM pg_catalog.pg_namespace n
  WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'
  ORDER BY 1;

       List of schemas
     Name     |     Owner
--------------+---------------
 public       | postgres
 tiger        | gis_admin
 tiger_data   | gis_admin
 topology     | gis_admin
(4 rows)
```

## 4단계: PostGIS 테이블 소유권 이전
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferObjects"></a>

**참고**  
PostGIS 함수의 소유권을 변경하지 마세요. PostGIS를 올바르게 운영하고 향후 업그레이드하려면 이러한 함수가 원래 소유권을 유지해야 합니다. PostGIS 권한에 대한 자세한 내용은 [PostgreSQL 보안](https://postgis.net/workshops/postgis-intro/security.html)을 참조하세요.

다음 함수를 사용하여 PostGIS 테이블 소유권을 `gis_admin` 역할로 이전합니다. psql 프롬프트에서 다음 문을 실행하여 함수를 생성합니다.

```
CREATE FUNCTION exec(text) returns text language plpgsql volatile AS $f$ BEGIN EXECUTE $1; RETURN $1; END; $f$;
CREATE FUNCTION
```

그런 다음 쿼리로 `exec` 함수를 실행하면 함수가 해당하는 문을 실행하여 권한을 변경합니다.

```
SELECT exec('ALTER TABLE ' || quote_ident(s.nspname) || '.' || quote_ident(s.relname) || ' OWNER TO gis_admin;')
  FROM (
    SELECT nspname, relname
    FROM pg_class c JOIN pg_namespace n ON (c.relnamespace = n.oid) 
    WHERE nspname in ('tiger','topology') AND
    relkind IN ('r','S','v') ORDER BY relkind = 'S')
s;
```

## 5단계: 확장 모듈을 테스트합니다.
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.Test"></a>

스키마 이름을 지정할 필요가 없도록 하려면 다음 명령을 사용하여 검색 경로에 `tiger` 스키마를 추가하세요.

```
SET search_path=public,tiger;
SET
```

다음 SELECT 문을 사용하여 `tiger` 스키마를 테스트합니다.

```
SELECT address, streetname, streettypeabbrev, zip
 FROM normalize_address('1 Devonshire Place, Boston, MA 02109') AS na;
address | streetname | streettypeabbrev |  zip
---------+------------+------------------+-------
       1 | Devonshire | Pl               | 02109
(1 row)
```

이 확장에 대한 자세한 내용은 PostGIS 문서에서 [Tiger Geocoder](https://postgis.net/docs/Extras.html#Tiger_Geocoder)를 참조하세요.

다음 `SELECT` 문을 사용하여 `topology` 스키마를 테스트합니다. 이렇게 하면 지정된 공간 참조 식별자(26986) 및 기본 허용 오차(0.5)를 사용하여 새 토폴로지 개체(my\$1new\$1topo)를 등록하는 `createtopology` 함수를 호출합니다. 자세한 내용은 PostgreSQL의 [CreateTopology](https://postgis.net/docs/CreateTopology.html) 문서를 참조하세요.

```
SELECT topology.createtopology('my_new_topo',26986,0.5);
 createtopology
----------------
              1
(1 row)
```

## 6단계: PostGIS 확장 업그레이드
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.Update"></a>

PostgreSQL의 각 새 릴리스는 해당 릴리스와 호환되는 하나 이상의 PostGIS 확장 버전을 지원합니다. PostgreSQL 엔진을 새 버전으로 업그레이드해도 PostGIS 확장은 자동으로 업그레이드되지 않습니다. PostgreSQL 엔진을 업그레이드하려면 일반적으로 PostGIS를 현재 PostgreSQL 버전에서 사용 가능한 최신 버전으로 업그레이드를 먼저 해야 합니다. 자세한 내용은 [PostGIS 확장 버전](#CHAP_PostgreSQL.Extensions.PostGIS) 단원을 참조하세요.

PostgreSQL 엔진 업그레이드 후 PostGIS 확장을 새로 업그레이드된 PostgreSQL 엔진 버전에 대해 지원되는 버전으로 다시 업그레이드합니다. PostgreSQL 엔진 업그레이드에 대한 자세한 내용은 [RDS for PostgreSQL에 대한 메이저 버전 업그레이드를 수행하는 방법](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Process.md) 단원을 따라가세요.

 RDS for PostgreSQL DB 인스턴스에서 사용 가능한 PostGIS 확장 버전 업데이트를 언제든지 확인할 수 있습니다. 이렇게 하려면 다음 명령을 실행합니다. 이 기능은 PostGIS 2.5.0 이상 버전에서 사용할 수 있습니다.

```
SELECT postGIS_extensions_upgrade();
```

애플리케이션이 최신 PostGIS 버전을 지원하지 않는 경우에도 다음과 같이 사용 중인 메이저 버전에서 사용할 수 있는 이전 버전의 PostGIS를 설치할 수 있습니다.

```
CREATE EXTENSION postgis VERSION "2.5.5";
```

이전 버전에서 특정 PostGIS 버전으로 업그레이드하려는 경우 다음 명령을 사용할 수도 있습니다.

```
ALTER EXTENSION postgis UPDATE TO "2.5.5";
```

업그레이드하는 버전에 따라 이 기능을 다시 사용해야 할 수도 있습니다. 기능의 첫 번째 실행 결과에 따라 추가 업그레이드 기능이 필요한지 여부가 결정됩니다. PostGIS 2에서 PostGIS 3으로 업그레이드하는 경우를 예로 들 수 있습니다. 자세한 내용은 [PostGIS 2를 PostGIS 3으로 업그레이드](#PostgreSQL.Extensions.PostGIS.versions.upgrading.2-to-3)을 참조하세요.

PostgreSQL 엔진의 메이저 버전 업그레이드를 준비하기 위해 이 확장을 업그레이드했다면 다른 예비 작업을 계속할 수 있습니다. 자세한 내용은 [RDS for PostgreSQL에 대한 메이저 버전 업그레이드를 수행하는 방법](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Process.md) 단원을 참조하세요.

## PostGIS 확장 버전
<a name="CHAP_PostgreSQL.Extensions.PostGIS"></a>

*Aurora PostgreSQL 릴리스 정보*의 *Amazon RDS for PostgreSQL 릴리스 정보*의 [Extension versions for Amazon RDS for PostgreSQL의 확장 버전](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html) 릴리스에서 사용 가능한 버전 목록을 얻으려면 다음 명령을 사용하세요.

```
SELECT * FROM pg_available_extension_versions WHERE name='postgis';
```

*Amazon RDS for PostgreSQL 릴리스 정보*의 다음 단원에서 버전 정보를 확인할 수 있습니다.
+ [ Amazon RDS에서 PostgreSQL 버전 16 확장 지원](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-16x)
+ [ Amazon RDS에서 지원되는 PostgreSQL 버전 15 확장](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-15x)
+ [ Amazon RDS에서 지원되는 PostgreSQL 버전 14 확장](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-14x)
+ [ Amazon RDS에서 지원되는 PostgreSQL 버전 13 확장](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-13x)
+ [ Amazon RDS에서 지원되는 PostgreSQL 버전 12 확장](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-12x)
+ [ Amazon RDS에서 지원되는 PostgreSQL 버전 11 확장](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-11x)
+ [ Amazon RDS에서 지원되는 PostgreSQL 버전 10 확장](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-101x)
+ [ Amazon RDS에서 지원되는 PostgreSQL 버전 9.6.x 확장](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-96x)

## PostGIS 2를 PostGIS 3으로 업그레이드
<a name="PostgreSQL.Extensions.PostGIS.versions.upgrading.2-to-3"></a>

버전 3.0부터 PostGIS 래스터 기능이 이제 별도의 확장인 `postgis_raster`입니다. 이 확장에는 자체 설치 및 업그레이드 경로가 있습니다. 이러한 경로를 통해 코어에서 핵심 `postgis` 확장에서 래스터 이미지 처리에 필요한 수십 가지 기능, 데이터 유형 및 기타 아티팩트를 제거합니다. 즉, 사용 사례에 래스터 처리가 필요하지 않은 경우 `postgis_raster` 확장을 설치할 필요가 없습니다.

다음 업그레이드 예에서 첫 번째 업그레이드 명령은 래스터 기능을 `postgis_raster` 확장으로 추출합니다. 그런 다음 `postgis_raster`를 새 버전으로 업그레이드하려면 두 번째 업그레이드 명령이 필요합니다.

**PostGIS 2에서 PostGIS 3으로 업그레이드하려면**

1. 의 PostgreSQL 버전에 사용할 수 있는 PostGIS의 기본 버전을 식별합니다. RDS for PostgreSQL DB 인스턴스  이렇게 하려면 다음 쿼리를 실행합니다.

   ```
   SELECT * FROM pg_available_extensions
       WHERE default_version > installed_version;
     name   | default_version | installed_version |                          comment
   ---------+-----------------+-------------------+------------------------------------------------------------
    postgis | 3.1.4           | 2.3.7             | PostGIS geometry and geography spatial types and functions
   (1 row)
   ```

1. 에서 각 데이터베이스에 설치된 PostGIS 버전을 식별합니다. 사용자의 RDS for PostgreSQL DB 인스턴트. 즉, 다음과 같이 각 사용자 데이터베이스를 쿼리합니다.

   ```
   SELECT
       e.extname AS "Name",
       e.extversion AS "Version",
       n.nspname AS "Schema",
       c.description AS "Description"
   FROM
       pg_catalog.pg_extension e
       LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace
       LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid
       AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass
   WHERE
       e.extname LIKE '%postgis%'
   ORDER BY
       1;
     Name   | Version | Schema |                             Description
   ---------+---------+--------+---------------------------------------------------------------------
    postgis | 2.3.7   | public | PostGIS geometry, geography, and raster spatial types and functions
   (1 row)
   ```

   기본 버전(PostGIS 3.1.4)과 설치된 버전(PostGIS 2.3.7) 간의 이러한 불일치는 PostGIS 확장을 업그레이드해야 함을 의미합니다.

   ```
   ALTER EXTENSION postgis UPDATE;
   ALTER EXTENSION
   WARNING: unpackaging raster
   WARNING: PostGIS Raster functionality has been unpackaged
   ```

1. 다음 쿼리를 실행하여 래스터 기능이 이제 자체 패키지에 포함되어 있는지 확인합니다.

   ```
   SELECT
       probin,
       count(*)
   FROM
       pg_proc
   WHERE
       probin LIKE '%postgis%'
   GROUP BY
       probin;
             probin          | count
   --------------------------+-------
    $libdir/rtpostgis-2.3    | 107
    $libdir/postgis-3        | 487
   (2 rows)
   ```

   출력 결과를 통해 여전히 버전 간에 여전히 차이가 있음을 알 수 있습니다. PostGIS 함수는 버전 3(postgis-3)이고 래스터 함수(rtpostgis)는 버전 2(rtpostgis-2.3)입니다. 업그레이드를 완료하려면 다음과 같이 upgrade 명령을 다시 실행합니다.

   ```
   postgres=> SELECT postgis_extensions_upgrade();
   ```

   경고 메시지는 무시해도 됩니다. 다음 쿼리를 다시 실행하여 업그레이드가 완료되었는지 확인합니다. PostGIS 및 모든 관련 확장 프로그램이 업그레이드 필요 항목으로 표시되지 않으면 업그레이드가 완료된 것입니다.

   ```
   SELECT postgis_full_version();
   ```

1. 다음 쿼리를 사용하여 완료된 업그레이드 프로세스와 별도로 패키징된 확장을 확인하고 해당 버전이 일치하는지 확인합니다.

   ```
   SELECT
       e.extname AS "Name",
       e.extversion AS "Version",
       n.nspname AS "Schema",
       c.description AS "Description"
   FROM
       pg_catalog.pg_extension e
       LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace
       LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid
           AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass
   WHERE
       e.extname LIKE '%postgis%'
   ORDER BY
       1;
         Name      | Version | Schema |                             Description
   ----------------+---------+--------+---------------------------------------------------------------------
    postgis        | 3.1.5   | public | PostGIS geometry, geography, and raster spatial types and functions
    postgis_raster | 3.1.5   | public | PostGIS raster types and functions
   (2 rows)
   ```

   출력은 PostGIS 2 확장이 PostGIS 3으로 업그레이드되었으며 `postgis`와 현재 별도의 `postgis_raster` 확장이 모두 버전 3.1.5임을 보여줍니다.

이 업그레이드가 완료된 후 래스터 기능을 사용하지 않으려는 경우 다음과 같이 확장을 삭제할 수 있습니다.

```
DROP EXTENSION postgis_raster;
```