実際のCREATE DATABASEの動作は、既存のデータベースをコピーすることです。 デフォルトでは、template1という名前の標準のシステムデータベースをコピーします。 したがって、このデータベースは新しく作成するデータベースの元になる"テンプレート"となります。 template1にオブジェクトを追加した場合、追加したオブジェクトはその後に作成されるユーザデータベースにコピーされます。 この振舞いによって、データベース標準オブジェクト群にサイト独自の変更を行うことができます。 例えば、PL/pgSQL手続き言語をtemplate1にインストールした場合、データベースを作成する時に追加操作を行うことなく、自動的にこの言語をユーザデータベースで使用することができます。
template0という名前の二次的な標準システムデータベースがあります。 このデータベースにはtemplate1の初期内容と同じデータが含まれています。 つまり、使用しているバージョンのPostgreSQLで定義済みの標準オブジェクトのみから構成されています。 template0をinitdb実行後に変更してはいけません。 CREATE DATABASEをtemplate1ではなくtemplate0をコピーするように実行することで、template1に追加されたサイト独自のものを含まない、"汚れがない"ユーザデータベースを作成することができます。 これは特に、pg_dumpダンプからリストアする時に便利です。 このダンプスクリプトは、現時点で template1 に存在する可能性がある追加されたものと衝突しないようにダンプしたデータベースの内容を正しく再作成するために、汚れのないデータベースにリストアされなければなりません。
template0をコピーしてデータベースを作成するには、
CREATE DATABASE dbname TEMPLATE template0;
をSQL環境から実行するか、または
createdb -T template0 dbname
をシェルから実行します。
さらにテンプレートデータベースを作成することができます。 また、実際のところCREATE DATABASEのテンプレートとして名前を指定することで、クラスタ内の任意のデータベースをコピーすることができます。 しかし、この機能は、(まだ)汎用目的の"COPY DATABASE"能力を意図したものではないことは理解しておいてください。 コピー操作の間、他のセッションから元のデータベースに接続することができないという点が大きな制限です。 CREATE DATABASEは、その起動時に他の接続が存在する場合失敗します。 さらに、CREATE DATABASEが終わるまで、元のデータベースへの新しい接続はロックされます。
datistemplate列とdatallowconn列という、データベースそれぞれに有用なフラグがpg_databaseに存在します。 datistemplateは、そのデータベースがCREATE DATABASEのテンプレートとして使用されることを目的としているものであることを意味するために設定することができます。 このフラグが設定された場合、CREATEDB権限を持つ全てのユーザはそのデータベースを複製することができます。 設定されていない場合は、スーパーユーザとそのデータベース所有者のみがそれを複製することができます。 datallowconnが偽の場合、そのデータベースへの新規接続はできません(しかし、このフラグを偽にするだけでは既存のセッションは閉ざされません)。 template0データベースは、変更を防ぐために、通常datallowconn = falseとされています。 template0とtemplate1の両方は、常にdatistemplate = trueとされていなければなりません。
注意: template1とtemplate0には、template1という名前がCREATE DATABASEのデフォルトのソースデータベースの名前であること以上の特別な地位はありません。 例えば、template1を削除し、template0から再作成しても何も問題ありません。 この操作は、不注意にごみをtemplate1に追加してしまった場合にお勧めします。 (template1を削除するには、pg_database.datistemplate = falseとしなければなりません。)
データベースクラスタが初期化される時、postgresも作成されます。 このデータベースは、ユーザとアプリケーションのデフォルトの接続先を意図したものです。 これはtemplate1の単純な複製で、必要に応じて削除したり再作成したりすることができます。