Thread: Foreign keys/unique values and views

Foreign keys/unique values and views

From
Einar Karttunen
Date:
Hi

I was wondering whether there is anyway to use unique values in views.
If I create a view it drops all unique definitions. Is it possible
to reference a view with a foreign key?

for example:
>test=# CREATE TABLE ex1 (c1 int PRIMARY KEY);
>NOTICE:  CREATE TABLE/PRIMARY KEY will create implicit index 'ex1_pkey'
>for table 'ex1'
>CREATE
>test=# CREATE TABLE ex2 (c2 int,col char[4]);
>CREATE
>test=# CREATE VIEW v AS SELECT * FROM ex1, ex2 WHERE c1=c2;
>CREATE
>test=# \d v
>               View "v"
> Attribute |      Type      | Modifier
>-----------+----------------+----------
> c1        | integer        |
> c2        | integer        |
> col       | character(1)[] |
>View definition: SELECT ex1.c1, ex2.c2, ex2.col FROM ex1, ex2 WHERE
>(ex1.c1 = ex2.c2);
c1 is here not unique!

- Einar Karttunen








Re: Foreign keys/unique values and views

From
"Richard Huxton"
Date:
From: "Einar Karttunen" <ekarttun@cs.Helsinki.FI>

> Hi
>
> I was wondering whether there is anyway to use unique values in views.
> If I create a view it drops all unique definitions. Is it possible
> to reference a view with a foreign key?

With a read-only view the data will reflect the underlying tables, so no
problem there. If you make a view updatable with your own triggers then what
happens on an update/insert is up to you. Regardless, the constraints on
underlying tables should be respected anyway.

I have to admit I've never tried referencing a view with a foreign key. I
don't know if it's possible and I have to admit the idea makes me
uncomfortable. Can't give a good reason why, but I'd apply constraints at
the table level.

> for example:
> >test=# CREATE TABLE ex1 (c1 int PRIMARY KEY);
> >NOTICE:  CREATE TABLE/PRIMARY KEY will create implicit index 'ex1_pkey'
> >for table 'ex1'
> >CREATE
> >test=# CREATE TABLE ex2 (c2 int,col char[4]);
> >CREATE
> >test=# CREATE VIEW v AS SELECT * FROM ex1, ex2 WHERE c1=c2;
> >CREATE
> >test=# \d v
> >               View "v"
> > Attribute |      Type      | Modifier
> >-----------+----------------+----------
> > c1        | integer        |
> > c2        | integer        |
> > col       | character(1)[] |
> >View definition: SELECT ex1.c1, ex2.c2, ex2.col FROM ex1, ex2 WHERE
> >(ex1.c1 = ex2.c2);
> c1 is here not unique!

No - because you've made a join between ex1 and ex2. If ex2 contains
duplicate values of c2 then you'll get multiple lines in the view.

A view is nothing more than a "pre-rolled" query. If you only want one line
for every value of c1 you need to design your query accordingly:

CREATE VIEW v AS SELECT c1,min(c2),min(col) FROM ex1,ex2 WHERE c1=c2 GROUP
BY c1;

Or similar, depending on what you are after.

- Richard Huxton


Re: Foreign keys/unique values and views

From
Einar Karttunen
Date:
On Thu, 22 Mar 2001, Richard Huxton wrote:
>
> I have to admit I've never tried referencing a view with a foreign key. I
> don't know if it's possible and I have to admit the idea makes me
> uncomfortable. Can't give a good reason why, but I'd apply constraints at
> the table level.
if one can reference a table with a foreign key it makes possible to
reference inheritance hierarchies. If I create a view from the parent
with CREATE VIEW name SELECT * FROM parent; (in v.7.1) it should contain
the entries from the children as well. Now if I could reference this view
I could simulate referencing parent and child tables easily.
What I have in mind is a hierarchy of persons all inheriting from a table
called person. Different kinds of persons have different attributes but
all have an id and name. What I want is that other tables could reference
these persons easily.

- Einar Karttunen



Re: Foreign keys/unique values and views

From
Stephan Szabo
Date:
On Thu, 22 Mar 2001, Einar Karttunen wrote:

> On Thu, 22 Mar 2001, Richard Huxton wrote:
> >
> > I have to admit I've never tried referencing a view with a foreign key. I
> > don't know if it's possible and I have to admit the idea makes me
> > uncomfortable. Can't give a good reason why, but I'd apply constraints at
> > the table level.
> if one can reference a table with a foreign key it makes possible to
> reference inheritance hierarchies. If I create a view from the parent
> with CREATE VIEW name SELECT * FROM parent; (in v.7.1) it should contain
> the entries from the children as well. Now if I could reference this view
> I could simulate referencing parent and child tables easily.
> What I have in mind is a hierarchy of persons all inheriting from a table
> called person. Different kinds of persons have different attributes but
> all have an id and name. What I want is that other tables could reference
> these persons easily.

