Home Explore Blog CI



postgresql

15th chunk of `doc/src/sgml/ddl.sgml`
9de525f191a30914ca96f840c5eedb05f86f95f85fa0e0000000000100000fa3
 constraint to be the same table; this is called
    a <firstterm>self-referential</firstterm> foreign key.  For
    example, if you want rows of a table to represent nodes of a tree
    structure, you could write
<programlisting>
CREATE TABLE tree (
    node_id integer PRIMARY KEY,
    parent_id integer REFERENCES tree,
    name text,
    ...
);
</programlisting>
    A top-level node would have NULL <structfield>parent_id</structfield>,
    while non-NULL <structfield>parent_id</structfield> entries would be
    constrained to reference valid rows of the table.
   </para>

   <para>
    A table can have more than one foreign key constraint.  This is
    used to implement many-to-many relationships between tables.  Say
    you have tables about products and orders, but now you want to
    allow one order to contain possibly many products (which the
    structure above did not allow).  You could use this table structure:
<programlisting>
CREATE TABLE products (
    product_no integer PRIMARY KEY,
    name text,
    price numeric
);

CREATE TABLE orders (
    order_id integer PRIMARY KEY,
    shipping_address text,
    ...
);

CREATE TABLE order_items (
    product_no integer REFERENCES products,
    order_id integer REFERENCES orders,
    quantity integer,
    PRIMARY KEY (product_no, order_id)
);
</programlisting>
    Notice that the primary key overlaps with the foreign keys in
    the last table.
   </para>

   <indexterm>
    <primary>CASCADE</primary>
    <secondary>foreign key action</secondary>
   </indexterm>

   <indexterm>
    <primary>RESTRICT</primary>
    <secondary>foreign key action</secondary>
   </indexterm>

   <para>
    We know that the foreign keys disallow creation of orders that
    do not relate to any products.  But what if a product is removed
    after an order is created that references it?  SQL allows you to
    handle that as well.  Intuitively, we have a few options:
    <itemizedlist spacing="compact">
     <listitem><para>Disallow deleting a referenced product</para></listitem>
     <listitem><para>Delete the orders as well</para></listitem>
     <listitem><para>Something else?</para></listitem>
    </itemizedlist>
   </para>

   <para>
    To illustrate this, let's implement the following policy on the
    many-to-many relationship example above: when someone wants to
    remove a product that is still referenced by an order (via
    <literal>order_items</literal>), we disallow it.  If someone
    removes an order, the order items are removed as well:
<programlisting>
CREATE TABLE products (
    product_no integer PRIMARY KEY,
    name text,
    price numeric
);

CREATE TABLE orders (
    order_id integer PRIMARY KEY,
    shipping_address text,
    ...
);

CREATE TABLE order_items (
    product_no integer REFERENCES products <emphasis>ON DELETE RESTRICT</emphasis>,
    order_id integer REFERENCES orders <emphasis>ON DELETE CASCADE</emphasis>,
    quantity integer,
    PRIMARY KEY (product_no, order_id)
);
</programlisting>
   </para>

   <para>
    The default <literal>ON DELETE</literal> action is <literal>ON DELETE NO
    ACTION</literal>; this does not need to be specified.  This means that the
    deletion in the referenced table is allowed to proceed.  But the
    foreign-key constraint is still required to be satisfied, so this
    operation will usually result in an error.  But checking of foreign-key
    constraints can also be deferred to later in the transaction (not covered
    in this chapter).  In that case, the <literal>NO ACTION</literal> setting
    would allow other commands to <quote>fix</quote> the situation before the
    constraint is checked, for example by inserting another suitable row into
    the referenced table or by deleting the now-dangling rows from the
    referencing table.
   </para>

   <para>
    <literal>RESTRICT</literal> is a stricter setting than <literal>NO
    ACTION</literal>.  It prevents deletion of a referenced row.
    <literal>RESTRICT</literal> does

Title: Self-Referential Foreign Keys, Many-to-Many Relationships, and ON DELETE Actions
Summary
This section explains self-referential foreign keys, where a table references itself, often used for hierarchical data like tree structures. It then discusses using multiple foreign keys to implement many-to-many relationships, using a 'products', 'orders', and 'order_items' example. The section introduces the concept of handling deletions in referenced tables using 'ON DELETE' actions. It illustrates 'ON DELETE RESTRICT' (disallowing deletion if referenced) and 'ON DELETE CASCADE' (deleting referencing rows). It also discusses the default 'ON DELETE NO ACTION' and the stricter 'RESTRICT' options, explaining how they behave with deferred constraint checking.