実際のCREATE DATABASE
の動作は、既存のデータベースをコピーすることです。
デフォルトでは、template1
という名前の標準のシステムデータベースをコピーします。
したがって、このデータベースは新しく作成するデータベースの元になる「テンプレート」となります。
template1
にオブジェクトを追加した場合、追加したオブジェクトはその後に作成されるユーザデータベースにコピーされます。
この振舞いによって、データベース標準オブジェクト群にサイト独自の変更を行うことができます。
例えば、PL/Perl手続き言語をtemplate1
にインストールした場合、データベースを作成する時に追加作業を行うことなく、自動的にこの言語をユーザデータベースで使用できます。
しかし、CREATE DATABASE
は、元のデータベースに付加されたデータベースレベルのGRANT
権限をコピーしません。
新しいデータベースにはデフォルトのデータベースレベルの権限があります。
template0
という名前の二次的な標準システムデータベースがあります。
このデータベースにはtemplate1
の初期内容と同じデータが含まれています。
つまり、使用しているバージョンのPostgreSQLで定義済みの標準オブジェクトのみから構成されています。
template0
をデータベースクラスタを初期化した後に変更してはいけません。
CREATE DATABASE
をtemplate1
ではなくtemplate0
をコピーするように実行することで、template1
に追加されたサイト独自のものを含まない、(そこではユーザ定義オブジェクトは存在せず、システムオブジェクトは変更されていない)「汚れがない」ユーザデータベースを作成できます。
これは特に、pg_dump
ダンプからリストアする時に便利です。
このダンプスクリプトは、後でtemplate1
に追加される可能性のあるオブジェクトと衝突しないように、ダンプしたデータベースの内容を正しく再作成するために、汚れのないデータベースにリストアされなければなりません。
template1
の代わりにtemplate0
をコピーするその他の一般的な理由は、template0
をコピーするときに新規の符号化方式とロケールを設定できることです。
一方、template1
のコピーはそれが行ったと同一の設定を使用しなければなりません。
これはtemplate0
が認識されていない一方で、template1
が符号化方式特有の、またはロケール特有のデータを含んでいる可能性があることに依ります。
template0
をコピーしてデータベースを作成するには、
CREATE DATABASE dbname
TEMPLATE template0;
をSQL環境から実行するか、または
createdb -T template0 dbname
をシェルから実行します。
さらにテンプレートデータベースを作成することができます。
また、実際のところCREATE DATABASE
のテンプレートとして名前を指定することで、クラスタ内の任意のデータベースをコピーできます。
しかし、この機能は、(まだ)汎用目的の「COPY 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
の単純なコピーで、必要に応じて削除したり再作成したりできます。