テンプレートデータベースの使用・作成・削除（PostgreSQL）

#テンプレートデータベースとは
　データベースを新規で作成するときに、**ひな型となるデータベース**のことです。
　例えば、もしテンプレートデータベースtemplate_experiment_databaseにtemplate_experimentテーブルがあれば、そのテンプレートデータベースをもとに新規で作成したデータベースexperimetn_databaseにもtemplate_experimentテーブルが作成されています。

#テンプレートデータベースの使い方
　(1)テンプレートデータベースを使って新規のデータベースを作成する方法、(2)テンプレートデータベースを作成する方法、(3)テンプレートデータベースを削除する方法を紹介します。

##(1)テンプレートデータベースを使ってデータベースを作成する
　テンプレートデータベースtemplate_experiment_databaseを使って、新規のデータベースexperiment_databaseを作成してみましょう。以下の二つの方法で作成することができます。ちなみに、何もテンプレートデータベースを指定せずにデータベースを作成した場合、デフォルトのテンプレートデータベース**template1が勝手にテンプレートデータベースとなっています**。

(1)createdbで-Tオプションを使う
**書き方：createdb 新規データベース名 -T テンプレートデータベース名**

```
$ createdb experiment_database -T template_experiment_database
```

(2)CREATE DATABASEでTEMPLATEを使う
**書き方：CREATE DATABASE 新規データベース名 TEMPLATE テンプレートデータベース名;**

```sql
postgres=# create database experiment_database template template_experiment_database;
CREATE DATABASE
```


##(2)テンプレートデータベースを作成する
　テンプレートデータベースは以下のようにして自分で作成することができます。

**書き方：CREATE DATABASE テンプレートデータベース名 IS_TEMPLATE true;**

```sql
postgres=# create database template_experiment_database is_template true;
CREATE DATABASE
```

　既存のデータベースをテンプレートデータベースにすることもできます。**ALTER DATABASE**を使用します。

**書き方：ALTER DATABASE テンプレートデータベース名 IS_TEMPLATE true;**

```sql
postgres=# alter database template_experiment_database is_template true;
ALTER DATABASE
```

　ちなみに、テンプレートデータベースでなくする場合には**IS_TEMPLATE false**とします。

##(3)テンプレートデータベースの削除
　テンプレートデータベースはdropdbしても削除することはできません。まず、**ALTER DATABASE～IS_TEMPLATE false;**でテンプレートデータベースから普通のデータベースに変更します（pg_database.datistemplateがfalseになる）。そのあとにdropdbを実行します。ただし、template0は削除することができません。
　ちなみにシステムカタログのpg_databaseはテーブルであるためUPDATEで変更することも可能ですが、システムカタログを直接変更してはいけません（マニュアルのシステムカタログを参照）。

```sql
$ dropdb template_experiment_database       --テンプレートデータベースであるため削除できない
2019-11-06 06:27:35.644 JST [4674] ERROR:  cannot drop a template database
2019-11-06 06:27:35.644 JST [4674] STATEMENT:  DROP DATABASE template_experiment             _database;
dropdb: error: database removal failed: ERROR:  cannot drop a template database

$ psql template_experiment_database         

template_experiment_database=# select * from pg_database;   --datistemplateがtrueになっていることを確認しているだけ
-[ RECORD 4 ]-+------------------------------
oid           | 65600
datname       | template_experiment_database
datdba        | 10
encoding      | 6
datcollate    | ja_JP.UTF-8
datctype      | ja_JP.UTF-8
datistemplate | t
datallowconn  | t
datconnlimit  | -1
datlastsysoid | 13592
datfrozenxid  | 479
datminmxid    | 1
dattablespace | 1663
datacl        |

template_experiment_database=# alter database template_experiment_database is_template false;                 --テンプレートデータベースから普通のデータベースに変更する
ALTER DATABASE

template_experiment_database=# select * from pg_database;   --datistemplateがfalseになっているかを確認
-[ RECORD 6 ]-+------------------------------
oid           | 65600
datname       | template_experiment_database
datdba        | 10
encoding      | 6
datcollate    | ja_JP.UTF-8
datctype      | ja_JP.UTF-8
datistemplate | f
datallowconn  | t
datconnlimit  | -1
datlastsysoid | 13592
datfrozenxid  | 479
datminmxid    | 1
dattablespace | 1663
datacl        |

template_experiment_database=# \q                          --template_experiment_databaseに接続したままだと削除できないため

$ dropdb template_experiment_database                      --template_experiment_databaseを削除
```
#まとめ
　新規のデータベースを作成するときには、-TオプションやTEMPLATEでテンプレートデータベースを指定することができました。
　テンプレートデータベースを作成するときにはIS_TEMPLATEをtrueに、削除するときにはIS_TEMPLATEをfalseにすることが必要です。
　最後までお読みいただき、ありがとうございました。

#参考
PostgreSQLマニュアル「テンプレートデータベース」
https://www.postgresql.jp/document/11/html/manage-ag-templatedbs.html
PostgreSQLマニュアル「システムカタログ」
https://www.postgresql.jp/document/11/html/catalogs.html