Every table has several system columns that are
implicitly defined by the system. Therefore, these names cannot be
used as names of user-defined columns. (Note that these
restrictions are separate from whether the name is a key word or
not; quoting a name will not allow you to escape these
restrictions.) You do not really need to be concerned about these
columns, just know they exist.
The object identifier (object ID) of a row. This is a serial
number that is automatically added by
PostgreSQL to all table rows (unless
the table was created WITHOUT OIDS, in which
case this column is not present). This column is of type
oid (same name as the column); see Section 5.10 for more information about the type.
The OID of the table containing this row. This attribute is
particularly handy for queries that select from inheritance
hierarchies, since without it, it's difficult to tell which
individual table a row came from. The
tableoid can be joined against the
oid column of
pg_class to obtain the table name.
The identity (transaction ID) of the inserting transaction for
this tuple. (Note: In this context, a tuple is an individual
state of a row; each update of a row creates a new tuple for the
same logical row.)
The command identifier (starting at zero) within the inserting
The identity (transaction ID) of the deleting transaction, or
zero for an undeleted tuple. It is possible for this field to
be nonzero in a visible tuple: That usually indicates that the
deleting transaction hasn't committed yet, or that an attempted
deletion was rolled back.
The command identifier within the deleting transaction, or zero.
The physical location of the tuple within its table. Note that
although the ctid can be used to
locate the tuple very quickly, a row's
ctid will change each time it is
updated or moved by VACUUM FULL. Therefore
ctid is useless as a long-term row
identifier. The OID, or even better a user-defined serial
number, should be used to identify logical rows.