Currently the reltype of the referenced thing has to be a table, plus I
don't think you can currently put a unique constraint on views either
which would be a prerequisite.

The reason for this is precisely the kind of thing you're trying to do.
The system doesn't currently know enough to be able to do this.  With the
triggers, we'd have to add triggers to the parent and children table for
update and delete, but we'd have to know what they were, and if you
inherit a new table, that one would need it to.  Plus, what if the
view has where clauses, etc, you have to work out when you would need
to limit things, etc.  If we ever do enough stuff to allow generic
updatable views (beyond really simple ones), we'd probably be able to do
this, but until then...



Re: Foreign keys/unique values and views

From
"Richard Huxton"
Date:
From: "Einar Karttunen" <ekarttun@cs.Helsinki.FI>

> On Thu, 22 Mar 2001, Richard Huxton wrote:
> >
> > I have to admit I've never tried referencing a view with a foreign key.
I
> > don't know if it's possible and I have to admit the idea makes me
> > uncomfortable. Can't give a good reason why, but I'd apply constraints
at
> > the table level.
> if one can reference a table with a foreign key it makes possible to
> reference inheritance hierarchies. If I create a view from the parent
> with CREATE VIEW name SELECT * FROM parent; (in v.7.1) it should contain
> the entries from the children as well. Now if I could reference this view
> I could simulate referencing parent and child tables easily.
> What I have in mind is a hierarchy of persons all inheriting from a table
> called person. Different kinds of persons have different attributes but
> all have an id and name. What I want is that other tables could reference
> these persons easily.

Ah - makes sense. I must admit I don't use inheritence/arrays since I never
know what platform I'll end up running on, so I like to keep things to
standard SQL where possible.

Trying the obvious (reference an id field in the parent) fails on execution:
  referential integrity violation - key referenced from bar not found in
foo_parent

You also can't reference the id field in the child table.

There's a question on this on the pgsql-sql list (from Johannes Groden -
dated today) but I don't see any replies yet. This sounds like something
Tom/Bruce will need to get involved in.

- Richard Huxton


Re: Foreign keys/unique values and views

From
Jan Wieck
Date:
Einar Karttunen wrote:
> On Thu, 22 Mar 2001, Richard Huxton wrote:
> >
> > I have to admit I've never tried referencing a view with a foreign key. I
> > don't know if it's possible and I have to admit the idea makes me
> > uncomfortable. Can't give a good reason why, but I'd apply constraints at
> > the table level.
> if one can reference a table with a foreign key it makes possible to
> reference inheritance hierarchies. If I create a view from the parent
> with CREATE VIEW name SELECT * FROM parent; (in v.7.1) it should contain
> the entries from the children as well. Now if I could reference this view
> I could simulate referencing parent and child tables easily.
> What I have in mind is a hierarchy of persons all inheriting from a table
> called person. Different kinds of persons have different attributes but
> all have an id and name. What I want is that other tables could reference
> these persons easily.

    Inheritance  isn't  supported  in  FOREIGN  KEY,  and cannot.
    Remember that it's not only the check if the  referenced  key
    exists  on FK insert and update. FOREIGN KEY ensures that you
    cannot remove those PKs or has automated actions defined  for
    that  case.  We don't have trigger inheritance. And since one
    of the requirements of FOREIGN KEY is that you have a  UNIQUE
    constraint  on your PK, this cannot be done with FOREIGN KEY.
    How do you put a UNIQUE constraint on the entire  inheritance
    hierarchie?

    You  can  create  custom triggers that check for whatever you
    want.  But FOREIGN KEY has  to  follow  the  SQL  specs.  All
    things fit together, if one doesn't fit, don't force it - use
    a bigger hammer. We have  sledge  hammers  available  in  all
    sizes :-)


Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #



_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com


Re: Foreign keys/unique values and views

From
Martijn van Oosterhout
Date:
On Thu, Mar 22, 2001 at 06:33:16PM -0500, Jan Wieck wrote:
> Einar Karttunen wrote:
>     How do you put a UNIQUE constraint on the entire  inheritance
>     hierarchie?

Easy. You make a unique index that covers an entire inheritance hierarchy.
If lots of table inherit a field "id" from a single table the you can put a
unique index on that field. All you need then is an index whose keys
reference not tuple IDs but (table ID, tuple ID) pairs.

Wow. I'm just thinking of how vacuum would deal with this. Probably not very
well. But it would give inheritance hierarchies very efficient lookups
rather than the implicit unioning done currently.

Martijn