Thread: Referencing a view?

Referencing a view?

From
"James Orr"
Date:
Hi,
 
Is there anyway that you can reference a column in a view for referential integrity?  The problem is with the unique thing, obviously I can't create a unique index on a view.  Here is what I have:

CREATE SEQUENCE "addresses_id_seq" start 1 increment 1 maxvalue 2147483647 minvalue 1  cache 1 ;
 
CREATE TABLE "org_addresses" (
 "id" integer DEFAULT nextval('addresses_id_seq'::text) NOT NULL,
 "orgid" integer references orgs on delete cascade,
 "name" character varying(255),
 "street1" character varying(255),
 "street2" character varying(100),
 "city" character varying(100),
 "state" character(2),
 "zip" character(10),
 Constraint "org_addresses_pkey" Primary Key ("id")
);
 
CREATE TABLE "user_addresses" (
 "id" integer DEFAULT nextval('addresses_id_seq'::text) NOT NULL,
 "userid" integer references users on delete cascade,
 "name" character varying(255),
 "street1" character varying(255),
 "street2" character varying(100),
 "city" character varying(100),
 "state" character(2),
 "zip" character(10),
 Constraint "user_addresses_pkey" Primary Key ("id")
);
 
CREATE VIEW "addresses" as SELECT user_addresses.id, user_addresses.userid, user_addresses.name, user_addresses.street1, user_addresses.street2, user_addresses.city, user_addresses.state, user_addresses.zip FROM user_addresses UNION SELECT org_addresses.id, NULL::unknown, org_addresses.name, org_addresses.street1, org_addresses.street2, org_addresses.city, org_addresses.state, org_addresses.zip FROM org_addresses;
So this gives me a view with every address, each with a unique id as I used the same sequence in both tables.  Now what I want to do is something like this :
 
CREATE TABLE orders (
    id serial primary key,
    shipping_address int references addresses(id),
.
.
);
 
Which of course doesn't work because addresses as a view can't have a unique index.  Any way around this?
 
- James

Re: Referencing a view?

From
Stephan Szabo
Date:
On Thu, 12 Jul 2001, James Orr wrote:

> Hi,
> 
> Is there anyway that you can reference a column in a view for
> referential integrity?  The problem is with the unique thing,
> obviously I can't create a unique index on a view.  Here is what I
> have:

