Thoughts on a surrogate key lookup function?

From: Nick <nboutelier(at)gmail(dot)com>
To: pgsql-general(at)postgresql(dot)org
Subject: Thoughts on a surrogate key lookup function?
Date: 2010-11-05 21:27:16
Message-ID: 5d5e5ae4-aa15-421c-b9a0-2bad52e9281a@f8g2000yqn.googlegroups.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Are there any existing trigger functions (preferably C) that could
retrieve a missing value for a compound foreign key on insert or
update? If this overall sounds like a really bad idea, please let me
know as well. This functionality could really speed my project up
though.

For example,

CREATE TABLE email_addresses (id BIGSERIAL, email_address VARCHAR);
ALTER TABLE email_addresses ADD CONSTRAINT _email_addresses_pkey
PRIMARY KEY (id,email_address);
CREATE TABLE users (id BIGSERIAL, email_address_id BIGINT,
email_address VARCHAR);
ALTER TABLE users ADD CONSTRAINT users_fkey_email_address_id FOREIGN
KEY (email_address_id,email_address) REFERENCES
email_addresses(id,email_address) ON UPDATE CASCADE ON DELETE SET
NULL;
CREATE TRIGGER "1-auto_email_address_id" BEFORE INSERT OR UPDATE ON
users FOR EACH ROW EXECUTE PROCEDURE _auto_id('email_address_id');

If I would like to insert a new user AND new email_address I would
assign the email_address_id of NULL or -1.

INSERT INTO users (id, email_address_id, email_address) VALUES
(1,-1,'foo(at)bar(dot)com') which would do...

SELECT id FROM email_addresses WHERE email_address = 'foo(at)bar(dot)com'
INTO NEW.email_address_id

If it cannot find a value, it then does...

INSERT INTO email_addresses (email_address) VALUES ('foo(at)bar(dot)com')
RETURNING id INTO NEW.email_address_id

If I would like to insert a new user and existing email address, I
would assign the email_address_id of 0.

INSERT INTO users (id, email_address_id, email_address) VALUES
(2,0,'foo(at)bar(dot)com') which would...

SELECT id FROM email_addresses WHERE email_address = 'foo(at)bar(dot)com'
INTO NEW.email_address_id

If it cannot find a value, it will raise an exception.

If I insert or update users and email_address_id is > 0 then it gets
the natual value by id...

INSERT INTO users (id, email_address_id, email_address) VALUES
(3,2,NULL) which will

SELECT email_address FROM email_addresses WHERE id = 2 INTO
NEW.email_address

And if both email_address_id and email_address are NULL then, both
values just get inserted into users as null.

Declaring the surrogate as -1 (select or insert) or 0 (select) would
save time having to lookup or create the value before inserting into
users. Ive been using a plperl function for this and really like the
results but im wondering if theres a faster way.

The foreign key constraint already scans the email_addresses table for
values so im wondering if theres a way to bootstrap that process or
maybe thats too risky? Any thoughts would be greatly appreciated.

Responses

Browse pgsql-general by date

  From Date Subject
Next Message mike stanton 2010-11-05 21:40:40 Re: Access postgresql data base from .net
Previous Message Scott Marlowe 2010-11-05 21:05:03 Re: Linux