En realidad, CREATE DATABASE funciona copiando una base de
datos existente. Por defecto, copia la base de datos estándar del sistema llamada
template1. Por lo tanto, esa
base de datos es la “plantilla” a partir de la cual se crean las nuevas bases de
datos. Si añades objetos a template1, estos objetos
se copiarán en las bases de datos de usuario creadas posteriormente. Este
comportamiento permite realizar modificaciones locales del sitio en el conjunto estándar de
objetos de las bases de datos. Por ejemplo, si instalas el lenguaje de procedimientos
PL/Perl en template1, estará disponible automáticamente
en las bases de datos de usuario sin tener que realizar ninguna acción adicional
cuando se creen esas bases de datos.
Sin embargo, CREATE DATABASE no copia los permisos
GRANT a nivel de base de datos asociados a la base de datos origen.
La nueva base de datos tiene los permisos por defecto a nivel de base de datos.
Existe una segunda base de datos estándar del sistema llamada
template0. Esta
base de datos contiene los mismos datos que el contenido inicial de
template1, es decir, solo los objetos estándar
predefinidos por tu versión de
PostgreSQL. template0
nunca debería cambiarse después de que el clúster de bases de datos haya sido
inicializado. Al indicarle a
CREATE DATABASE que copie template0 en lugar
de template1, puedes crear una base de datos de usuario “intacta”
(una en la que no existen objetos definidos por el usuario y donde los objetos del sistema
no han sido alterados) que no contenga ninguna de las adiciones locales del sitio en
template1. Esto es particularmente útil cuando se restaura un
respaldo de pg_dump: el script de volcado debe restaurarse en una
base de datos intacta para garantizar que se recree el contenido correcto
de la base de datos volcada, sin conflictos con los objetos que
puedan haberse añadido a template1 más adelante.
Otra razón común para copiar template0 en lugar de
template1 es que se pueden especificar nuevos ajustes de codificación
y configuración regional (locale) al copiar template0, mientras que una copia
de template1 debe usar los mismos ajustes que esta tiene.
Esto se debe a que template1 podría contener datos específicos de la codificación
o de la configuración regional, mientras que se sabe que template0 no los tiene.
Para crear una base de datos copiando template0, usa:
CREATE DATABASE nombre_bd TEMPLATE template0;
desde el entorno SQL, o:
createdb -T template0 nombre_bd
desde la shell.
Es posible crear bases de datos plantilla adicionales y, de hecho,
se puede copiar cualquier base de datos de un clúster especificando su nombre
como plantilla para CREATE DATABASE. Sin embargo, es importante
entender que esto no está pensado (aún) como
una funcionalidad de “COPY DATABASE” de uso general.
La limitación principal es que ninguna otra sesión puede estar conectada a
la base de datos origen mientras se está copiando. CREATE
DATABASE fallará si existe cualquier otra conexión cuando se inicia;
durante la operación de copia, se impiden nuevas conexiones a la base de datos origen.
Existen dos etiquetas útiles en pg_database para cada
base de datos: las columnas datistemplate y
datallowconn. datistemplate
se puede establecer para indicar que una base de datos está pensada como plantilla para
CREATE DATABASE. Si esta etiqueta está activa, la base de datos puede ser
clonada por cualquier usuario con permisos CREATEDB; si no está activa,
solo los superusuarios y el propietario de la base de datos pueden clonarla.
Si datallowconn es falso, no se permitirán nuevas conexiones
a esa base de datos (pero las sesiones existentes no se terminan
simplemente por establecer la etiqueta en falso). La base de datos
template0 normalmente se marca como datallowconn = false para evitar su modificación.
Tanto template0 como template1
siempre deberían estar marcadas con datistemplate = true.
template1 y template0 no tienen ningún estado especial
más allá del hecho de que el nombre template1 es el nombre por defecto
de la base de datos origen para CREATE DATABASE.
Por ejemplo, se podría eliminar template1 y recrearla a partir de
template0 sin ningún efecto adverso. Este curso de acción
podría ser aconsejable si has añadido descuidadamente un montón de basura en
template1. (Para eliminar template1,
debe tener pg_database.datistemplate = false).
La base de datos postgres también se crea cuando se inicializa
un clúster de bases de datos. Esta base de datos está pensada como una base de datos por defecto para
que los usuarios y aplicaciones se conecten a ella. Es simplemente una copia de
template1 y se puede eliminar y volver a crear si es necesario.