Not right now, and actually you still wouldn't get something that would
work even with a unique index.  We'd have to be able to push the
constraint conditions down into the two tables that you're unioning to
make it work correctly (think about the triggers on the referenced table
for update and delete - which in your case with a unique index would
be safe to put the triggers on all the time in both, but some view
conditions would be such that that wouldn't be sufficient).

You *might* be able to add the triggers manually and have it work.  I
haven't tried, and wouldn't guarantee it at all...




Re: Referencing a view?

From
"Grigoriy G. Vovk"
Date:
Jul 12, 16:25 -0400, James Orr wrote:

Much better will be change database structure - you have absolutely
identical tables, so is not good from normalization point of view.
Better use one table for address, and link it to one table for
"entity" - both person and company, and "entity" link to specific
information about person and company.
Somathing like this:

create table entity(
id_entity serial not null primary key,
_all_other_fields_,
.........);

create table address(
id_address serial not null primary key,
id_entity integer not null references entity,
_all_other_fields_,
.........);

create table person(
id_entity integer not null primary key references entity,
first_name text,
last_name text,
...........);

create table company(
id_entity integer not null primary key references entity,
company_name text,
........);

It may be usefull to add column 'who_is' boolean in the 'entity' table -
when you will do a search on 'address' table you will get 'id_entity',
and you can do a search on 'entity' table and get 'who_is', and than you
can get other information fom 'person' or 'company' tables.

> Hi,
>
> Is there anyway that you can reference a column in a view for referential integrity?  The problem is with the unique
thing,obviously I can't create a unique index on a view.  Here is what I have:
 
>
> CREATE SEQUENCE "addresses_id_seq" start 1 increment 1 maxvalue 2147483647 minvalue 1  cache 1 ;
>
> CREATE TABLE "org_addresses" (
>  "id" integer DEFAULT nextval('addresses_id_seq'::text) NOT NULL,
>  "orgid" integer references orgs on delete cascade,
>  "name" character varying(255),
>  "street1" character varying(255),
>  "street2" character varying(100),
>  "city" character varying(100),
>  "state" character(2),
>  "zip" character(10),
>  Constraint "org_addresses_pkey" Primary Key ("id")
> );
>
> CREATE TABLE "user_addresses" (
>  "id" integer DEFAULT nextval('addresses_id_seq'::text) NOT NULL,
>  "userid" integer references users on delete cascade,
>  "name" character varying(255),
>  "street1" character varying(255),
>  "street2" character varying(100),
>  "city" character varying(100),
>  "state" character(2),
>  "zip" character(10),
>  Constraint "user_addresses_pkey" Primary Key ("id")
> );
>
> CREATE VIEW "addresses" as SELECT user_addresses.id, user_addresses.userid, user_addresses.name,
user_addresses.street1,user_addresses.street2, user_addresses.city, user_addresses.state, user_addresses.zip FROM
user_addressesUNION SELECT org_addresses.id, NULL::unknown, org_addresses.name, org_addresses.street1,
org_addresses.street2,org_addresses.city, org_addresses.state, org_addresses.zip FROM org_addresses;
 
>
> So this gives me a view with every address, each with a unique id as I used the same sequence in both tables.  Now
whatI want to do is something like this :
 
>
> CREATE TABLE orders (
>     id serial primary key,
>     shipping_address int references addresses(id),
> .
> .
> );
>
> Which of course doesn't work because addresses as a view can't have a unique index.  Any way around this?
>
> - James
>

my best regards,
----------------
Grigoriy G. Vovk



Re: Referencing a view?

From
"James Orr"
Date:
Thanks for all the responses!  The one from Grigoriy was particularly
interesting, I hadn't thought of that approach.

However, I came to the realization that if somebody changes their address, I
don't want it to be changed on previous orders.  So I think i'll change the
orders table to contain the actual address information and use an INSERT ...
SELECT instead.  That way I can be sure I have an accurate record of all
orders.

Thanks!
- James



Re: Referencing a view?

From
"Grigoriy G. Vovk"
Date:
Jul 13, 09:41 -0400, James Orr wrote:

> Thanks for all the responses!  The one from Grigoriy was particularly
> interesting, I hadn't thought of that approach.
>
> However, I came to the realization that if somebody changes their address, I
> don't want it to be changed on previous orders.  So I think i'll change the
> orders table to contain the actual address information and use an INSERT ...
> SELECT instead.  That way I can be sure I have an accurate record of all
> orders.
Yes, its really a problem... When  information sometime changes but we
want to keep old information for depending data. (If I understand correctly
what about you are speaking).
But, you can resolve the problem if will copy information about address
for executed order in a different place as a text, not as a link to the
table 'address'. So, after execution of an order you will take current
address by the link and copy all information (may be, as one field
everything - concat all fields from the address together). Its a one
solution.
Next - you can use many addresses for an entity, and work only with some
of them, 'valid', or 'current', as do you like, not with all.
So, you will have full addresses history - when was changed, etc. And the
order will always links to correct address, even now current address is
different.
You can do it by add field 'current' bool in the table 'address' or
create additional table 'current_address' which will have 'id_entity' and
'id_address', so if you will do a search on 'current_address' you got
a list of current addresses, in case you will do a search on 'address' -
you got a list of all addresses. I prefere to create additional table.
May be I've explained not well - ask, I'll type an database structure
example, for developers it may be easy way :)


my best regards,
----------------
Grigoriy G. Vovk



Re: Referencing a view?

From
"Josh Berkus"
Date:
James,

> However, I came to the realization that if somebody changes their
> address, I
> don't want it to be changed on previous orders.  So I think i'll
> change the
> orders table to contain the actual address information and use an
> INSERT ...
> SELECT instead.  That way I can be sure I have an accurate record of
> all
> orders.

Hey, if you really want to be sophisticated about it, you should have
multiple addresses per customer, with perhaps a status selector to
indicate which addresses are new and which are old.  For my current
Postgres app, it goes futher than that to support companies with many
contacts and locations:



Company              Address              Contact
. CompanyID -----------CompanyID------------CompanyID
. Name                 AddressID------------AddressID
.                      Status/Type          Status/Type
.                      Address              Name, Title


This allows me to have mutliple addresses per company (including old
addresses for historical compatibility) and multiple contacts at each
address.  There's also an elegant (at least I think so) way to maintain
a "default" contact and address for each company.

Of course, this all requires some sophistication in the user interface,
as one has to make the user distinguish between address corrections
(UPDATE) and new addresses (INSERT) which possibly replace old addresses
(UPDATE SET STATUS = old).

-Josh Berkus



______AGLIO DATABASE SOLUTIONS___________________________
                                       Josh Berkus
  Complete information technology      josh@agliodbs.com
   and data management solutions       (415) 565-7293
  for law firms, small businesses        fax 621-2533
    and non-profit organizations.      San Francisco

Attachment