2000-03-31 05:27:42 +02:00
|
|
|
<!--
|
2001-11-19 06:37:53 +01:00
|
|
|
$Header: /cvsroot/pgsql/doc/src/sgml/advanced.sgml,v 1.23 2001/11/19 05:37:53 tgl Exp $
|
2000-03-31 05:27:42 +02:00
|
|
|
-->
|
|
|
|
|
2001-09-03 01:27:50 +02:00
|
|
|
<chapter id="tutorial-advanced">
|
|
|
|
<title>Advanced Features</title>
|
|
|
|
|
|
|
|
<sect1 id="tutorial-advanced-intro">
|
|
|
|
<title>Introduction</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
In the previous chapter we have covered the basics of using
|
2001-11-19 06:37:53 +01:00
|
|
|
<acronym>SQL</acronym> to store and access your data in
|
2001-09-03 01:27:50 +02:00
|
|
|
<productname>PostgreSQL</productname>. We will now discuss some
|
2001-11-19 06:37:53 +01:00
|
|
|
more advanced features of <acronym>SQL</acronym> that simplify
|
2001-09-03 01:27:50 +02:00
|
|
|
management and prevent loss or corruption of your data. Finally,
|
|
|
|
we will look at some <productname>PostgreSQL</productname>
|
|
|
|
extensions.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
This chapter will on occasion refer to examples found in <xref
|
|
|
|
linkend="tutorial-sql"> to change or improve them, so it will be
|
|
|
|
of advantage if you have read that chapter. Some examples from
|
|
|
|
this chapter can also be found in
|
|
|
|
<filename>advanced.sql</filename> in the tutorial directory. This
|
|
|
|
file also contains some example data to load, which is not
|
|
|
|
repeated here. (Refer to <xref linkend="tutorial-sql-intro"> for
|
|
|
|
how to use the file.)
|
|
|
|
</para>
|
|
|
|
</sect1>
|
|
|
|
|
|
|
|
|
|
|
|
<sect1 id="tutorial-views">
|
|
|
|
<title>Views</title>
|
|
|
|
|
|
|
|
<indexterm zone="tutorial-views">
|
|
|
|
<primary>view</primary>
|
|
|
|
</indexterm>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Refer back to the queries in <xref linkend="tutorial-join">.
|
|
|
|
Suppose the combined listing of weather records and city location
|
|
|
|
is of particular interest to your application, but you don't want
|
|
|
|
to type the query each time you need it. You can create a
|
|
|
|
<firstterm>view</firstterm> over the query, which gives a name to
|
|
|
|
the query that you can refer to like an ordinary table.
|
|
|
|
|
|
|
|
<programlisting>
|
|
|
|
CREATE VIEW myview AS
|
|
|
|
SELECT city, temp_lo, temp_hi, prcp, date, location
|
|
|
|
FROM weather, cities
|
|
|
|
WHERE city = name;
|
|
|
|
|
|
|
|
SELECT * FROM myview;
|
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Making liberal use of views is a key aspect of good SQL database
|
|
|
|
design. Views allow you to encapsulate the details of the
|
|
|
|
structure of your tables, which may change as your application
|
|
|
|
evolves, behind consistent interfaces.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Views can be used in almost any place a real table can be used.
|
|
|
|
Building views upon other views is not uncommon.
|
|
|
|
</para>
|
|
|
|
</sect1>
|
|
|
|
|
|
|
|
|
|
|
|
<sect1 id="tutorial-fk">
|
|
|
|
<title>Foreign Keys</title>
|
|
|
|
|
|
|
|
<indexterm zone="tutorial-fk">
|
|
|
|
<primary>foreign key</primary>
|
|
|
|
</indexterm>
|
|
|
|
|
|
|
|
<indexterm zone="tutorial-fk">
|
|
|
|
<primary>referential integrity</primary>
|
|
|
|
</indexterm>
|
|
|
|
|
|
|
|
<para>
|
2001-11-19 06:37:53 +01:00
|
|
|
Recall the <classname>weather</classname> and
|
2001-09-03 01:27:50 +02:00
|
|
|
<classname>cities</classname> tables from <xref
|
|
|
|
linkend="tutorial-sql">. Consider the following problem: You
|
|
|
|
want to make sure that no one can insert rows in the
|
|
|
|
<classname>weather</classname> table that do not have a matching
|
|
|
|
entry in the <classname>cities</classname> table. This is called
|
|
|
|
maintaining the <firstterm>referential integrity</firstterm> of
|
|
|
|
your data. In simplistic database systems this would be
|
|
|
|
implemented (if at all) by first looking at the
|
|
|
|
<classname>cities</classname> table to check if a matching record
|
|
|
|
exists, and then inserting or rejecting the new
|
|
|
|
<classname>weather</classname> records. This approach has a
|
|
|
|
number of problems and is very inconvenient, so
|
|
|
|
<productname>PostgreSQL</productname> can do this for you.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The new declaration of the tables would look like this:
|
|
|
|
|
|
|
|
<programlisting>
|
|
|
|
CREATE TABLE cities (
|
|
|
|
name varchar(80) primary key,
|
|
|
|
location point
|
|
|
|
);
|
|
|
|
|
|
|
|
CREATE TABLE weather (
|
|
|
|
city varchar(80) references weather,
|
|
|
|
temp_lo int,
|
|
|
|
temp_hi int,
|
|
|
|
prcp real,
|
|
|
|
date date
|
|
|
|
);
|
|
|
|
|
|
|
|
</programlisting>
|
|
|
|
|
|
|
|
Now try inserting an invalid record:
|
|
|
|
|
|
|
|
<programlisting>
|
|
|
|
INSERT INTO weather VALUES ('Berkeley', 45, 53, 0.0, '1994-11-28');
|
|
|
|
</programlisting>
|
|
|
|
|
|
|
|
<screen>
|
|
|
|
ERROR: <unnamed> referential integrity violation - key referenced from weather not found in cities
|
|
|
|
</screen>
|
|
|
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The behavior of foreign keys can be finely tuned to your
|
|
|
|
application. We will not go beyond this simple example in this
|
|
|
|
tutorial and refer you to the <citetitle>Reference
|
|
|
|
Manual</citetitle> for more information. Making correct use of
|
|
|
|
foreign keys will definitely improve the quality of your database
|
|
|
|
applications, so you are strongly encouraged to learn about them.
|
|
|
|
</para>
|
|
|
|
</sect1>
|
|
|
|
|
|
|
|
|
|
|
|
<sect1 id="tutorial-transactions">
|
|
|
|
<title>Transactions</title>
|
|
|
|
|
|
|
|
<comment>This section needs to be written.</comment>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
|
|
|
</para>
|
|
|
|
</sect1>
|
|
|
|
|
|
|
|
|
|
|
|
<sect1 id="tutorial-inheritance">
|
1999-08-08 06:21:33 +02:00
|
|
|
<title>Inheritance</title>
|
|
|
|
|
2001-09-03 01:27:50 +02:00
|
|
|
<indexterm zone="tutorial-inheritance">
|
|
|
|
<primary>inheritance</primary>
|
|
|
|
</indexterm>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Inheritance is a concept from object-oriented databases. It opens
|
|
|
|
up interesting new possibilities of database design.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Let's create two tables: A table <classname>cities</classname>
|
|
|
|
and a table <classname>capitals</classname>. Naturally, capitals
|
|
|
|
are also cities, so you want some way to show the capitals
|
|
|
|
implicitly when you list all cities. If you're really clever you
|
|
|
|
might invent some scheme like this:
|
|
|
|
|
|
|
|
<programlisting>
|
|
|
|
CREATE TABLE capitals (
|
|
|
|
name text,
|
|
|
|
population real,
|
|
|
|
altitude int, -- (in ft)
|
|
|
|
state char(2)
|
|
|
|
);
|
|
|
|
|
|
|
|
CREATE TABLE non_capitals (
|
|
|
|
name text,
|
|
|
|
population real,
|
|
|
|
altitude int -- (in ft)
|
|
|
|
);
|
|
|
|
|
|
|
|
CREATE VIEW cities AS
|
|
|
|
SELECT name, population, altitude FROM capitals
|
|
|
|
UNION
|
|
|
|
SELECT name, population, altitude FROM non_capitals;
|
|
|
|
</programlisting>
|
|
|
|
|
|
|
|
This works OK as far as querying goes, but it gets ugly when you
|
|
|
|
need to update several rows, to name one thing.
|
|
|
|
</para>
|
|
|
|
|
1999-08-08 06:21:33 +02:00
|
|
|
<para>
|
2001-09-03 01:27:50 +02:00
|
|
|
A better solution is this:
|
1999-08-08 06:21:33 +02:00
|
|
|
|
2001-09-03 01:27:50 +02:00
|
|
|
<programlisting>
|
1998-03-01 09:16:16 +01:00
|
|
|
CREATE TABLE cities (
|
|
|
|
name text,
|
2001-01-14 00:58:55 +01:00
|
|
|
population real,
|
1999-08-08 06:21:33 +02:00
|
|
|
altitude int -- (in ft)
|
1998-03-01 09:16:16 +01:00
|
|
|
);
|
|
|
|
|
2001-01-05 07:34:23 +01:00
|
|
|
CREATE TABLE capitals (
|
1999-08-08 06:21:33 +02:00
|
|
|
state char(2)
|
2001-01-05 07:34:23 +01:00
|
|
|
) INHERITS (cities);
|
2001-09-03 01:27:50 +02:00
|
|
|
</programlisting>
|
|
|
|
|
|
|
|
In this case, a row of <classname>capitals</classname>
|
|
|
|
<firstterm>inherits</firstterm> all columns (<structfield>name</>,
|
|
|
|
<structfield>population</>, and <structfield>altitude</>) from its
|
|
|
|
<firstterm>parent</firstterm>, <classname>cities</classname>. The
|
|
|
|
type of the column <structfield>name</structfield> is
|
|
|
|
<type>text</type>, a native <productname>Postgres</productname>
|
|
|
|
type for variable length character strings. State capitals have
|
|
|
|
an extra column, state, that shows their state. In
|
|
|
|
<productname>PostgreSQL</productname>, a table can inherit from
|
|
|
|
zero or more other tables.
|
2000-06-14 15:12:52 +02:00
|
|
|
</para>
|
1999-08-08 06:21:33 +02:00
|
|
|
|
2000-06-14 15:12:52 +02:00
|
|
|
<para>
|
|
|
|
For example, the following query finds the names of all cities,
|
|
|
|
including state capitals, that are located at an altitude
|
2001-09-03 01:27:50 +02:00
|
|
|
over 500 ft.:
|
2000-06-09 03:44:34 +02:00
|
|
|
|
2001-09-03 01:27:50 +02:00
|
|
|
<programlisting>
|
2001-01-05 07:34:23 +01:00
|
|
|
SELECT name, altitude
|
|
|
|
FROM cities
|
|
|
|
WHERE altitude > 500;
|
2001-09-03 01:27:50 +02:00
|
|
|
</programlisting>
|
2000-06-09 03:44:34 +02:00
|
|
|
|
2000-06-14 15:12:52 +02:00
|
|
|
which returns:
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2001-09-03 01:27:50 +02:00
|
|
|
<screen>
|
|
|
|
name | altitude
|
|
|
|
-----------+----------
|
|
|
|
Las Vegas | 2174
|
|
|
|
Mariposa | 1953
|
|
|
|
Madison | 845
|
|
|
|
(3 rows)
|
|
|
|
</screen>
|
2000-06-14 15:12:52 +02:00
|
|
|
</para>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2000-06-14 15:12:52 +02:00
|
|
|
<para>
|
|
|
|
On the other hand, the following query finds
|
2001-01-05 07:34:23 +01:00
|
|
|
all the cities that are not state capitals and
|
2001-09-03 01:27:50 +02:00
|
|
|
are situated at an altitude of 500 ft. or higher:
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2001-09-03 01:27:50 +02:00
|
|
|
<programlisting>
|
2000-06-14 15:12:52 +02:00
|
|
|
SELECT name, altitude
|
2000-06-09 03:44:34 +02:00
|
|
|
FROM ONLY cities
|
|
|
|
WHERE altitude > 500;
|
2001-09-03 01:27:50 +02:00
|
|
|
</programlisting>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2001-09-03 01:27:50 +02:00
|
|
|
<screen>
|
|
|
|
name | altitude
|
|
|
|
-----------+----------
|
|
|
|
Las Vegas | 2174
|
|
|
|
Mariposa | 1953
|
|
|
|
(2 rows)
|
|
|
|
</screen>
|
2000-06-14 15:12:52 +02:00
|
|
|
</para>
|
2000-06-09 03:44:34 +02:00
|
|
|
|
2000-06-14 15:12:52 +02:00
|
|
|
<para>
|
2001-09-03 01:27:50 +02:00
|
|
|
Here the <literal>ONLY</literal> before <literal>cities</literal>
|
|
|
|
indicates that the query should be run over only the
|
|
|
|
<classname>cities</classname> table, and not tables below
|
|
|
|
<classname>cities</classname> in the inheritance hierarchy. Many
|
|
|
|
of the commands that we have already discussed --
|
|
|
|
<command>SELECT</command>, <command>UPDATE</command> and
|
|
|
|
<command>DELETE</command> -- support this <literal>ONLY</literal>
|
|
|
|
notation.
|
2000-06-14 15:12:52 +02:00
|
|
|
</para>
|
1999-08-08 06:21:33 +02:00
|
|
|
</sect1>
|
|
|
|
|
|
|
|
|
2001-09-03 01:27:50 +02:00
|
|
|
<sect1 id="tutorial-conclusion">
|
|
|
|
<title>Conclusion</title>
|
|
|
|
|
1999-08-08 06:21:33 +02:00
|
|
|
<para>
|
2001-09-03 01:27:50 +02:00
|
|
|
<productname>PostgreSQL</productname> has many features not
|
|
|
|
touched upon in this tutorial introduction, which has been
|
|
|
|
oriented toward newer users of <acronym>SQL</acronym>. These
|
|
|
|
features are discussed in more detail in both the
|
|
|
|
<citetitle>User's Guide</citetitle> and the
|
|
|
|
<citetitle>Programmer's Guide</citetitle>.
|
1999-08-08 06:21:33 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2001-09-03 01:27:50 +02:00
|
|
|
If you feel you need more introductory material, please visit the
|
|
|
|
<ulink url="http://www.postgresql.org">PostgreSQL web
|
|
|
|
site</ulink> for links to more resources.
|
1999-08-08 06:21:33 +02:00
|
|
|
</para>
|
|
|
|
</sect1>
|
2000-04-07 15:30:58 +02:00
|
|
|
|
1999-08-08 06:21:33 +02:00
|
|
|
</chapter>
|
|
|
|
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
|
|
Local variables:
|
2000-03-31 05:27:42 +02:00
|
|
|
mode:sgml
|
1999-08-08 06:21:33 +02:00
|
|
|
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
|
2000-03-31 05:27:42 +02:00
|
|
|
sgml-local-catalogs:("/usr/lib/sgml/catalog")
|
1999-08-08 06:21:33 +02:00
|
|
|
sgml-local-ecat-files:nil
|
|
|
|
End:
|
|
|
|
-->
|