Thread: Foreign keys and inheritance

Foreign keys and inheritance

From
"Pierre Thibaudeau"
Date:
I thought I had understood the question of primary key and foreign keys in the context of inheritance, but it seems I don't, and I would appreciate some light over this situation.  Here's the setup:

I have a parent table entitled "generic", composed of a SERIAL primary key "id" plus a few other columns, one of which is a not-null character-type entitled "kind".  The possible values of "kind" are constrained to be only 'a' or 'b'.

Table "generic" has two children:  "child_a" and "child_b".  In "child_a", the column "kind" is constrained to be 'a';  in "child_b", the value of "kind" is constrained to 'b'.  The two children differ slightly in the structure of the columns that aren't part of their "generic" parent.  Moreover, all the tuples of "generic" have to belong to either "child_a" or "child_b".  (In other words, any tuple appearing in "generic" has been inserted in either "child_a" or "child_b".)

In parallel with all that, I have another table "family" containing an attribute which references (as foreign key) the "id" of table "generic".  You see, "family" isn't really bothered to know whether it is referencing a tuple in "child_a" or one in "child_b":  if we need to access the extra columns proper to the children, we'll do that at a later stage...

However, Postgres isn't too happy about that:  when, in cousin, I insert a reference to a tuple of "generic", I am told:

ERROR: insert or update on table "cousin" violates foreign key constraint "cousin_generic_fkey"
DETAILS: Key (family_relative)=(5) is not present in table "generic"

All the while, a SELECT on "generic" will give something like:

 id | kind | reliability
----+------+-------------
 4  | b    | 2
 5  | a    | 8

In other words, although the tuple with id=5 appears in the SELECT query, it seems that Postgres would rather I referenced it inside "child_a" rather than inside "generic". All along, I had been under the impression that a tuple belonging to a child automatically belongs to the parent, yet I wouldn't be able to reference that tuple???

Is that normal behaviour?  Can I relax the foreign key constraint so as to be able to reference any item within "generic", whether the tuple originally came from "generic" or from one of its children?

(Running PostgreSQL v.8.1.3 on WindowsXP.)

Re: Foreign keys and inheritance

From
Richard Broersma Jr
Date:
 All along, I had been under the impression that a
> tuple belonging to a child automatically belongs to the parent, yet I
> wouldn't be able to reference that tuple???

I was under the same impression also.  However, I didn't take any time to play with inherited
tables as I wanted to relate two child tables together via a relate table.  The docs explicitly
same that currently this isn't possible. (However, it is on the to-do list for 8.2 :-D. I am
really excited about that.  It should be added as long as it doesn't get pushed aside for more
important additions.)

However, if I interpret the docs correctly, could make sense that relation breaks down because the
tuple only appears to be in the parent table when you select * from parent;.

Notice the use of the Key work ONLY in the snippet of the 8.1.3 postgres document:

   In PostgreSQL, a table can inherit from zero
   or more other tables, and a query can reference
   either all rows of a table or all rows of a
   table plus all of its descendant tables. The
   latter behavior is the default. For example,
   the following query finds the names of all
   cities, including state capitals, that are
   located at an altitude over 500ft:

  SELECT name, altitude
      FROM cities
      WHERE altitude > 500;
   Given the sample data from the PostgreSQL
   tutorial (see Section 2.1),   this returns:

     name    | altitude
  -----------+----------
   Las Vegas |     2174
   Mariposa  |     1953
   Madison   |      845
   On the other hand, the following query finds
   all the cities that are not state capitals
   and are situated at an altitude over 500ft:

  SELECT name, altitude
      FROM ONLY cities
      WHERE altitude > 500;

     name    | altitude
  -----------+----------
   Las Vegas |     2174
   Mariposa  |     1953
  Here the ONLY keyword indicates that the query
  should apply only to cities, and not any tables
  below cities in the inheritance hierarchy. Many
  of the commands that we have already discussed
  — SELECT, UPDATE and DELETE — support the ONLY
  keyword.



If I was to take a guess why the relation breaks,  It would be that the table inheritance really
only works like a union query on two tables.  So in reality, the parent table may not really have
the child's tuple in it.


>
> Is that normal behaviour?  Can I relax the foreign key constraint so as to
> be able to reference any item within "generic", whether the tuple originally
> came from "generic" or from one of its children?
>
> (Running PostgreSQL v.8.1.3 on WindowsXP.)
>

I was able to emulate inherited tables using one parent table and two child tables. The child
table linked to the parent table with unique foriforeigns.  To simplify the insertion and
selection of the two child and parent tables it made use of two insert-able, update-able,
delete-able views.

This gives me full control and allows me to create relations on any of the tables.  The down side
is that this schema is labor intensive.

Regards,

Richard Broersma


Re: Foreign keys and inheritance

From
Michael Glaesemann
Date:
On Apr 7, 2006, at 14:37 , Richard Broersma Jr wrote:

> I was under the same impression also.  However, I didn't take any
> time to play with inherited
> tables as I wanted to relate two child tables together via a relate
> table.  The docs explicitly
> same that currently this isn't possible. (However, it is on the to-
> do list for 8.2 :-D.

Not to dampen your excitement, but the todo list at
http://www.postgresql.org/docs/faqs.TODO.html
is for *all* todos, those being implemented for 8.2 and those that
people have thought might be nice but haven't done any work on.
Unless something's already been committed to head, or you see
something on the patch list (or are submitting a patch
yourself? :) ), there's no guarantee that anything on the todo list
will be in 8.2. (Or did I miss something? I've been known to.)

Patches welcome  :)

Michael Glaesemann
grzm myrealbox com