<!--
$Header: /cvsroot/pgsql/doc/src/sgml/manage-ag.sgml,v 2.15 2001/09/13 15:55:23 petere Exp $
-->

<chapter id="managing-databases">
 <title>Managing Databases</title>

 <para>
  A database is a named collection of SQL objects (<quote>database
  objects</quote>); every database object (tables, function, etc.)
  belongs to one and only one database. An application that connects
  to the database server specifies with its connection request the
  name of the database it wants to connect to. It is not possible to
  access more than one database per connection. (But an application
  is not restricted in the number of connections it opens to the same
  or other databases.)
 </para>

 <note>
  <para>
   <acronym>SQL</> calls databases <quote>catalogs</>, but there is no
   difference in practice.
  </para>
 </note>

 <para>
  In order to create or drop databases, the <productname>Postgres</>
  <application>postmaster</> must be up and running (see <xref
  linkend="postmaster-start">).
 </para>

 <sect1 id="manage-ag-createdb">
  <title>Creating a Database</title>

  <para>
   Databases are created with the query language command
   <command>CREATE DATABASE</command>:
<synopsis>
CREATE DATABASE <replaceable>name</>
</synopsis>
   where <replaceable>name</> can be chosen freely. (Depending on the
   current implementation, certain characters that are special to the
   underlying operating system might be prohibited. There will be
   run-time checks for that.) The current user automatically becomes
   the owner of the new database. It is the privilege of the owner of
   a database to remove it later on (which also removes all the
   objects in it, even if they have a different owner).
  </para>

  <para>
   The creation of databases is a restricted operation. See <xref
   linkend="user-attributes"> how to grant permission.
  </para>

  <formalpara>
   <title>Bootstrapping</title>
   <para>
    Since you need to be connected to the database server in order to
    execute the <command>CREATE DATABASE</command> command, the
    question remains how the <emphasis>first</> database at any given
    site can be created. The first database is always created by the
    <command>initdb</> command when the data storage area is
    initialized. (See <xref linkend="creating-cluster">.) This
    database is called <literal>template1</> and cannot be deleted. So
    to create the first <quote>real</> database you can connect to
    <literal>template1</>.
   </para>
  </formalpara>

  <para>
   The name <quote>template1</quote> is no accident: When a new
   database is created, the template database is essentially cloned.
   This means that any changes you make in <literal>template1</> are
   propagated to all subsequently created databases. This implies that
   you should not use the template database for real work, but when
   used judiciously this feature can be convenient.
  </para>

  <para>
   As an extra convenience, there is also a program that you can
   execute from the shell to create new databases,
   <filename>createdb</>.

<synopsis>
createdb <replaceable class="parameter">dbname</replaceable>
</synopsis>

   <command>createdb</> does no magic. It connects to the template1
   database and executes the <command>CREATE DATABASE</> command,
   exactly as described above. It uses <application>psql</> program
   internally. The reference page on <command>createdb</> contains the invocation
   details. In particular, <command>createdb</> without any arguments will create
   a database with the current user name, which may or may not be what
   you want.
  </para>

  <sect2>
   <title>Alternative Locations</title>

   <para>
    It is possible to create a database in a location other than the
    default. Remember that all database access occurs through the
    database server backend, so that any location specified must be
    accessible by the backend.
   </para>

   <para>
    Alternative database locations are referenced by an environment
    variable which gives the absolute path to the intended storage
    location. This environment variable must have been defined before
    the backend was started. Any valid environment variable name may
    be used to reference an alternative location, although using
    variable names with a prefix of <literal>PGDATA</> is recommended
    to avoid confusion and conflict with other variables.
   </para>

   <para>
    To create the variable in the environment of the server process
    you must first shut down the server, define the variable,
    initialize the data area, and finally restart the server. (See
    <xref linkend="postmaster-shutdown"> and <xref
    linkend="postmaster-start">.) To set an environment variable, type
    <informalexample>
<programlisting>
PGDATA2=/home/postgres/data
export PGDATA2
</programlisting>
    </informalexample>
    in Bourne shells, or
    <informalexample>
<programlisting>
setenv PGDATA2 /home/postgres/data
</programlisting>
    </informalexample>
    in <application>csh</> or <application>tcsh</>. You have to make sure that this environment
    variable is always defined in the server environment, otherwise
    you won't be able to access that database. Therefore you probably
    want to set it in some sort of shell start-up file or server
    start-up script.
   </para>

   <para>
    To create a data storage area in <envar>PGDATA2</>, ensure that
    <filename>/home/postgres</filename> already exists and is writable
    by the user account that runs the server (see <xref
    linkend="postgres-user">). Then from the command line, type
    <informalexample>
<programlisting>
initlocation PGDATA2
</programlisting>
    </informalexample>
    The you can restart the server.
   </para>

   <para>
    To create a database at the new location, use the command
