CREATE DATABASE
实际上通过拷贝一个已有数据库进行工作。默认情况下,它拷贝名为template1
的标准系统数据库。所以该数据库是创建新数据库的“模板”。 如果你为template1
数据库增加对象,这些对象将被拷贝到后续创建的用户数据库中。 这种行为允许对数据库中标准对象集合的站点本地修改。例如,如果你把过程语言PL/Perl安装到 template1
中,那么你在创建用户数据库后不需要额外的操作就可以使用该语言。
系统里还有名为template0
的第二个标准系统数据库。这个数据库包含和template1
初始内容一样的数据,也就是说,只包含你的PostgreSQL版本预定义的标准对象。在数据库集簇被初始化之后,不应该对template0
做任何修改。通过指示CREATE DATABASE
使用template0
取代template1
进行拷贝,你可以创建一个“纯净的”用户数据库,它不会包含任何template1
中的站点本地附加物。 这一点在恢复一个pg_dump
转储时非常方便:转储脚本应该在一个纯净的数据库 中恢复以确保我们重建被转储数据库的正确内容,而不和任何现在可能已经被加入到template1
中的附加物相冲突。
另一个从template0
而不是template1
复制的常见原因是, 可以在复制template0
时指定新的编码和区域设置,而一个template1
的副本必须使用和它相同的设置。这是因为的template1
可能包含编码相关或区域相关的数据,而template0
中没有。
要通过拷贝template0
来创建一个数据库,使用:SQL 环境中的
CREATE DATABASE dbname
TEMPLATE template0;
或者 shell 中的
createdb -T template0 dbname
可以创建额外的模板数据库,并且实际上可以通过将集簇中任意数据库指定为CREATE DATABASE
的模板来从该数据库拷贝。不过,我们必需明白,这个功能并不是设计作为一般性的“COPY DATABASE
”功能。主要的限制是当源数据库被拷贝时,不能有其他会话连接到它。如果在CREATE DATABASE
开始时存在任何其它连接,那么该命令将会失败。在拷贝操作期间,到源数据库的新连接将被阻止。
对于每一个数据库在pg_database
中存在两个有用的标志: datistemplate
和datallowconn
列。datistemplate
可以被设置来指示该数据库是不是要作为CREATE DATABASE
的模板。如果设置了这个标志,那么该数据库可以被任何有 CREATEDB
权限的用户克隆;如果没有被设置,那么只有超级用户和该数据库的拥有者可以克隆它。如果datallowconn
为假,那么将不允许与该数据库建立任何新的连接(但已有的会话不会因为把该标志设置为假而被中止)。template0
通常被标记为datallowconn = false
来阻止对它的修改。template0
和template1
通常总是被标记为datistemplate = true
。
除了template1
是CREATE DATABASE
的默认源数据库名之外, template1
和template0
没有任何特殊的状态。例如,我们可以删除template1
然后从template0
重新创建它而不会有任何不良效果。如果我们不小心在template1
中增加了一堆垃圾,那么我们就会建议做这样的操作(要删除template1
,它必须有pg_database.datistemplate = false
)。
当数据库集簇被初始化时,也会创建postgres
数据库。这个数据库用于做为用户和应用连接的默认数据库。它只是 template1
的一个拷贝,需要时可以删除并重建。