/[gentoo]/xml/htdocs/doc/en/postgres-howto.xml
Gentoo

Contents of /xml/htdocs/doc/en/postgres-howto.xml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (hide annotations) (download) (as text)
Tue Apr 10 07:16:49 2007 UTC (10 years, 8 months ago) by nightmorph
Branch: MAIN
Changes since 1.2: +7 -31 lines
File MIME type: application/xml
updated postgresql guide, bug 173987

1 neysx 1.1 <?xml version="1.0" encoding="UTF-8"?>
2     <!DOCTYPE guide SYSTEM "/dtd/guide.dtd">
3 nightmorph 1.3 <!-- $Header: /var/cvsroot/gentoo/xml/htdocs/doc/en/postgres-howto.xml,v 1.2 2006/03/16 21:25:36 neysx Exp $ -->
4 neysx 1.1
5     <guide link="/doc/en/postgres-howto.xml" lang="en">
6     <title>PostgreSQL Guide</title>
7    
8     <author title="Author">
9     <mail link="chriswhite@gentoo.org">Chris White</mail>
10     </author>
11     <author title="Editor">
12     <mail link="neysx@gentoo.org">Xavier Neys</mail>
13     </author>
14    
15     <abstract>
16     This guide is meant to show the basic setup of PostgreSQL. The setup described
17     here should be sufficient enough to use for basic web appplications, and any
18     other program that provides PostgreSQL support.
19     </abstract>
20    
21     <!-- The content of this document is licensed under the CC-BY-SA license -->
22     <!-- See http://creativecommons.org/licenses/by-sa/2.5 -->
23     <license/>
24    
25 nightmorph 1.3 <version>1.1</version>
26     <date>2006-04-10</date>
27 neysx 1.1
28     <chapter>
29     <title>Introduction</title>
30     <section>
31     <title>PostgreSQL introduction</title>
32     <body>
33    
34     <p>
35     When talking to most developers about the different database solutions to use,
36     two major databases will usually form the answer. One would be <c>MySQL</c>,
37     and the other is what this document will refer to, <c>PostgreSQL</c>. The
38     advantages of one over the other is a somewhat long winded debate, however it
39     is just to say that PostgreSQL has had a more firm grasp on true relational
40     database structure than MySQL. Most of the standard features such as
41     <b>FOREIGN KEY</b> was only just added in MySQL 5. However, whatever the case
42     may be, this document assumes that you have selected PostgreSQL as the
43     database to use. The first place to start is the <c>emerge</c> process. In the
44     next section, the installation process through emerge will be described, as
45     well as the basic configuration.
46     </p>
47    
48     </body>
49     </section>
50     <section>
51     <title>PostgreSQL installation</title>
52     <body>
53    
54     <p>
55     To begin, we must first <c>emerge</c> the PostgreSQL package. To do so, run the
56     following code to first ensure that the options for it are properly set:
57     </p>
58    
59     <pre caption="Checking the PostgreSQL build options">
60     # <i>emerge -pv postgresql</i>
61    
62     These are the packages that I would merge, in order:
63    
64     Calculating dependencies ...done!
65 nightmorph 1.3 [ebuild N ] dev-db/postgresql-8.0.4 -doc -kerberos +nls +pam +perl -pg-intdatetime +python +readline (-selinux) +ssl -tcl +xml +zlib 0 kB
66 neysx 1.1 </pre>
67    
68     <p>
69     Here's a list of what the different build options indicate:
70     </p>
71    
72     <table>
73     <tr>
74     <th>USE Flag</th>
75     <th>Meaning</th>
76     </tr>
77     <tr>
78     <ti>doc</ti>
79     <ti>
80     This USE flag enables or disables the installation of documentation
81     outside of the standard man pages. The one good time to disable this
82     option is if you are low on space, or you have alternate methods of
83     getting a hold of the documentation (online, etc.)
84     </ti>
85     </tr>
86     <tr>
87     <ti>kerberos</ti>
88     <ti>
89     When connecting to the database, with this option enabled, the admin
90     has the option of using <c>kerberos</c> to authenticate their
91     users/services to the database.
92     </ti>
93     </tr>
94     <tr>
95     <ti>nls</ti>
96     <ti>
97 neysx 1.2 If this option is enabled, PostgreSQL can utilize translated strings for
98     non-English speaking users.
99 neysx 1.1 </ti>
100     </tr>
101     <tr>
102     <ti>pam</ti>
103     <ti>
104     If this option is enabled, and the admin configures the PostgreSQL
105     configuration file properly, users/services will be able to login to a
106     PostgreSQL database using <c>PAM</c> (Pluggable Authentication Module).
107     </ti>
108     </tr>
109     <tr>
110     <ti>perl</ti>
111     <ti>
112     If this option is enabled, <c>perl</c> bindings for PostgreSQL will be
113     built.
114     </ti>
115     </tr>
116     <tr>
117     <ti>pg-intdatetime</ti>
118     <ti>
119     If this option is enabled, PostgreSQL will support 64 bit integer date
120     types.
121     </ti>
122     </tr>
123     <tr>
124     <ti>python</ti>
125     <ti>
126     If this option is enabled, PostgreSQL will be built with
127     <c>python</c> bindings.
128     </ti>
129     </tr>
130     <tr>
131     <ti>readline</ti>
132     <ti>
133     If this option is enabled, PostgreSQL will support <c>readline</c> style
134     command line editing. This includes command history and isearch.
135     </ti>
136     </tr>
137     <tr>
138     <ti>selinux</ti>
139     <ti>
140     If this option is enabled, an <c>selinux</c> policy for PostgreSQL will be
141     installed.
142     </ti>
143     </tr>
144     <tr>
145     <ti>ssl</ti>
146     <ti>
147     If this option is enabled, PostgreSQL will utilize the <c>OpenSSL</c>
148     library to encrypt traffic between PostgreSQL clients and servers.
149     </ti>
150     </tr>
151     <tr>
152 nightmorph 1.3 <ti>tcl</ti>
153 neysx 1.1 <ti>
154 nightmorph 1.3 If this option is enabled, PostgreSQL will build <c>tcl</c> bindings.
155 neysx 1.1 </ti>
156     </tr>
157     <tr>
158 nightmorph 1.3 <ti>xml</ti>
159 neysx 1.1 <ti>
160     If this option is enabled, <c>XPATH</c> style xml support will be built.
161     More information on using xml support with PostgreSQL can be found on:
162     <uri link="http://www.throwingbeans.org/tech/postgresql_and_xml.html">
163     PostgreSQL and XML</uri>.
164     </ti>
165     </tr>
166     <tr>
167     <ti>zlib</ti>
168     <ti>
169     This isn't really used by PostgreSQL itself, but by <c>pg_dump</c> to
170     compress the dumps it produces.
171     </ti>
172     </tr>
173     </table>
174    
175     <p>
176     Once you've customized PostgreSQL to meet your specific needs, go ahead and
177     start the <c>emerge</c>:
178     </p>
179    
180     <pre caption="Emerge-ing PostgreSQL">
181     # <i>emerge postgresql</i>
182     <comment>(Output shortened)</comment>
183     >>> /usr/lib/libecpg.so.5 -> libecpg.so.5.0
184     >>> /usr/bin/postmaster -> postgres
185     * Make sure the postgres user in /etc/passwd has an account setup with /bin/bash as the shell
186     *
187     * Execute the following command
188     * emerge --config =postgresql-8.0.4
189     * to setup the initial database environment.
190     *
191     >>> Regenerating /etc/ld.so.cache...
192     >>> dev-db/postgresql-8.0.4 merged.
193     </pre>
194    
195     <p>
196     As shown by the einfo output, there is some post setup that must be done. The
197     next chapter will look at the actual configuration of PostgreSQL.
198     </p>
199    
200     </body>
201     </section>
202     </chapter>
203     <chapter>
204     <title>PostgreSQL configuration</title>
205     <section>
206     <title>Setting up the initial database environment</title>
207     <body>
208    
209     <p>
210     As noted in the earlier <c>emerge</c> output, the initial database environment
211     must be setup. However, before this is done, one thing needs to be considered.
212     Unlike, say MySQL, PostgreSQL's "root" password is the password of the actual
213     user. However, only the user is created by the ebuild <e>not</e> the password.
214     So before we can begin, the password must be set for the postgres user:
215     </p>
216    
217     <pre caption="Setting the password">
218     # <i>passwd postgres</i>
219     New UNIX password:
220     Retype new UNIX password:
221     passwd: password updated successfully
222     </pre>
223    
224     <p>
225     Now that this is setup, the creation of the initial database environment can occur:
226     </p>
227    
228     <pre caption="Configuring the database environment with emerge --config">
229     # <i>emerge --config =postgresql-8.0.4</i>
230    
231    
232     Configuring pkg...
233    
234     * Creating the data directory ...
235     * Initializing the database ...
236     The files belonging to this database system will be owned by user "postgres".
237     This user must also own the server process.
238    
239     The database cluster will be initialized with locale C.
240    
241     fixing permissions on existing directory /var/lib/postgresql/data ... ok
242     creating directory /var/lib/postgresql/data/global ... ok
243     creating directory /var/lib/postgresql/data/pg_xlog ... ok
244     creating directory /var/lib/postgresql/data/pg_xlog/archive_status ... ok
245     creating directory /var/lib/postgresql/data/pg_clog ... ok
246     creating directory /var/lib/postgresql/data/pg_subtrans ... ok
247     creating directory /var/lib/postgresql/data/base ... ok
248     creating directory /var/lib/postgresql/data/base/1 ... ok
249     creating directory /var/lib/postgresql/data/pg_tblspc ... ok
250     selecting default max_connections ... 100
251     selecting default shared_buffers ... 1000
252     creating configuration files ... ok
253     creating template1 database in /var/lib/postgresql/data/base/1 ... ok
254     initializing pg_shadow ... ok
255     enabling unlimited row size for system tables ... ok
256     initializing pg_depend ... ok
257     creating system views ... ok
258     loading pg_description ... ok
259     creating conversions ... ok
260     setting privileges on built-in objects ... ok
261     creating information schema ... ok
262     vacuuming database template1 ... ok
263     copying template1 to template0 ... ok
264    
265     WARNING: enabling "trust" authentication for local connections
266     You can change this by editing pg_hba.conf or using the -A option the
267     next time you run initdb.
268    
269     Success. You can now start the database server using:
270    
271     /usr/bin/postmaster -D /var/lib/postgresql/data
272     or
273     /usr/bin/pg_ctl -D /var/lib/postgresql/data -l logfile start
274    
275     *
276     * You can use /etc/init.d/postgresql script to run PostgreSQL instead of pg_ctl.
277     *
278     </pre>
279    
280     <p>
281     Now the initial database environment is setup. The next section will look at
282     verifying the install and setting up users to access the database.
283     </p>
284    
285     </body>
286     </section>
287     <section>
288     <title>PostgreSQL database setup</title>
289     <body>
290    
291     <p>
292     Now that PostgreSQL is setup, it's a good idea at this point to verify the
293     installation. First, make sure the service starts up ok:
294     </p>
295    
296     <pre caption="Starting up the PostgreSQL service">
297     # <i>/etc/init.d/postgresql start</i>
298     * Starting PostgreSQL ... [ ok ]
299     </pre>
300    
301     <p>
302     Once this is verified working, it's also a good idea to add it to the default
303     runlevel so it starts at boot:
304     </p>
305    
306     <pre caption="Adding to the default runlevel">
307     # <i>rc-update add postgresql default</i>
308     * postgresql added to runlevel default
309     </pre>
310    
311     <p>
312     Now that the service has started, it's time to try setting up a test database.
313     To start out, let's create a test database by using the <c>createdb</c>
314     command. We'll also pass along the <c>-U</c> option to set the user (it
315     defaults to the current user name if you don't), and the <c>-W</c> option to
316     request the password we created earlier. Finally we give it the name of the
317     database we want to create:
318     </p>
319    
320     <pre caption="Creating a database with createdb">
321     $ <i>createdb -U postgres -W test</i>
322     Password:
323     CREATE DATABASE
324     </pre>
325    
326     <p>
327     The database was successfully created, and we can confirm that the database can
328     run basic tasks. We'll go ahead and drop this database (remove it) with the
329     <c>dropdb</c> command, creating a new one for usage later on:
330     </p>
331    
332     <pre caption="Droping a database with dropdb">
333     $ <i>dropdb -U postgres -W test</i>
334     Password:
335     DROP DATABASE
336     </pre>
337    
338     <p>
339     Right now, only the postgres user can run commands. Obviously this is not the
340     sort of setup one would like in a multi-user environment. The next section will
341     look at working with user accounts.
342     </p>
343    
344     </body>
345     </section>
346     <section>
347     <title>Setting up database user accounts</title>
348     <body>
349    
350     <p>
351     As mentioned earlier, having to login as the postgres user is somewhat
352     undesirable in a mult-user environment. In most cases there will be various
353     users and services accessing the server, and each have different permission
354     requirements. So, to handle this, the <c>createuser</c> command can be used.
355     This command is an alternative to running a few SQL queries, and is a lot more
356     flexible from an admin standpoint. We'll go ahead and create two users, a
357     'superuser' that can add other users and administer the db, and a standard user:
358     </p>
359    
360     <pre caption="Setting up the superuser">
361     <comment>(replace chris with the username you'd like to use)</comment>
362     $ <i>createuser -a -d -P -E -U postgres -W chris</i>
363     Enter password for new user:
364     Enter it again:
365     Password:
366     CREATE USER
367     </pre>
368    
369     <p>
370     There, we've created the superuser. The command line option <c>-a</c> specifies
371     that this user can add other users. <c>-d</c> means that this user can create
372     databases. <c>-P</c> let's you enter a password for the user and <c>-E</c> will
373     encrypt it for security purposes. Now then, we'll test this new user's
374     permissions out by setting up our standard user:
375     </p>
376    
377     <pre caption="Setting up the standard user">
378     <comment>(replace chris with the username you've just created)</comment>
379     $ <i>createuser -A -D -P -E -U chris -W testuser</i>
380     Enter password for new user:
381     Enter it again:
382     Password:
383     CREATE USER
384     </pre>
385    
386     <p>
387     Success! Our new user was created using the previously created superuser. The
388     <c>-A</c> and <c>-D</c> options do the opposite of <c>-a</c> and <c>-d</c>, and
389     instead deny the user the ability to create other users and databases. Now that
390     there are users to work with, and a new database created, the next chapter will
391     look at using the new database.
392     </p>
393    
394     </body>
395     </section>
396     </chapter>
397     <chapter>
398     <title>Using PostgreSQL</title>
399     <section>
400     <title>Setting up permissions</title>
401     <body>
402    
403     <p>
404     With the new database created, there is a user that can create databases and
405     add other users, and the main postgres user that can do anything. The user
406     created earlier can currently login to the server, and that's about it. In
407     general, users need to be able to insert data and retrieve data, and sometimes
408     any other number of tasks. So, for this new user to be able to do anything,
409     they must be setup with the proper permissions. This can easily be done by
410     passing the <c>-O</c> parameter to <c>createdb</c>. We'll start by making a
411     new database, <b>MyDB</b> with our superuser that will be owned by the previous
412     testuser:
413     </p>
414    
415     <pre caption="Creating the MyDB database">
416     $ <i>createdb -O testuser -U chris -W MyDB</i>
417     Password:
418     CREATE DATABASE
419     </pre>
420    
421     <p>
422     Alright, now we have a new MyDB database, and a testuser that can access it.
423     To test this out, we'll login as the testuser to the new MyDB database. We'll
424     do this with the <c>psql</c> program. This program is what's used to connect to
425     the PostgreSQL database from command line. So connect to the new database like
426     so:
427     </p>
428    
429     <pre caption="Logging into the MyDB database as the testuser">
430     $ <i>psql -U testuser -W MyDB</i>
431     Password:
432     Welcome to psql 8.0.4, the PostgreSQL interactive terminal.
433    
434     Type: \copyright for distribution terms
435     \h for help with SQL commands
436     \? for help with psql commands
437     \g or terminate with semicolon to execute query
438     \q to quit
439    
440     MyDB=&gt;
441     </pre>
442    
443     <p>
444     So, the testuser is now logged into the database, and can begin to initiate
445     some commands. To get a feel for using PostgreSQL, the next section will take a
446     look at some of the basic commands in navigating the <c>psql</c> client.
447     </p>
448    
449     </body>
450     </section>
451     <section>
452     <title>Basic PostgreSQL commands and creating a table</title>
453     <body>
454    
455     <p>
456     For those who are used to MySQL, this is somewhat of a definite read. This is
457     where PostgreSQL may get somewhat unique with regards to running commands. To
458     start, here is a list of some commands that will be discussed:
459     </p>
460    
461     <table>
462     <tr>
463     <th>Command</th>
464     <th>Usage</th>
465     <th>MySQL Equivalent</th>
466     </tr>
467     <tr>
468     <ti>\c[onnect] [DBNAME|- [USER]]</ti>
469     <ti>Connects to another database</ti>
470     <ti>USE DATABASE</ti>
471     </tr>
472     <tr>
473     <ti>\q</ti>
474     <ti>Quit the <c>psql</c> client</ti>
475     <ti>quit</ti>
476     </tr>
477     <tr>
478     <ti>\i FILE</ti>
479     <ti>Run commands from <c>FILE</c></ti>
480     <ti>source FILE</ti>
481     </tr>
482     <tr>
483     <ti>\o [FILE]</ti>
484     <ti>Send query results to <c>FILE</c></ti>
485     <ti>INTO OUTFILE, but outputs everything (not just SELECTS)</ti>
486     </tr>
487     <tr>
488     <ti>\d [NAME]</ti>
489     <ti>Describe a database or table (as well as other items)</ti>
490     <ti>DESC(RIBE)</ti>
491     </tr>
492     <tr>
493     <ti>\db [PATTERN]</ti>
494     <ti>
495     List available tables that match <c>PATTERN</c> (all if no pattern
496     is given)
497     </ti>
498     <ti>SHOW TABLES</ti>
499     </tr>
500     </table>
501    
502     <p>
503     With the exception of <c>\c[onnect]</c>, all the commands shown will be used
504     later on in the section. So right now the database is empty. That said, we need
505     to insert some data. The first step to inserting data, however, is to put it in
506     a table. Right now there are no tables in the database, so we need to create
507     one. This is done with the <c>CREATE TABLE</c> command. We'll make a table of
508     items. They will contain a Product ID, Description, and price:
509     </p>
510    
511     <pre caption="Creating the products table">
512     MyDB=> CREATE TABLE products (
513     MyDB(&gt; product_id SERIAL,
514     MyDB(&gt; description TEXT,
515     MyDB(&gt; price DECIMAL
516     MyDB(&gt; );
517     NOTICE: CREATE TABLE will create implicit sequence "products_product_id_seq"
518     for serial column "products.product_id"
519     CREATE TABLE
520     </pre>
521    
522     <p>
523     You can ignore the NOTICE, it's perfectly harmless. Looking at the last line of
524     the function, <c>CREATE TABLE</c> seems to indicate that the command has
525     succeeded. However, let's go ahead and verify that the table was indeed
526     successfully created with the <c>\d</c> command:
527     </p>
528    
529     <pre caption="Looking at the newly created table">
530     MyDB=&gt; <i>\d products</i>
531     Table "public.products"
532     Column | Type | Modifiers
533     -------------+---------+------------------------------------------------------------------
534     product_id | integer | not null default nextval('public.products_product_id_seq'::text)
535     description | text |
536     price | numeric |
537     </pre>
538    
539     <p>
540     Indeed the table was successfully created. Now that the table is created, it
541     needs to be populated with data. The next section will look at populating the
542     database with data.
543     </p>
544    
545     </body>
546     </section>
547     <section>
548     <title>Inserting data into the database</title>
549     <body>
550    
551     <p>
552     This section will look at the two ways of populating the newly created table
553     with data. First let's look at the most basic command, <c>INSERT</c>:
554     </p>
555    
556     <pre caption="INSERT syntax">
557     INSERT INTO [tablename] (column1,column2,column3) VALUES(value1,value2,value3)
558     </pre>
559    
560     <p>
561     <c>tablename</c> contains the name of the table to insert the data into.
562     (column1,column2,column3) lets you specify the specific columns to insert the
563     values into. VALUES(value1,value2,value3) is the listing of values. The values
564     are inserted into the same order as the columns (column1 gets value1, column2
565     gets value2, column3 gets value3). These counts <e>must</e> be the same. So
566     let's go ahead and insert an item into the table:
567     </p>
568    
569     <impo>
570     From working with databases for a long time, I personally recommend specifying
571     <c>INSERT</c> statements exactly as above. Developers often make the mistake of
572     using <c>INSERT INTO</c> without specifying columns. This is unproductive, as
573     if a new column gets added to the database, it will cause in error if the value
574     to column count is not the same. You should <e>always</e> specify the columns
575     unless you're 300% sure you'll never add a column.
576     </impo>
577    
578     <pre caption="Inserting data into the table">
579     MyDB=&gt; <i>INSERT INTO products (description,price) VALUES('A test product', 12.00);</i>
580     INSERT 17273 1
581     </pre>
582    
583     <p>
584     The last line needs a bit of explaining. The return of an insert command is an
585     OID (Object Identifier) and the number of rows inserted. OID's are a bit beyond
586     the scope of this guide, and the <uri
587     link="http://www.postgresql.org/docs/8.1/static/datatype-oid.html">PostgreSQL
588     manual</uri> has some good information on it. Now, for a situation where you
589     have 20,000 products, these insert statements can be a little tedious. However,
590     not all is lost. The <c>COPY</c> command can be used to insert data into a
591     table from a file or stdin. In this example, let's assume that you have a csv
592     (comma separated values) file, which contains the product id, description, and
593     price. The file looks like this:
594     </p>
595    
596     <pre caption="products.csv">
597     2,meat,6.79
598     3,soup,0.69
599     4,soda,1.79
600     </pre>
601    
602     <p>
603     Now we'll use the <c>COPY</c> command to populate our data:
604     </p>
605    
606     <impo>
607     The <c>COPY FROM STDIN</c> command is used because only the postgres user can
608     insert data from a file (for obvious security reasons).
609     </impo>
610    
611     <pre caption="Using COPY to populate the products table">
612     MyDB=&gt; <i>COPY products FROM STDIN WITH DELIMITER AS ',';</i>
613     Enter data to be copied followed by a newline.
614     End with a backslash and a period on a line by itself.
615     >> <i>2,meat,6.79</i>
616     >> <i>3,soup,0.69</i>
617     >> <i>4,soda,1.79</i>
618     >> <i>\.</i>
619     </pre>
620    
621     <p>
622     Unfortunately, this line doesn't return the same status information as the
623     <c>INSERT INTO</c> statement. How do we know the data was inserted? The next
624     section will look at running queries to check our data.
625     </p>
626    
627     </body>
628     </section>
629     <section>
630     <title>Using PostgreSQL queries</title>
631     <body>
632    
633     <p>
634     This section will look at using the <c>SELECT</c> statement to view data in our
635     tables. The basic <c>SELECT</c> format looks like this:
636     </p>
637    
638     <pre caption="SELECT syntax">
639     SELECT (column1,column2|*) FROM (table) [WHERE (conditionals)]
640     </pre>
641    
642     <p>
643     There are two ways to select columns. The first is using <c>*</c> to select all
644     columns, and the second is to specify a list of specific columns you wish to
645     see. The second is quite handy when you want to find a specific column in a
646     rather large list of them. Let's start out with using <c>SELECT</c> with
647     <c>*</c> to specify all columns:
648     </p>
649    
650     <pre caption="Viewing the products table">
651     MyDB=&gt; <i>SELECT * FROM products;</i>
652     product_id | description | price
653     ------------+----------------+-------
654     1 | A test product | 12.00
655     2 | meat | 6.79
656     3 | soup | 0.69
657     4 | soda | 1.79
658     (4 rows)
659     </pre>
660    
661     <p>
662     As shown here, all the data we inserted earlier is indeed in the table. Now
663     let's say we only want to see the description and the price, and don't care
664     about the product id. In this case we'll use the column specific SELECT form:
665     </p>
666    
667     <pre caption="Viewing specific columns from the products table">
668     MyDB=&gt; <i>SELECT description,price FROM products;</i>
669     description | price
670     ----------------+-------
671     A test product | 12.00
672     meat | 6.79
673     soup | 0.69
674     soda | 1.79
675     (4 rows)
676     </pre>
677    
678     <p>
679     Now only the product and price is shown, letting us focus on only the important
680     data. Now let's say that we want to see only the items that are greater than
681     $2.00. Here's where the <c>WHERE</c> clause comes in handy:
682     </p>
683    
684     <pre caption="Viewing specific rows from the products table">
685     MyDB=&gt; <i>SELECT description,price FROM products WHERE price > 2.00;</i>
686     description | price
687     ----------------+-------
688     A test product | 12.00
689     meat | 6.79
690     (2 rows)
691     </pre>
692    
693     <p>
694     Now a listing of products over $2.00 is displayed, focusing the data even more.
695     These forms of querying for information are very powerful, and can help create
696     extremely useful reports.
697     </p>
698    
699     </body>
700     </section>
701     <section>
702     <title>Conclusion</title>
703     <body>
704    
705     <p>
706     This concludes the PostgreSQL Guide. A big thanks goes to Masatomo Nakano, the
707     Gentoo PostgreSQL maintainer for his help in answering my questions. Any
708     suggestions on this guide should be sent to <mail>chriswhite@gentoo.org</mail>.
709     For more extensive documentation, see the <uri
710     link="http://www.postgresql.org">PostgreSQL website</uri>.
711     </p>
712    
713     </body>
714     </section>
715     </chapter>
716     </guide>

  ViewVC Help
Powered by ViewVC 1.1.20