<synopsis>
CREATE DATABASE <replaceable>name</> WITH LOCATION = '<replaceable>location</>'
</synopsis>
    where <replaceable>location</> is the environment variable you
    used, <envar>PGDATA2</> in this example. The <command>createdb</>
    command has the option <option>-D</> for this purpose.
   </para>

   <para>
    Database created at alternative locations using this method can be
    accessed and dropped like any other database.
   </para>

   <note>
    <para>
     It can also be possible to specify absolute paths directly to the
     <command>CREATE DATABASE</> command without defining environment
     variables. This is disallowed by default because it is a security
     risk. To allow it, you must compile <productname>Postgres</> with
     the C preprocessor macro <literal>ALLOW_ABSOLUTE_DBPATHS</>
     defined. One way to do this is to run the compilation step like
     this: <userinput>gmake CPPFLAGS=-DALLOW_ABSOLUTE_DBPATHS all</>.
    </para>
   </note>

  </sect2>
 </sect1>

 <sect1 id="manage-ag-accessdb">
  <title>Accessing a Database</title>

  <para>
   Once you have constructed a database, you can access it by:

   <itemizedlist spacing="compact" mark="bullet">
    <listitem>
     <para>
      running the <productname>Postgres</productname>  terminal  monitor  program 
      (<application>psql</application>) which allows you to interactively
      enter, edit, and execute <acronym>SQL</acronym> commands.
     </para>
    </listitem>

    <listitem>
     <para>
      writing a  C  program  using  the  <literal>libpq</literal>  subroutine
      library.   This  allows  you  to submit <acronym>SQL</acronym> commands
      from C and get answers and status messages  back  to
      your  program.   This interface is discussed further
      in the <citetitle>PostgreSQL Programmer's Guide</citetitle>.
     </para>
    </listitem>
   </itemizedlist>

   You might want to start up <application>psql</application>, 
   to try out  the  examples  in  this manual. It can be activated for the
   <replaceable class="parameter">dbname</replaceable> database by typing the command:

<programlisting>
psql <replaceable class="parameter">dbname</replaceable>
</programlisting>

   You will be greeted with the following message:

<programlisting>
Welcome to psql, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help on internal slash commands
       \g or terminate with semicolon to execute query
       \q to quit

<replaceable>dbname</replaceable>=&gt;
</programlisting>
   </para>

   <para>
    This prompt indicates that the terminal monitor is listening  
    to you and that you can type <acronym>SQL</acronym> queries into a
    workspace maintained by the terminal monitor.
    The <application>psql</application> program responds to escape
    codes  that  begin
    with  the  backslash  character, <literal>\</literal>.  For example, you
    can get help on the syntax of various 
    <productname>Postgres</productname> <acronym>SQL</acronym> commands by typing:

    <programlisting>
<replaceable>dbname</replaceable>=> \h
    </programlisting>

    Once  you  have finished entering your queries into the
    workspace, you can pass the contents of  the  workspace
    to the <productname>Postgres</productname> server by typing:

    <programlisting>
<replaceable>dbname</replaceable>=> \g
    </programlisting>

    This  tells  the  server  to process the query.  If you
    terminate your query with a semicolon, the  backslash-g is  not
    necessary.   <application>psql</application> will automatically 
    process semicolon terminated queries.
    To read queries from a file,  instead  of
    entering them interactively, type:

    <programlisting>
<replaceable>dbname</replaceable>=> \i <replaceable class="parameter">filename</replaceable>
    </programlisting>

    To get out of <application>psql</application> and return to Unix, type

    <programlisting>
<replaceable>dbname</replaceable>=&gt; \q
    </programlisting>

    and  <application>psql</application>  will  quit  and  return  
    you to your command shell. (For more escape codes, type
    backslash-h at  the  monitor prompt.)
    White  space  (i.e.,  spaces, tabs and newlines) may be
    used freely in <acronym>SQL</acronym> queries.  
    Single-line comments  are  denoted  by two dashes
    ("<literal>--</literal>").   Everything  after the dashes up to the end of the
    line is ignored. Multiple-line comments, and comments within a line,
    are denoted by <literal>/* ... */</literal>, a convention borrowed
    from <productname>Ingres</productname>.
   </para>
 </sect1>
     
 <sect1 id="manage-ag-dropdb">
  <title>Destroying a Database</title>

  <para>
   Databases are destroyed with the command <command>DROP DATABASE</command>:
<synopsis>
DROP DATABASE <replaceable>name</>
</synopsis>
   Only the owner of the database (i.e., the user that created it) can
   drop databases. Dropping a databases removes all objects that were
   contained within the database. The destruction of a database cannot
   be undone.
  </para>

  <para>
   You cannot execute the <command>DROP DATABASE</command> command
   while connected to the victim database. You can, however, be
   connected to any other database, including the template1 database,
   which would be the only option for dropping the last database of a
   given cluster.
  </para>

  <para>
   For convenience, there is also a shell program to drop databases:
<synopsis>
dropdb <replaceable class="parameter">dbname</replaceable>
</synopsis>
   (Unlike <command>createdb</>, it is not the default action to drop
   the database with the current user name.)
  </para>
 </sect1>
</chapter>

<!-- Keep this comment at the end of the file
Local variables:
mode:sgml
sgml-omittag:nil
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:"./reference.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:("/usr/lib/sgml/catalog")
sgml-local-ecat-files:nil
End:
-->
