mirror of https://github.com/postgres/postgres
lisp.sgml is a placeholder for Eric Marsden's upcoming contribution. catalogs.sgml is not yet marked up or integrated. It should perhaps become an appendix.REL7_0_PATCHES
parent
a27512e634
commit
f2f43efbe1
@ -0,0 +1,450 @@ |
||||
.\" This is -*-nroff-*- |
||||
.\" XXX standard disclaimer belongs here.... |
||||
.\" $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.1 1999/07/22 15:11:03 thomas Exp $ |
||||
.TH "SYSTEM CATALOGS" INTRO 03/13/94 PostgreSQL PostgreSQL |
||||
.SH "Section 7 - System Catalogs" |
||||
.de LS |
||||
.PP |
||||
.if n .ta 5 +13 +13 |
||||
.if t .ta 0.5i +1.3i +1.3i |
||||
.in 0 |
||||
.nf |
||||
.. |
||||
.de LE |
||||
.fi |
||||
.in |
||||
.. |
||||
.SH "DESCRIPTION" |
||||
In this |
||||
section we list each of the attributes of the system catalogs and |
||||
define their meanings. |
||||
.SH "CLASS/TYPE SYSTEM CATALOGS" |
||||
These catalogs form the core of the extensibility system: |
||||
.LS |
||||
\fBname\fP \fBshared/local\fP \fBdescription\fP |
||||
pg_aggregate local aggregate functions |
||||
pg_am local access methods |
||||
pg_amop local operators usable with specific access methods |
||||
pg_amproc local procedures used with specific access methods |
||||
pg_attribute local class attributes |
||||
pg_class local classes |
||||
pg_index local secondary indices |
||||
pg_inherits local class inheritance hierarchy |
||||
pg_language local procedure implementation languages |
||||
pg_opclass local operator classes |
||||
pg_operator local query language operators |
||||
pg_proc local procedures (functions) |
||||
pg_type local data types |
||||
.LE |
||||
.SH "ENTITIES" |
||||
These catalogs deal with identification of entities known throughout |
||||
the site: |
||||
.LS |
||||
\fBname\fP \fBshared/local\fP \fBdescription\fP |
||||
pg_database shared current databases |
||||
pg_group shared user groups |
||||
pg_shadow shared valid users |
||||
.LE |
||||
.SH "RULE SYSTEM CATALOGS" |
||||
.LS |
||||
\fBname\fP \fBshared/local\fP \fBdescription\fP |
||||
pg_listener local processes waiting on alerters |
||||
pg_prs2plans local instance system procedures |
||||
pg_prs2rule local instance system rules |
||||
pg_prs2stub local instance system ``stubs'' |
||||
pg_rewrite local rewrite system information |
||||
.LE |
||||
.SH "LARGE OBJECT CATALOGS" |
||||
.PP |
||||
These catalogs are specific to the Inversion file system and large |
||||
objects in general: |
||||
.LS |
||||
\fBname\fP \fBshared/local\fP \fBdescription\fP |
||||
pg_lobj local description of a large object |
||||
pg_naming local Inversion name space mapping |
||||
pg_platter local jukebox platter inventory |
||||
pg_plmap local jukebox platter extent map |
||||
.LE |
||||
.SH "INTERNAL CATALOGS" |
||||
.PP |
||||
These catalogs are internal classes that are not stored as normal |
||||
heaps and cannot be accessed through normal means (attempting to do so |
||||
causes an error). |
||||
.LS |
||||
\fBname\fP \fBshared/local\fP \fBdescription\fP |
||||
pg_log shared transaction commit/rollback log |
||||
pg_magic shared magic constant |
||||
pg_time shared commit/rollback times |
||||
pg_variable shared special variable values |
||||
.LE |
||||
.PP |
||||
There are several other classes defined with \*(lqpg_\*(rq names. |
||||
Aside from those that end in \*(lqind\*(rq (secondary indices), these |
||||
are all obsolete or otherwise deprecated. |
||||
.SH "CLASS/TYPE SYSTEM CATALOGS" |
||||
.PP |
||||
The following catalogs relate to the class/type system. |
||||
.nf M |
||||
/* |
||||
* aggregates |
||||
* |
||||
* see DEFINE AGGREGATE for an explanation of transition functions |
||||
*/ |
||||
pg_aggregate |
||||
NameData aggname /* aggregate name (e.g., "count") */ |
||||
oid aggowner /* usesysid of creator */ |
||||
regproc aggtransfn1 /* first transition function */ |
||||
regproc aggtransfn2 /* second transition function */ |
||||
regproc aggfinalfn /* final function */ |
||||
oid aggbasetype /* type of data on which aggregate |
||||
operates */ |
||||
oid aggtranstype1 /* type returned by aggtransfn1 */ |
||||
oid aggtranstype2 /* type returned by aggtransfn2 */ |
||||
oid aggfinaltype /* type returned by aggfinalfn */ |
||||
text agginitval1 /* external format of initial |
||||
(starting) value of aggtransfn1 */ |
||||
text agginitval2 /* external format of initial |
||||
(starting) value of aggtransfn2 */ |
||||
.fi |
||||
.nf M |
||||
pg_am |
||||
NameData amname /* access method name */ |
||||
oid amowner /* usesysid of creator */ |
||||
char amkind /* - deprecated */ |
||||
/* originally: |
||||
h=hashed |
||||
o=ordered |
||||
s=special */ |
||||
int2 amstrategies /* total NUMBER of strategies by which |
||||
we can traverse/search this AM */ |
||||
int2 amsupport /* total NUMBER of support functions |
||||
that this AM uses */ |
||||
regproc amgettuple /* "next valid tuple" function */ |
||||
regproc aminsert /* "insert this tuple" function */ |
||||
regproc amdelete /* "delete this tuple" function */ |
||||
regproc amgetattr /* - deprecated */ |
||||
regproc amsetlock /* - deprecated */ |
||||
regproc amsettid /* - deprecated */ |
||||
regproc amfreetuple /* - deprecated */ |
||||
regproc ambeginscan /* "start new scan" function */ |
||||
regproc amrescan /* "restart this scan" function */ |
||||
regproc amendscan /* "end this scan" function */ |
||||
regproc ammarkpos /* "mark current scan position" |
||||
function */ |
||||
regproc amrestrpos /* "restore marked scan position" |
||||
function */ |
||||
regproc amopen /* - deprecated */ |
||||
regproc amclose /* - deprecated */ |
||||
regproc ambuild /* "build new index" function */ |
||||
regproc amcreate /* - deprecated */ |
||||
regproc amdestroy /* - deprecated */ |
||||
.fi |
||||
.nf M |
||||
pg_amop |
||||
oid amopid /* access method with which this |
||||
operator be used */ |
||||
oid amopclaid /* operator class with which this |
||||
operator can be used */ |
||||
oid amopopr /* the operator */ |
||||
int2 amopstrategy /* traversal/search strategy number |
||||
to which this operator applies */ |
||||
regproc amopselect /* function to calculate the operator |
||||
selectivity */ |
||||
regproc amopnpages /* function to calculate the number of |
||||
pages that will be examined */ |
||||
.fi |
||||
.nf M |
||||
pg_amproc |
||||
oid amid /* access method with which this |
||||
procedure is associated */ |
||||
oid amopclaid /* operator class with which this |
||||
operator can be used */ |
||||
oid amproc /* the procedure */ |
||||
int2 amprocnum /* support function number to which |
||||
this operator applies */ |
||||
.fi |
||||
.nf M |
||||
pg_class |
||||
NameData relname /* class name */ |
||||
oid relowner /* usesysid of owner */ |
||||
oid relam /* access method */ |
||||
int4 relpages /* # of 8KB pages */ |
||||
int4 reltuples /* # of instances */ |
||||
abstime relexpires /* time after which instances are |
||||
deleted from non-archival storage */ |
||||
reltime relpreserved /* timespan after which instances are |
||||
deleted from non-archival storage */ |
||||
bool relhasindex /* does the class have a secondary |
||||
index? */ |
||||
bool relisshared /* is the class shared or local? */ |
||||
char relkind /* type of relation: |
||||
i=index |
||||
r=relation (heap) |
||||
s=special |
||||
u=uncatalogued (temporary) */ |
||||
char relarch /* archive mode: |
||||
h=heavy |
||||
l=light |
||||
n=none */ |
||||
int2 relnatts /* current # of non-system |
||||
attributes */ |
||||
int2 relsmgr /* storage manager: |
||||
0=magnetic disk |
||||
1=sony WORM jukebox |
||||
2=main memory */ |
||||
int28 relkey /* - unused */ |
||||
oid8 relkeyop /* - unused */ |
||||
aclitem relacl[1] /* access control lists */ |
||||
.fi |
||||
.nf M |
||||
pg_attribute |
||||
oid attrelid /* class containing this attribute */ |
||||
NameData attname /* attribute name */ |
||||
oid atttypid /* attribute type */ |
||||
oid attdefrel /* - deprecated */ |
||||
int4 attnvals /* - deprecated */ |
||||
oid atttyparg /* - deprecated */ |
||||
int2 attlen /* attribute length, in bytes |
||||
-1=variable */ |
||||
int2 attnum /* attribute number |
||||
>0=user attribute |
||||
<0=system attribute */ |
||||
int2 attbound /* - deprecated */ |
||||
bool attbyval /* type passed by value? */ |
||||
bool attcanindex /* - deprecated */ |
||||
oid attproc /* - deprecated */ |
||||
int4 attnelems /* # of array dimensions */ |
||||
int4 attcacheoff /* cached offset into tuple */ |
||||
bool attisset /* is attribute set-valued? */ |
||||
.fi |
||||
.nf M |
||||
pg_inherits |
||||
oid inhrel /* child class */ |
||||
oid inhparent /* parent class */ |
||||
int4 inhseqno /* - deprecated */ |
||||
.fi |
||||
.nf M |
||||
oid indexrelid /* oid of secondary index class */ |
||||
oid indrelid /* oid of indexed heap class */ |
||||
oid indproc /* function to compute index key from |
||||
attribute(s) in heap |
||||
0=not a functional index */ |
||||
int28 indkey /* attribute numbers of key |
||||
attribute(s) */ |
||||
oid8 indclass /* opclass of each key */ |
||||
bool indisclustered /* is the index clustered? |
||||
- unused */ |
||||
bool indisarchived /* is the index archival? |
||||
- unused */ |
||||
text indpred /* query plan for partial index |
||||
predicate */ |
||||
.fi |
||||
.nf M |
||||
pg_type |
||||
NameData typname /* type name */ |
||||
oid typowner /* usesysid of owner */ |
||||
int2 typlen /* length in internal form |
||||
-1=variable-length */ |
||||
int2 typprtlen /* length in external form */ |
||||
bool typbyval /* type passed by value? */ |
||||
char typtype /* kind of type: |
||||
c=catalog (composite) |
||||
b=base */ |
||||
bool typisdefined /* defined or still a shell? */ |
||||
char typdelim /* delimiter for array external form */ |
||||
oid typrelid /* class (if composite) */ |
||||
oid typelem /* type of each array element */ |
||||
regproc typinput /* external-internal conversion |
||||
function */ |
||||
regproc typoutput /* internal-external conversion |
||||
function */ |
||||
regproc typreceive /* client-server conversion function */ |
||||
regproc typsend /* server-client conversion function */ |
||||
text typdefault /* default value */ |
||||
.fi |
||||
.nf M |
||||
pg_operator |
||||
NameData oprname /* operator name */ |
||||
oid oprowner /* usesysid of owner */ |
||||
int2 oprprec /* - deprecated */ |
||||
char oprkind /* kind of operator: |
||||
b=binary |
||||
l=left unary |
||||
r=right unary */ |
||||
bool oprisleft /* is operator left/right associative? */ |
||||
bool oprcanhash /* is operator usable for hashjoin? */ |
||||
oid oprleft /* left operand type */ |
||||
oid oprright /* right operand type */ |
||||
oid oprresult /* result type */ |
||||
oid oprcom /* commutator operator */ |
||||
oid oprnegate /* negator operator */ |
||||
oid oprlsortop /* sort operator for left operand */ |
||||
oid oprrsortop /* sort operator for right operand */ |
||||
regproc oprcode /* function implementing this operator */ |
||||
regproc oprrest /* function to calculate operator |
||||
restriction selectivity */ |
||||
regproc oprjoin /* function to calculate operator |
||||
join selectivity */ |
||||
.fi |
||||
.nf M |
||||
pg_opclass |
||||
NameData opcname /* operator class name */ |
||||
.fi |
||||
.nf M |
||||
pg_proc |
||||
NameData proname /* function name */ |
||||
oid proowner /* usesysid of owner */ |
||||
oid prolang /* function implementation language */ |
||||
bool proisinh /* - deprecated */ |
||||
bool proistrusted /* run in server or untrusted function |
||||
process? */ |
||||
bool proiscachable /* can the function return values be |
||||
cached? */ |
||||
int2 pronargs /* # of arguments */ |
||||
bool proretset /* does the function return a set? |
||||
- unused */ |
||||
oid prorettype /* return type */ |
||||
oid8 proargtypes /* argument types */ |
||||
int4 probyte_pct /* % of argument size (in bytes) that |
||||
needs to be examined in order to |
||||
compute the function */ |
||||
int4 properbyte_cpu /* sensitivity of the function's |
||||
running time to the size of its |
||||
inputs */ |
||||
int4 propercall_cpu /* overhead of the function's |
||||
invocation (regardless of input |
||||
size) */ |
||||
int4 prooutin_ratio /* size of the function's output as a |
||||
percentage of the size of the input */ |
||||
text prosrc /* function definition: |
||||
INTERNAL function: actual C name of function |
||||
C function: currently, this field is unused |
||||
SQL function: text of query(s) |
||||
PL function: text in procedural language */ |
||||
bytea probin /* path to object file (C functions only) */ |
||||
.fi |
||||
.nf M |
||||
pg_language |
||||
NameData lanname /* language name */ |
||||
text lancompiler /* - deprecated */ |
||||
.fi |
||||
.SH "ENTITIES" |
||||
.nf M |
||||
pg_database |
||||
NameData datname /* database name */ |
||||
oid datdba /* usesysid of database administrator */ |
||||
text datpath /* directory of database under |
||||
$PGDATA */ |
||||
.fi |
||||
.nf M |
||||
pg_group |
||||
NameData groname /* group name */ |
||||
int2 grosysid /* group's UNIX group id */ |
||||
int2 grolist[1] /* list of usesysids of group members */ |
||||
.fi |
||||
.nf M |
||||
pg_shadow |
||||
NameData usename /* user's name */ |
||||
int2 usesysid /* user's UNIX user id */ |
||||
bool usecreatedb /* can user create databases? */ |
||||
bool usetrace /* can user set trace flags? */ |
||||
bool usesuper /* can user be POSTGRES superuser? */ |
||||
bool usecatupd /* can user update catalogs? */ |
||||
.fi |
||||
.SH "RULE SYSTEM CATALOGS" |
||||
.nf M |
||||
pg_listener |
||||
NameData relname /* class for which asynchronous |
||||
notification is desired */ |
||||
int4 listenerpid /* process id of server corresponding |
||||
to a frontend program waiting for |
||||
asynchronous notification */ |
||||
int4 notification /* whether an event notification for |
||||
this process id still pending */ |
||||
|
||||
.fi |
||||
.nf M |
||||
pg_prs2rule |
||||
NameData prs2name /* rule name */ |
||||
char prs2eventtype /* rule event type: |
||||
R=retrieve |
||||
U=update (replace) |
||||
A=append |
||||
D=delete */ |
||||
oid prs2eventrel /* class to which event applies */ |
||||
int2 prs2eventattr /* attribute to which event applies */ |
||||
float8 necessary /* - deprecated */ |
||||
float8 sufficient /* - deprecated */ |
||||
text prs2text /* text of original rule definition */ |
||||
.fi |
||||
.nf M |
||||
pg_prs2plans |
||||
oid prs2ruleid /* prs2rule instance for which this |
||||
plan is used */ |
||||
int2 prs2planno /* plan number (one rule may invoke |
||||
multiple plans) */ |
||||
text prs2code /* external representation of the plan */ |
||||
.fi |
||||
.nf M |
||||
pg_prs2stub |
||||
oid prs2relid /* class to which this rule applies */ |
||||
bool prs2islast /* is this the last stub fragment? */ |
||||
int4 prs2no /* stub fragment number */ |
||||
stub prs2stub /* stub fragment */ |
||||
.fi |
||||
.nf M |
||||
pg_rewrite |
||||
NameData rulename /* rule name */ |
||||
char ev_type /* event type: |
||||
RETRIEVE, REPLACE, APPEND, DELETE |
||||
codes are parser-dependent (!?) */ |
||||
oid ev_class /* class to which this rule applies */ |
||||
int2 ev_attr /* attribute to which this rule applies */ |
||||
bool is_instead /* is this an "instead" rule? */ |
||||
text ev_qual /* qualification with which to modify |
||||
(rewrite) the plan that triggered this |
||||
rule */ |
||||
text action /* parse tree of action */ |
||||
.fi |
||||
.SH "LARGE OBJECT CATALOGS" |
||||
.nf M |
||||
pg_lobj |
||||
oid ourid /* 'ourid' from pg_naming that |
||||
identifies this object in the |
||||
Inversion file system namespace */ |
||||
int4 objtype /* storage type code: |
||||
0=Inversion |
||||
1=Unix |
||||
2=External |
||||
3=Jaquith */ |
||||
bytea object_descripto/* opaque object-handle structure */ |
||||
.fi |
||||
.nf M |
||||
pg_naming |
||||
NameData filename /* filename component */ |
||||
oid ourid /* random oid used to identify this |
||||
instance in other instances (can't |
||||
use the actual oid for obscure |
||||
reasons */ |
||||
oid parentid /* pg_naming instance of parent |
||||
Inversion file system directory */ |
||||
.fi |
||||
.nf M |
||||
pg_platter |
||||
NameData plname /* platter name */ |
||||
int4 plstart /* the highest OCCUPIED extent */ |
||||
.fi |
||||
.nf M |
||||
pg_plmap |
||||
oid plid /* platter (in pg_platter) on which |
||||
this extent (of blocks) resides */ |
||||
oid pldbid /* database of the class to which this |
||||
extent (of blocks) belongs */ |
||||
oid plrelid /* class to which this extend (of |
||||
blocks) belongs */ |
||||
int4 plblkno /* starting block number within the |
||||
class */ |
||||
int4 ploffset /* offset within the platter at which |
||||
this extent begins */ |
||||
int4 plextentsz /* length of this extent */ |
||||
.fi |
@ -1,252 +1,279 @@ |
||||
<Chapter Id="extend"> |
||||
<Title>Extending <Acronym>SQL</Acronym>: An Overview</Title> |
||||
|
||||
<Para> |
||||
In the sections that follow, we will discuss how you |
||||
can extend the <ProductName>Postgres</ProductName> <Acronym>SQL</Acronym> query language by adding: |
||||
<ItemizedList Mark="bullet" Spacing="compact"> |
||||
<ListItem> |
||||
<Para> |
||||
<chapter id="extend"> |
||||
<title>Extending <acronym>SQL</acronym>: An Overview</title> |
||||
|
||||
<para> |
||||
In the sections that follow, we will discuss how you |
||||
can extend the <productname>Postgres</productname> |
||||
<acronym>SQL</acronym> query language by adding: |
||||
|
||||
<itemizedlist spacing="compact" mark="bullet"> |
||||
<listitem> |
||||
<para> |
||||
functions |
||||
</Para> |
||||
</ListItem> |
||||
<ListItem> |
||||
<Para> |
||||
</para> |
||||
</listitem> |
||||
<listitem> |
||||
<para> |
||||
types |
||||
</Para> |
||||
</ListItem> |
||||
<ListItem> |
||||
<Para> |
||||
</para> |
||||
</listitem> |
||||
<listitem> |
||||
<para> |
||||
operators |
||||
</Para> |
||||
</ListItem> |
||||
<ListItem> |
||||
<Para> |
||||
</para> |
||||
</listitem> |
||||
<listitem> |
||||
<para> |
||||
aggregates |
||||
</Para> |
||||
</ListItem> |
||||
</ItemizedList> |
||||
</Para> |
||||
|
||||
<Sect1> |
||||
<Title>How Extensibility Works</Title> |
||||
|
||||
<Para> |
||||
<ProductName>Postgres</ProductName> is extensible because its operation is |
||||
catalog-driven. If you are familiar with standard |
||||
relational systems, you know that they store information |
||||
about databases, tables, columns, etc., in what are |
||||
commonly known as system catalogs. (Some systems call |
||||
this the data dictionary). The catalogs appear to the |
||||
user as classes, like any other, but the <Acronym>DBMS</Acronym> stores |
||||
its internal bookkeeping in them. One key difference |
||||
between <ProductName>Postgres</ProductName> and standard relational systems is |
||||
that <ProductName>Postgres</ProductName> stores much more information in its |
||||
catalogs -- not only information about tables and columns, |
||||
but also information about its types, functions, access |
||||
methods, and so on. These classes can be modified by |
||||
the user, and since <ProductName>Postgres</ProductName> bases its internal operation |
||||
on these classes, this means that <ProductName>Postgres</ProductName> can be |
||||
extended by users. By comparison, conventional |
||||
database systems can only be extended by changing hardcoded |
||||
procedures within the <Acronym>DBMS</Acronym> or by loading modules |
||||
specially-written by the <Acronym>DBMS</Acronym> vendor. |
||||
</Para> |
||||
<Para> |
||||
<ProductName>Postgres</ProductName> is also unlike most other data managers in |
||||
that the server can incorporate user-written code into |
||||
itself through dynamic loading. That is, the user can |
||||
specify an object code file (e.g., a compiled .o file |
||||
or shared library) that implements a new type or function |
||||
and <ProductName>Postgres</ProductName> will load it as required. Code written |
||||
in <Acronym>SQL</Acronym> are even more trivial to add to the server. |
||||
This ability to modify its operation "on the fly" makes |
||||
<ProductName>Postgres</ProductName> uniquely suited for rapid prototyping of new |
||||
applications and storage structures. |
||||
</Para> |
||||
</Sect1> |
||||
|
||||
<Sect1> |
||||
<Title>The <ProductName>Postgres</ProductName> Type System</Title> |
||||
|
||||
<Para> |
||||
The <ProductName>Postgres</ProductName> type system can be broken down in several ways. |
||||
Types are divided into base types and composite types. |
||||
Base types are those, like <FirstTerm>int4</FirstTerm>, that are implemented |
||||
in a language such as <ProductName>C</ProductName>. They generally correspond to |
||||
what are often known as "abstract data types"; <ProductName>Postgres</ProductName> |
||||
can only operate on such types through methods provided |
||||
by the user and only understands the behavior of such |
||||
types to the extent that the user describes them. |
||||
Composite types are created whenever the user creates a |
||||
class. EMP is an example of a composite type. |
||||
</Para> |
||||
<Para> |
||||
<ProductName>Postgres</ProductName> stores these types in only one way (within the |
||||
file that stores all instances of the class) but the |
||||
user can "look inside" at the attributes of these types |
||||
from the query language and optimize their retrieval by |
||||
(for example) defining indices on the attributes. |
||||
<ProductName>Postgres</ProductName> base types are further divided into built-in |
||||
types and user-defined types. Built-in types (like |
||||
<FirstTerm>int4</FirstTerm>) are those that are compiled into the system. |
||||
User-defined types are those created by the user in the |
||||
manner to be described below. |
||||
</Para> |
||||
</Sect1> |
||||
|
||||
<Sect1> |
||||
<Title>About the <ProductName>Postgres</ProductName> System Catalogs</Title> |
||||
|
||||
<Para> |
||||
Having introduced the basic extensibility concepts, we |
||||
can now take a look at how the catalogs are actually |
||||
laid out. You can skip this section for now, but some |
||||
later sections will be incomprehensible without the |
||||
information given here, so mark this page for later |
||||
reference. |
||||
All system catalogs have names that begin with <FirstTerm>pg_</FirstTerm>. |
||||
The following classes contain information that may be |
||||
useful to the end user. (There are many other system |
||||
catalogs, but there should rarely be a reason to query |
||||
them directly.) |
||||
|
||||
<TABLE TOCENTRY="1"> |
||||
<TITLE>Postgres System Catalogs</TITLE> |
||||
<TITLEABBREV>Catalogs</TITLEABBREV> |
||||
<TGROUP COLS="2"> |
||||
<THEAD> |
||||
<ROW> |
||||
<ENTRY>Catalog Name</ENTRY> |
||||
<ENTRY>Description</ENTRY> |
||||
</ROW> |
||||
</THEAD> |
||||
<TBODY> |
||||
<ROW> |
||||
<ENTRY>pg_database</ENTRY> |
||||
<ENTRY> databases</ENTRY> |
||||
</ROW> |
||||
<ROW> |
||||
<ENTRY>pg_class</ENTRY> |
||||
<ENTRY> classes</ENTRY> |
||||
</ROW> |
||||
<ROW> |
||||
<ENTRY>pg_attribute</ENTRY> |
||||
<ENTRY> class attributes</ENTRY> |
||||
</ROW> |
||||
<ROW> |
||||
<ENTRY>pg_index</ENTRY> |
||||
<ENTRY> secondary indices</ENTRY> |
||||
</ROW> |
||||
<ROW> |
||||
<ENTRY>pg_proc</ENTRY> |
||||
<ENTRY> procedures (both C and SQL)</ENTRY> |
||||
</ROW> |
||||
<ROW> |
||||
<ENTRY>pg_type</ENTRY> |
||||
<ENTRY> types (both base and complex)</ENTRY> |
||||
</ROW> |
||||
<ROW> |
||||
<ENTRY>pg_operator</ENTRY> |
||||
<ENTRY> operators</ENTRY> |
||||
</ROW> |
||||
<ROW> |
||||
<ENTRY>pg_aggregate</ENTRY> |
||||
<ENTRY> aggregates and aggregate functions</ENTRY> |
||||
</ROW> |
||||
<ROW> |
||||
<ENTRY>pg_am</ENTRY> |
||||
<ENTRY> access methods</ENTRY> |
||||
</ROW> |
||||
<ROW> |
||||
<ENTRY>pg_amop</ENTRY> |
||||
<ENTRY> access method operators</ENTRY> |
||||
</ROW> |
||||
<ROW> |
||||
<ENTRY>pg_amproc</ENTRY> |
||||
<ENTRY> access method support functions</ENTRY> |
||||
</ROW> |
||||
<ROW> |
||||
<ENTRY>pg_opclass</ENTRY> |
||||
<ENTRY> access method operator classes</ENTRY> |
||||
</ROW> |
||||
</TBODY> |
||||
</TGROUP> |
||||
</TABLE> |
||||
</Para> |
||||
|
||||
<Para> |
||||
<Figure Id="EXTEND-CATALOGS" Float="1"> |
||||
<Title>The major <ProductName>Postgres</ProductName> system catalogs</Title> |
||||
<Graphic Align="center" FileRef="catalogs.gif" Format="GIF"></Graphic> |
||||
</Figure> |
||||
|
||||
The Reference Manual gives a more detailed explanation |
||||
of these catalogs and their attributes. However, |
||||
<XRef LinkEnd="EXTEND-CATALOGS" EndTerm="EXTEND-CATALOGS"> |
||||
shows the major entities and their relationships |
||||
in the system catalogs. (Attributes that do not refer |
||||
to other entities are not shown unless they are part of |
||||
a primary key.) |
||||
This diagram is more or less incomprehensible until you |
||||
actually start looking at the contents of the catalogs |
||||
and see how they relate to each other. For now, the |
||||
main things to take away from this diagram are as follows: |
||||
</para> |
||||
</listitem> |
||||
</itemizedlist> |
||||
</para> |
||||
|
||||
<sect1> |
||||
<title>How Extensibility Works</title> |
||||
|
||||
<para> |
||||
<productname>Postgres</productname> is extensible because its operation is |
||||
catalog-driven. If you are familiar with standard |
||||
relational systems, you know that they store information |
||||
about databases, tables, columns, etc., in what are |
||||
commonly known as system catalogs. (Some systems call |
||||
this the data dictionary). The catalogs appear to the |
||||
user as classes, like any other, but the <acronym>DBMS</acronym> stores |
||||
its internal bookkeeping in them. One key difference |
||||
between <productname>Postgres</productname> and standard relational systems is |
||||
that <productname>Postgres</productname> stores much more information in its |
||||
catalogs -- not only information about tables and columns, |
||||
but also information about its types, functions, access |
||||
methods, and so on. These classes can be modified by |
||||
the user, and since <productname>Postgres</productname> bases its internal operation |
||||
on these classes, this means that <productname>Postgres</productname> can be |
||||
extended by users. By comparison, conventional |
||||
database systems can only be extended by changing hardcoded |
||||
procedures within the <acronym>DBMS</acronym> or by loading modules |
||||
specially-written by the <acronym>DBMS</acronym> vendor. |
||||
</para> |
||||
|
||||
<para> |
||||
<productname>Postgres</productname> is also unlike most other data managers in |
||||
that the server can incorporate user-written code into |
||||
itself through dynamic loading. That is, the user can |
||||
specify an object code file (e.g., a compiled .o file |
||||
or shared library) that implements a new type or function |
||||
and <productname>Postgres</productname> will load it as required. Code written |
||||
in <acronym>SQL</acronym> are even more trivial to add to the server. |
||||
This ability to modify its operation "on the fly" makes |
||||
<productname>Postgres</productname> uniquely suited for rapid prototyping of new |
||||
applications and storage structures. |
||||
</para> |
||||
</sect1> |
||||
|
||||
<sect1> |
||||
<title>The <productname>Postgres</productname> Type System</title> |
||||
|
||||
<para> |
||||
The <productname>Postgres</productname> type system |
||||
can be broken down in several ways. |
||||
Types are divided into base types and composite types. |
||||
Base types are those, like <firstterm>int4</firstterm>, that are implemented |
||||
in a language such as <productname>C</productname>. They generally correspond to |
||||
what are often known as "abstract data types"; <productname>Postgres</productname> |
||||
can only operate on such types through methods provided |
||||
by the user and only understands the behavior of such |
||||
types to the extent that the user describes them. |
||||
Composite types are created whenever the user creates a |
||||
class. EMP is an example of a composite type. |
||||
</para> |
||||
|
||||
<para> |
||||
<productname>Postgres</productname> stores these types |
||||
in only one way (within the |
||||
file that stores all instances of the class) but the |
||||
user can "look inside" at the attributes of these types |
||||
from the query language and optimize their retrieval by |
||||
(for example) defining indices on the attributes. |
||||
<productname>Postgres</productname> base types are further |
||||
divided into built-in |
||||
types and user-defined types. Built-in types (like |
||||
<firstterm>int4</firstterm>) are those that are compiled |
||||
into the system. |
||||
User-defined types are those created by the user in the |
||||
manner to be described below. |
||||
</para> |
||||
</sect1> |
||||
|
||||
<sect1> |
||||
<title>About the <productname>Postgres</productname> System Catalogs</title> |
||||
|
||||
<para> |
||||
Having introduced the basic extensibility concepts, we |
||||
can now take a look at how the catalogs are actually |
||||
laid out. You can skip this section for now, but some |
||||
later sections will be incomprehensible without the |
||||
information given here, so mark this page for later |
||||
reference. |
||||
All system catalogs have names that begin with |
||||
<firstterm>pg_</firstterm>. |
||||
The following classes contain information that may be |
||||
useful to the end user. (There are many other system |
||||
catalogs, but there should rarely be a reason to query |
||||
them directly.) |
||||
|
||||
<table tocentry="1"> |
||||
<title>Postgres System Catalogs</title> |
||||
<titleabbrev>Catalogs</titleabbrev> |
||||
<tgroup cols="2"> |
||||
<thead> |
||||
<row> |
||||
<entry>Catalog Name</entry> |
||||
<entry>Description</entry> |
||||
</row> |
||||
</thead> |
||||
<tbody> |
||||
<row> |
||||
<entry>pg_database</entry> |
||||
<entry> databases</entry> |
||||
</row> |
||||
<row> |
||||
<entry>pg_class</entry> |
||||
<entry> classes</entry> |
||||
</row> |
||||
<row> |
||||
<entry>pg_attribute</entry> |
||||
<entry> class attributes</entry> |
||||
</row> |
||||
<row> |
||||
<entry>pg_index</entry> |
||||
<entry> secondary indices</entry> |
||||
</row> |
||||
<row> |
||||
<entry>pg_proc</entry> |
||||
<entry> procedures (both C and SQL)</entry> |
||||
</row> |
||||
<row> |
||||
<entry>pg_type</entry> |
||||
<entry> types (both base and complex)</entry> |
||||
</row> |
||||
<row> |
||||
<entry>pg_operator</entry> |
||||
<entry> operators</entry> |
||||
</row> |
||||
<row> |
||||
<entry>pg_aggregate</entry> |
||||
<entry> aggregates and aggregate functions</entry> |
||||
</row> |
||||
<row> |
||||
<entry>pg_am</entry> |
||||
<entry> access methods</entry> |
||||
</row> |
||||
<row> |
||||
<entry>pg_amop</entry> |
||||
<entry> access method operators</entry> |
||||
</row> |
||||
<row> |
||||
<entry>pg_amproc</entry> |
||||
<entry> access method support functions</entry> |
||||
</row> |
||||
<row> |
||||
<entry>pg_opclass</entry> |
||||
<entry> access method operator classes</entry> |
||||
</row> |
||||
</tbody> |
||||
</tgroup> |
||||
</table> |
||||
</para> |
||||
|
||||
<para> |
||||
<figure float="1" id="EXTEND-CATALOGS"> |
||||
<title>The major <productname>Postgres</productname> system catalogs</title> |
||||
<graphic fileref="catalogs.gif" format="GIF" align="center"></graphic> |
||||
</figure> |
||||
|
||||
The Reference Manual gives a more detailed explanation |
||||
of these catalogs and their attributes. However, |
||||
<xref endterm="EXTEND-CATALOGS" linkend="EXTEND-CATALOGS"> |
||||
shows the major entities and their relationships |
||||
in the system catalogs. (Attributes that do not refer |
||||
to other entities are not shown unless they are part of |
||||
a primary key.) |
||||
This diagram is more or less incomprehensible until you |
||||
actually start looking at the contents of the catalogs |
||||
and see how they relate to each other. For now, the |
||||
main things to take away from this diagram are as follows: |
||||
|
||||
<ItemizedList Mark="bullet" Spacing="compact"> |
||||
<ListItem> |
||||
<Para> |
||||
In several of the sections that follow, we will |
||||
present various join queries on the system |
||||
catalogs that display information we need to extend |
||||
the system. Looking at this diagram should make |
||||
some of these join queries (which are often |
||||
three- or four-way joins) more understandable, |
||||
because you will be able to see that the |
||||
attributes used in the queries form foreign keys |
||||
in other classes. |
||||
</Para> |
||||
</ListItem> |
||||
<ListItem> |
||||
<Para> Many different features (classes, attributes, |
||||
functions, types, access methods, etc.) are |
||||
tightly integrated in this schema. A simple |
||||
create command may modify many of these catalogs. |
||||
</Para> |
||||
</ListItem> |
||||
<ListItem> |
||||
<Para> Types and procedures |
||||
are central to the schema. |
||||
|
||||
<Note> |
||||
<Para> |
||||
We use the words <FirstTerm>procedure</FirstTerm> and <FirstTerm>function</FirstTerm> more or less |
||||
interchangably. |
||||
</Para> |
||||
</Note> |
||||
|
||||
Nearly every catalog contains some reference to |
||||
instances in one or both of these classes. For |
||||
example, <ProductName>Postgres</ProductName> frequently uses type |
||||
signatures (e.g., of functions and operators) to |
||||
identify unique instances of other catalogs. |
||||
|
||||
</Para> |
||||
</ListItem> |
||||
<ListItem> |
||||
<Para> There are many attributes and relationships that |
||||
have obvious meanings, but there are many |
||||
(particularly those that have to do with access |
||||
methods) that do not. The relationships between |
||||
pg_am, pg_amop, pg_amproc, pg_operator and |
||||
pg_opclass are particularly hard to understand |
||||
and will be described in depth (in the section |
||||
on interfacing types and operators to indices) |
||||
after we have discussed basic extensions. |
||||
</para> |
||||
</ListItem> |
||||
</ItemizedList> |
||||
|
||||
</Para> |
||||
</sect1> |
||||
</Chapter> |
||||
<itemizedlist spacing="compact" mark="bullet"> |
||||
<listitem> |
||||
<para> |
||||
In several of the sections that follow, we will |
||||
present various join queries on the system |
||||
catalogs that display information we need to extend |
||||
the system. Looking at this diagram should make |
||||
some of these join queries (which are often |
||||
three- or four-way joins) more understandable, |
||||
because you will be able to see that the |
||||
attributes used in the queries form foreign keys |
||||
in other classes. |
||||
</para> |
||||
</listitem> |
||||
<listitem> |
||||
<para> |
||||
Many different features (classes, attributes, |
||||
functions, types, access methods, etc.) are |
||||
tightly integrated in this schema. A simple |
||||
create command may modify many of these catalogs. |
||||
</para> |
||||
</listitem> |
||||
<listitem> |
||||
<para> |
||||
Types and procedures |
||||
are central to the schema. |
||||
|
||||
<note> |
||||
<para> |
||||
We use the words <firstterm>procedure</firstterm> |
||||
and <firstterm>function</firstterm> more or less interchangably. |
||||
</para> |
||||
</note> |
||||
|
||||
Nearly every catalog contains some reference to |
||||
instances in one or both of these classes. For |
||||
example, <productname>Postgres</productname> frequently uses type |
||||
signatures (e.g., of functions and operators) to |
||||
identify unique instances of other catalogs. |
||||
</para> |
||||
</listitem> |
||||
<listitem> |
||||
<para> |
||||
There are many attributes and relationships that |
||||
have obvious meanings, but there are many |
||||
(particularly those that have to do with access |
||||
methods) that do not. The relationships between |
||||
pg_am, pg_amop, pg_amproc, pg_operator and |
||||
pg_opclass are particularly hard to understand |
||||
and will be described in depth (in the section |
||||
on interfacing types and operators to indices) |
||||
after we have discussed basic extensions. |
||||
</para> |
||||
</listitem> |
||||
</itemizedlist> |
||||
</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: |
||||
--> |
||||
|
@ -1,57 +1,384 @@ |
||||
<chapter id="indices"> |
||||
<title>Indices</title> |
||||
<chapter id="indices"> |
||||
<title id="indices-title">Indices and Keys</title> |
||||
|
||||
<para> |
||||
<para> |
||||
Indexes are primarily used to enhance database |
||||
performance. They should be defined on table columns (or class |
||||
attributes) which are used as qualifications in repetative queries. |
||||
Inappropriate use will result in slower performance, since update |
||||
and insertion times are increased in the presence of indices. |
||||
</para> |
||||
|
||||
<sect1> |
||||
<title>Partial Indices</title> |
||||
<para> |
||||
Two forms of indices may be defined: |
||||
|
||||
<para> |
||||
<note> |
||||
<title>Author</title> |
||||
<para> |
||||
This is from a reply to a question on the e-mail list |
||||
by <ulink url="aoki@CS.Berkeley.EDU">Paul M. Aoki</ulink> |
||||
on 1998-08-11. |
||||
<itemizedlist> |
||||
<listitem> |
||||
<para> |
||||
For a <firstterm>value index</firstterm>, |
||||
the key fields for the |
||||
index are specified as column names; a column may also have |
||||
an associated operator class. An operator class is used |
||||
to specify the operators to be used for a particular |
||||
index. For example, a btree index on four-byte integers |
||||
would use the <literal>int4_ops</literal> class; |
||||
this operator class includes |
||||
comparison functions for four-byte integers. The default |
||||
operator class is the appropriate operator class for that |
||||
field type. |
||||
</para> |
||||
</listitem> |
||||
|
||||
<listitem> |
||||
<para> |
||||
For a <firstterm>functional index</firstterm>, an index is defined |
||||
on the result of a user-defined function applied |
||||
to one or more attributes of a single class. |
||||
These functional indices |
||||
can be used to obtain fast access to data |
||||
based on operators that would normally require some |
||||
transformation to apply them to the base data. |
||||
</para> |
||||
</listitem> |
||||
</itemizedlist> |
||||
</para> |
||||
|
||||
<para> |
||||
Postgres provides btree, rtree and hash access methods for |
||||
secondary indices. The btree access method is an implementation of |
||||
the Lehman-Yao high-concurrency btrees. The rtree access method |
||||
implements standard rtrees using Guttman's quadratic split algorithm. |
||||
The hash access method is an implementation of Litwin's linear |
||||
hashing. We mention the algorithms used solely to indicate that all |
||||
of these access methods are fully dynamic and do not have to be |
||||
optimized periodically (as is the case with, for example, static hash |
||||
access methods). |
||||
</para> |
||||
|
||||
<para> |
||||
The Postgres query optimizer will consider using btree indices in a scan |
||||
whenever an indexed attribute is involved in a comparison using one of: |
||||
|
||||
<simplelist type="inline"> |
||||
<member><</member> |
||||
<member><=</member> |
||||
<member>=</member> |
||||
<member>>=</member> |
||||
<member>></member> |
||||
</simplelist> |
||||
</para> |
||||
|
||||
<para> |
||||
Both box classes support indices on the <literal>box</literal> data |
||||
type in <productname>Postgres</productname>. |
||||
The difference between them is that <literal>bigbox_ops</literal> |
||||
scales box coordinates down, to avoid floating point exceptions from |
||||
doing multiplication, addition, and subtraction on very large |
||||
floating-point coordinates. If the field on which your rectangles lie |
||||
is about 20,000 units square or larger, you should use |
||||
<literal>bigbox_ops</literal>. |
||||
The <literal>poly_ops</literal> operator class supports rtree |
||||
indices on <literal>polygon</literal> data. |
||||
</para> |
||||
|
||||
<para> |
||||
The <productname>Postgres</productname> |
||||
query optimizer will consider using an rtree index whenever |
||||
an indexed attribute is involved in a comparison using one of: |
||||
|
||||
<simplelist type="inline"> |
||||
<member><<</member> |
||||
<member>&<</member> |
||||
<member>&></member> |
||||
<member>>></member> |
||||
<member>@</member> |
||||
<member>~=</member> |
||||
<member>&&</member> |
||||
</simplelist> |
||||
</para> |
||||
|
||||
<para> |
||||
The <productname>Postgres</productname> |
||||
query optimizer will consider using a hash index whenever |
||||
an indexed attribute is involved in a comparison using |
||||
the <literal>=</literal> operator. |
||||
</para> |
||||
|
||||
<para> |
||||
Currently, only the BTREE access method supports multi-column |
||||
indexes. Up to 7 keys may be specified. |
||||
</para> |
||||
|
||||
<para> |
||||
Use <xref endterm="sql-dropindex-title" |
||||
linkend="sql-dropindex-title"> |
||||
to remove an index. |
||||
</para> |
||||
|
||||
<para> |
||||
The <literal>int24_ops</literal> |
||||
operator class is useful for constructing indices on int2 data, and |
||||
doing comparisons against int4 data in query qualifications. |
||||
Similarly, <literal>int42_ops</literal> |
||||
support indices on int4 data that is to be compared against int2 data |
||||
in queries. |
||||
</para> |
||||
|
||||
<para> |
||||
The following select list returns all ops_names: |
||||
|
||||
<programlisting> |
||||
SELECT am.amname AS acc_name, |
||||
opc.opcname AS ops_name, |
||||
opr.oprname AS ops_comp |
||||
FROM pg_am am, pg_amop amop, |
||||
pg_opclass opc, pg_operator opr |
||||
WHERE amop.amopid = am.oid AND |
||||
amop.amopclaid = opc.oid AND |
||||
amop.amopopr = opr.oid |
||||
ORDER BY acc_name, ops_name, ops_comp |
||||
</programlisting> |
||||
</para> |
||||
|
||||
<sect1 id="keys"> |
||||
<title id="keys-title">Keys</title> |
||||
|
||||
<para> |
||||
<note> |
||||
<title>Author</title> |
||||
<para> |
||||
Written by |
||||
<ulink url="herouth@oumail.openu.ac.il">Herouth Maoz</ulink> |
||||
This originally appeared on the User's Mailing List on 1998-03-02 |
||||
in response to the question: |
||||
"What is the difference between PRIMARY KEY and UNIQUE constraints?". |
||||
</para> |
||||
</note> |
||||
</para> |
||||
|
||||
<para> |
||||
<programlisting> |
||||
Subject: Re: [QUESTIONS] PRIMARY KEY | UNIQUE |
||||
|
||||
What's the difference between: |
||||
|
||||
PRIMARY KEY(fields,...) and |
||||
UNIQUE (fields,...) |
||||
|
||||
- Is this an alias? |
||||
- If PRIMARY KEY is already unique, then why |
||||
is there another kind of key named UNIQUE? |
||||
</programlisting> |
||||
</para> |
||||
|
||||
<para> |
||||
A primary key is the field(s) used to identify a specific row. For example, |
||||
Social Security numbers identifying a person. |
||||
</para> |
||||
|
||||
<para> |
||||
A simply UNIQUE combination of fields has nothing to do with identifying |
||||
the row. It's simply an integrity constraint. For example, I have |
||||
collections of links. Each collection is identified by a unique number, |
||||
which is the primary key. This key is used in relations. |
||||
</para> |
||||
|
||||
<para> |
||||
However, my application requires that each collection will also have a |
||||
unique name. Why? So that a human being who wants to modify a collection |
||||
will be able to identify it. It's much harder to know, if you have two |
||||
collections named "Life Science", the the one tagged 24433 is the one you |
||||
need, and the one tagged 29882 is not. |
||||
</para> |
||||
|
||||
<para> |
||||
So, the user selects the collection by its name. We therefore make sure, |
||||
withing the database, that names are unique. However, no other table in the |
||||
database relates to the collections table by the collection Name. That |
||||
would be very inefficient. |
||||
</para> |
||||
|
||||
<para> |
||||
Moreover, despite being unique, the collection name does not actually |
||||
define the collection! For example, if somebody decided to change the name |
||||
of the collection from "Life Science" to "Biology", it will still be the |
||||
same collection, only with a different name. As long as the name is unique, |
||||
that's OK. |
||||
</para> |
||||
|
||||
<para> |
||||
So: |
||||
|
||||
<itemizedlist> |
||||
<listitem> |
||||
<para> |
||||
Primary key: |
||||
<itemizedlist spacing="compact" mark="bullet"> |
||||
<listitem> |
||||
<para> |
||||
Is used for identifying the row and relating to it. |
||||
</para> |
||||
</listitem> |
||||
<listitem> |
||||
<para> |
||||
Is impossible (or hard) to update. |
||||
</para> |
||||
</listitem> |
||||
<listitem> |
||||
<para> |
||||
Should not allow NULLs. |
||||
</para> |
||||
</listitem> |
||||
</itemizedlist> |
||||
</para> |
||||
</listitem> |
||||
|
||||
<listitem> |
||||
<para> |
||||
Unique field(s): |
||||
<itemizedlist spacing="compact" mark="bullet"> |
||||
<listitem> |
||||
<para> |
||||
Are used as an alternative access to the row. |
||||
</para> |
||||
</listitem> |
||||
<listitem> |
||||
<para> |
||||
Are updateable, so long as they are kept unique. |
||||
</para> |
||||
</listitem> |
||||
<listitem> |
||||
<para> |
||||
NULLs are acceptable. |
||||
</para> |
||||
</listitem> |
||||
</itemizedlist> |
||||
</para> |
||||
</listitem> |
||||
</itemizedlist> |
||||
</para> |
||||
|
||||
<para> |
||||
As for why no non-unique keys are defined explicitly in standard |
||||
<acronym>SQL</acronym> syntax? Well, you |
||||
must understand that indices are implementation-dependent. |
||||
<acronym>SQL</acronym> does not |
||||
define the implementation, merely the relations between data in the |
||||
database. <productname>Postgres</productname> does allow |
||||
non-unique indices, but indices |
||||
used to enforce <acronym>SQL</acronym> keys are always unique. |
||||
</para> |
||||
|
||||
<para> |
||||
Thus, you may query a table by any combination of its columns, despite the |
||||
fact that you don't have an index on these columns. The indexes are merely |
||||
an implementational aid which each <acronym>RDBMS</acronym> offers |
||||
you, in order to cause |
||||
commonly used queries to be done more efficiently. |
||||
Some <acronym>RDBMS</acronym> may give you |
||||
additional measures, such as keeping a key stored in main memory. They will |
||||
have a special command, for example |
||||
<programlisting> |
||||
CREATE MEMSTORE ON <table> COLUMNS <cols> |
||||
</programlisting> |
||||
(this is not an existing command, just an example). |
||||
</para> |
||||
|
||||
<para> |
||||
In fact, when you create a primary key or a unique combination of fields, |
||||
nowhere in the <acronym>SQL</acronym> specification does it say |
||||
that an index is created, nor that |
||||
the retrieval of data by the key is going to be more efficient than a |
||||
sequential scan! |
||||
</para> |
||||
|
||||
<para> |
||||
So, if you want to use a combination of fields which is not unique as a |
||||
secondary key, you really don't have to specify anything - just start |
||||
retrieving by that combination! However, if you want to make the retrieval |
||||
efficient, you'll have to resort to the means your |
||||
<acronym>RDBMS</acronym> provider gives you |
||||
- be it an index, my imaginary MEMSTORE command, or an intelligent |
||||
<acronym>RDBMS</acronym> |
||||
which creates indices without your knowledge based on the fact that you have |
||||
sent it many queries based on a specific combination of keys... (It learns |
||||
from experience). |
||||
</para> |
||||
</sect1> |
||||
|
||||
<sect1 id="partial-index"> |
||||
<title id="partial-index-title">Partial Indices</title> |
||||
|
||||
<note> |
||||
<title>Author</title> |
||||
<para> |
||||
This is from a reply to a question on the e-mail list |
||||
by <ulink url="aoki@CS.Berkeley.EDU">Paul M. Aoki</ulink> |
||||
on 1998-08-11. |
||||
<!-- |
||||
Paul M. Aoki | University of California at Berkeley |
||||
aoki@CS.Berkeley.EDU | Dept. of EECS, Computer Science Division #1776 |
||||
| Berkeley, CA 94720-1776 |
||||
--> |
||||
</note> |
||||
|
||||
A <firstterm>partial index</firstterm> |
||||
is an index built over a subset of a table; the subset is defined by |
||||
a predicate. <productname>Postgres</productname> |
||||
supported partial indices with arbitrary |
||||
predicates. I believe IBM's db2 for as/400 supports partial indices |
||||
using single-clause predicates. |
||||
|
||||
<para> |
||||
The main motivation for partial indices is this: |
||||
if all of the queries you ask that can |
||||
profitably use an index fall into a certain range, why build an index |
||||
over the whole table and suffer the associated space/time costs? |
||||
|
||||
(There are other reasons too; see |
||||
<xref linkend="STON89b-full" endterm="STON89b"> for details.) |
||||
|
||||
<para> |
||||
The machinery to build, update and query partial indices isn't too |
||||
bad. The hairy parts are index selection (which indices do I build?) |
||||
and query optimization (which indices do I use?); i.e., the parts |
||||
that involve deciding what predicate(s) match the workload/query in |
||||
some useful way. For those who are into database theory, the problems |
||||
are basically analogous to the corresponding materialized view |
||||
problems, albeit with different cost parameters and formulae. These |
||||
are, in the general case, hard problems for the standard ordinal |
||||
<acronym>SQL</acronym> |
||||
types; they're super-hard problems with black-box extension types, |
||||
because the selectivity estimation technology is so crude. |
||||
|
||||
<para> |
||||
Check <xref linkend="STON89b-full" endterm="STON89b">, |
||||
<xref linkend="OLSON93-full" endterm="OLSON93">, |
||||
and |
||||
<xref linkend="SESHADRI95-full" endterm="SESHADRI95"> |
||||
for more information. |
||||
</para> |
||||
</note> |
||||
|
||||
<para> |
||||
A <firstterm>partial index</firstterm> |
||||
is an index built over a subset of a table; the subset is defined by |
||||
a predicate. <productname>Postgres</productname> |
||||
supported partial indices with arbitrary |
||||
predicates. I believe IBM's db2 for as/400 supports partial indices |
||||
using single-clause predicates. |
||||
</para> |
||||
|
||||
<para> |
||||
The main motivation for partial indices is this: |
||||
if all of the queries you ask that can |
||||
profitably use an index fall into a certain range, why build an index |
||||
over the whole table and suffer the associated space/time costs? |
||||
|
||||
(There are other reasons too; see |
||||
<xref endterm="STON89b" linkend="STON89b-full"> for details.) |
||||
</para> |
||||
|
||||
<para> |
||||
The machinery to build, update and query partial indices isn't too |
||||
bad. The hairy parts are index selection (which indices do I build?) |
||||
and query optimization (which indices do I use?); i.e., the parts |
||||
that involve deciding what predicate(s) match the workload/query in |
||||
some useful way. For those who are into database theory, the problems |
||||
are basically analogous to the corresponding materialized view |
||||
problems, albeit with different cost parameters and formulae. These |
||||
are, in the general case, hard problems for the standard ordinal |
||||
<acronym>SQL</acronym> |
||||
types; they're super-hard problems with black-box extension types, |
||||
because the selectivity estimation technology is so crude. |
||||
</para> |
||||
|
||||
<para> |
||||
Check <xref endterm="STON89b" linkend="STON89b-full">, |
||||
<xref endterm="OLSON93" linkend="OLSON93-full">, |
||||
and |
||||
<xref endterm="SESHADRI95" linkend="SESHADRI95-full"> |
||||
for more information. |
||||
</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: |
||||
--> |
||||
|
@ -0,0 +1,104 @@ |
||||
<chapter id="lisp"> |
||||
<title id="lisp-title">Lisp Programming Interface</title> |
||||
|
||||
<abstract> |
||||
<para> |
||||
<filename>pg.el</filename> is a socket-level interface to |
||||
<productname>Postgres</productname> for emacs. |
||||
</para> |
||||
</abstract> |
||||
|
||||
<note> |
||||
<title>Author</title> |
||||
<para> |
||||
Written by |
||||
<ulink url="mailto:emarsden@mail.dotcom.fr">Eric Marsden</ulink> |
||||
on 21 Jul 1999. |
||||
</para> |
||||
</note> |
||||
|
||||
<para> |
||||
<filename>pg.el</filename> is a socket-level interface to |
||||
<productname>Postgres</productname> for emacs (text |
||||
editor extraordinaire). The module is capable of type coercions from a |
||||
range of SQL types to the equivalent Emacs Lisp type. It currently |
||||
supports neither crypt or Kerberos authentication, nor large objects. |
||||
</para> |
||||
|
||||
<para> |
||||
The code (version 0.2) is available under GNU GPL from |
||||
<ulink url="http://www.chez.com/emarsden/downloads/pg.el"> |
||||
http://www.chez.com/emarsden/downloads/pg.el</ulink> |
||||
</para> |
||||
|
||||
<para> |
||||
Changes since last release: |
||||
|
||||
<itemizedlist mark="bullet" spacing="compact"> |
||||
<listitem> |
||||
<para> |
||||
now works with XEmacs (tested with Emacs 19.34 & 20.2, and XEmacs |
||||
20.4) |
||||
</para> |
||||
</listitem> |
||||
|
||||
<listitem> |
||||
<para> |
||||
added functions to provide database metainformation (list of |
||||
databases, of tables, of columns) |
||||
</para> |
||||
</listitem> |
||||
|
||||
<listitem> |
||||
<para> |
||||
arguments to `pg:result' are now :keywords |
||||
</para> |
||||
</listitem> |
||||
|
||||
<listitem> |
||||
<para> |
||||
MULE-resistant |
||||
</para> |
||||
</listitem> |
||||
|
||||
<listitem> |
||||
<para> |
||||
more self-testing code |
||||
</para> |
||||
</listitem> |
||||
</itemizedlist> |
||||
</para> |
||||
|
||||
<para> |
||||
Please note that this is a programmer's API, and doesn't provide any |
||||
form of user interface. Example: |
||||
|
||||
<programlisting> |
||||
(defun demo () |
||||
(interactive) |
||||
(let* ((conn (pg:connect "template1" "postgres" "postgres")) |
||||
(res (pg:exec conn "SELECT * from scshdemo WHERE a = 42"))) |
||||
(message "status is %s" (pg:result res :status)) |
||||
(message "metadata is %s" (pg:result res :attributes)) |
||||
(message "data is %s" (pg:result res :tuples)) |
||||
(pg:disconnect conn))) |
||||
</programlisting> |
||||
</para> |
||||
</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: |
||||
--> |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue