参考网址
了解 PostgreSQL的人肯定听过 template1 和 template0,这两个作为模板库,在建库的时候会用到,但这两者是有很大差别的,曾经一段时间对这两个模板库的使用比较模糊,今天再次查看了文档,决定通过实验记录下来。
关于默认模板库
默认模板库为 template1
postgres=# create database db1;
CREATE DATABASE
备注:建库时如果不指定 TEMPLATE 属性,默认用的是 template1 模板库.
手工指定模板库
postgres=# create database db2 template template0;
CREATE DATABASE
备注:也可以指定模板库为 template0
template1 和 template0 的区别?
数据库初始化之后, 就有了 template0, template1 库,开始时这两个库的内容是一样的,但这两个库有啥异同呢?
template1 可以连接并创建对象,template0 不可以连接
postgres=# \c template1
You are now connected to database “template1” as user “postgres”.
template1=# create table tmp_1( id int4);
CREATE TABLE
template1=# \c template0
FATAL: database “template0” is not currently accepting connections
Previous connection kept
备注:当然可以通过其它方法连接 template0 库。正因为 template1 可以创建对像,相比 template0 ,被称为非干净数据库,而 template0被称为干净的数据库。
使用 template1 模板库建库时不可指定新的 encoding 和 locale,而 template0 可以
template1=# create database db3 TEMPLATE template0 ENCODING ‘SQL_ASCII’ ;
CREATE DATABASE
template1=# create database db4 TEMPLATE template1 ENCODING ‘SQL_ASCII’ ;
ERROR: new encoding (SQL_ASCII) is incompatible with the encoding of the template database (UTF8)
HINT: Use the same encoding as in the template database, or use template0 as template.
template0 库和 template1 都不可删除
postgres=# drop database template0;
ERROR: cannot drop a template database
postgres=# drop database template1;
ERROR: cannot drop a template database
备注:当然有方法删除 template1 库,而且这个操作并不危险,需要修改系统表,这里不演示了。
关于复制数据库
之前简单介绍了 template0 和 template1 的异同,有必要介绍通过模板库复制库的操作,例如这里已经有个 francs 库了,现在想复制一个 francs1 库,内容和francs 库一样。
复制库
postgres=# \c francs
You are now connected to database “francs” as user “postgres”.
francs=# select count(*) from pg_stat_user_tables ;
count 41 (1 row)
postgres=# create database francs1 TEMPLATE francs ;
CREATE DATABASE
postgres=# \c francs1 francs
You are now connected to database “francs1” as user “francs”.
francs1=> select count(*) from pg_stat_user_tables ;
count 41 (1 row)
备注:这种方法在复制数据库时提供了方便, 也可以定制自己的数据库模板,但是这么操作有个前提,复制时源库不可以连接,复制过程中也不允许连接源库, 否则会报以下错误:
ERROR: source database “francs” is being accessed by other users
DETAIL: There is 1 other session using the database.
根据需要创建符合自己编码方式的数据库
CREATE DATABASE fintest
WITH
OWNER = postgres
ENCODING = ‘UTF8’
LC_COLLATE = ‘en_US.utf8’
LC_CTYPE = ‘en_US.utf8’
TABLESPACE = pg_default
template = template0
CONNECTION LIMIT = -1;
检查 /etc/profile 文件。应该在里面加入:
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
export LC_CTYPE=en_US.UTF-8
整体的环境变量如果设置好了也不会出现后面的事。postgres用户也不会变成别的字符集。
postgres不仅创建的数据库字符集是LATIN1 ,连postgres和template 0 和template1 都是LATIN1.
解决代码:
update pg_database set datallowconn = TRUE where datname = ‘template0’;
\c template0
update pg_database set datistemplate = FALSE where datname = ‘template1’;
drop database template1;
create database template1 with encoding = ‘UTF8’ LC_CTYPE = ‘en_US.UTF-8’ LC_COLLATE = ‘en_US.UTF-8’ template = template0;
update pg_database set datallowconn = TRUE where datname = ‘template1’;
\c template1
update pg_database set datallowconn = FALSE where datname = ‘template0’;