Thread: REFERENCES constraint
Two questions (maybe they are silly..) 1. Can a column reference more than one table? (This assumes you use a single sequence to generate the IDs for both "tbla" and "tblb". I guess you would also have the problem of enforcing a unique index. Say what?! A unique index across multiple tables.. absurd :) eg.. CREATE TABLE blah ( id int4, f_id int4 REFERENCES tbla (id) REFERENCES tblb (id) ) 2. Can a column reference another column in the same table? eg.. CREATE TABLE bloo ( id int4, p_id int4 REFERENCES bloo (id) -- or --p_id int4 REFERENCES (id) ) I'm guessing the answer is no, in which case I have to fall back to writing custom PL/ functions and triggers. Just thought I'd ask anyway. It would be nice if it were this easy though... -Cedar p.s. please CC my on this thread.. I'm on vacation (on this list) :0
Cedar, > 1. Can a column reference more than one table? (This assumes you use > a > single sequence to generate the IDs for both "tbla" and "tblb". I > guess > you would also have the problem of enforcing a unique index. Say > what?! > A unique index across multiple tables.. absurd :) eg.. > > CREATE TABLE blah ( > id int4, > f_id int4 REFERENCES tbla (id) REFERENCES tblb (id) > ) I'd reccomend, instead, having blah reference tbla and tbla reference tblb. It'd have the same effect, without forcing you to monkey around with custom triggers. > 2. Can a column reference another column in the same table? eg.. > > CREATE TABLE bloo ( > id int4, > p_id int4 REFERENCES bloo (id) > -- or > --p_id int4 REFERENCES (id) > ) Er ... why would you want to? -Josh Berkus ______AGLIO DATABASE SOLUTIONS___________________________ Josh Berkus Complete informationtechnology josh@agliodbs.com and data management solutions (415) 565-7293 for law firms, small businesses fax 621-2533 and non-profit organizations. San Francisco
Cedar, (sorry for the double posting, folks) > 2. Can a column reference another column in the same table? eg.. > > CREATE TABLE bloo ( > id int4, > p_id int4 REFERENCES bloo (id) > -- or > --p_id int4 REFERENCES (id) > ) You don't do this with REFERENCES ... you do it with a CHECK CONSTRAINT (look it up in the docs). -Josh Berkus ______AGLIO DATABASE SOLUTIONS___________________________ Josh Berkus Complete informationtechnology josh@agliodbs.com and data management solutions (415) 565-7293 for law firms, small businesses fax 621-2533 and non-profit organizations. San Francisco
As for me it is looking as not good normalized structure. After normalization should not be any questions, I think... Aug 8, 19:02 +0300, Cedar Cox wrote: > > Two questions (maybe they are silly..) > > 1. Can a column reference more than one table? (This assumes you use a > single sequence to generate the IDs for both "tbla" and "tblb". I guess > you would also have the problem of enforcing a unique index. Say what?! > A unique index across multiple tables.. absurd :) eg.. > > CREATE TABLE blah ( > id int4, > f_id int4 REFERENCES tbla (id) REFERENCES tblb (id) > ) > > 2. Can a column reference another column in the same table? eg.. > > CREATE TABLE bloo ( > id int4, > p_id int4 REFERENCES bloo (id) > -- or > --p_id int4 REFERENCES (id) > ) > > I'm guessing the answer is no, in which case I have to fall back to > writing custom PL/ functions and triggers. Just thought I'd ask anyway. > It would be nice if it were this easy though... > > -Cedar > p.s. please CC my on this thread.. I'm on vacation (on this list) :0 > > > ---------------------------(end of broadcast)--------------------------- > TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org > my best regards, ---------------- Grigoriy G. Vovk
Josh Berkus wrote: > Cedar, > > > 1. Can a column reference more than one table? (This assumes you use > > a > > single sequence to generate the IDs for both "tbla" and "tblb". I > > guess > > you would also have the problem of enforcing a unique index. Say > > what?! > > A unique index across multiple tables.. absurd :) eg.. > > > > CREATE TABLE blah ( > > id int4, > > f_id int4 REFERENCES tbla (id) REFERENCES tblb (id) > > ) > > I'd reccomend, instead, having blah reference tbla and tbla reference > tblb. It'd have the same effect, without forcing you to monkey around > with custom triggers. Nobody said that primary keys are limited to the serial datatype. So in case that tbla and tblb could have different sets of keys with a possible intersection, and further given that blah.f_id shall be limited to values both have in common, there's no other way than having multiple foreign key constraints on that one column. Thus, it is possible. I'm not sure if the above syntax is supported, but at least you can put table level CONSTRAINT clauses into the statement and/or add the constraints later with ALTER TABLE. > > > 2. Can a column reference another column in the same table? eg.. > > > > CREATE TABLE bloo ( > > id int4, > > p_id int4 REFERENCES bloo (id) > > -- or > > --p_id int4 REFERENCES (id) > > ) > > Er ... why would you want to? To build a tree structure of nodes. Root nodes have p_id (meaning parent-id I guess) set to NULL, all others musthave an existing node as parent. Together with ON DELETE CASCADE it'd build an expert-directory-structure (experts usually have "alias rm='/bin/rm -rf'" in their .profile, you know). Again, since it makes sense it is possible. 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
On Wed, 8 Aug 2001, Cedar Cox wrote: > > Two questions (maybe they are silly..) > > 1. Can a column reference more than one table? (This assumes you use a > single sequence to generate the IDs for both "tbla" and "tblb". I guess > you would also have the problem of enforcing a unique index. Say what?! > A unique index across multiple tables.. absurd :) eg.. > > CREATE TABLE blah ( > id int4, > f_id int4 REFERENCES tbla (id) REFERENCES tblb (id) > ) Yes, you should be able to do this, but it won't do what you want, it'll make it be required in both tables. You'll need to do this one by hand. > 2. Can a column reference another column in the same table? eg.. > > CREATE TABLE bloo ( > id int4, > p_id int4 REFERENCES bloo (id) > -- or > --p_id int4 REFERENCES (id) > ) Yes, using your first syntax that should work.
On Wed, 8 Aug 2001, Jan Wieck wrote: > Josh Berkus wrote: > > Cedar, > > > > > 1. Can a column reference more than one table? (This assumes you use > > > a > > > single sequence to generate the IDs for both "tbla" and "tblb". I > > > guess > > > you would also have the problem of enforcing a unique index. Say > > > what?! > > > A unique index across multiple tables.. absurd :) eg.. > > > > > > CREATE TABLE blah ( > > > id int4, > > > f_id int4 REFERENCES tbla (id) REFERENCES tblb (id) > > > ) > > > > I'd reccomend, instead, having blah reference tbla and tbla reference > > tblb. It'd have the same effect, without forcing you to monkey around > > with custom triggers. > > Nobody said that primary keys are limited to the serial > datatype. So in case that tbla and tblb could have different > sets of keys with a possible intersection, and further given > that blah.f_id shall be limited to values both have in > common, there's no other way than having multiple foreign key > constraints on that one column. > > Thus, it is possible. I'm not sure if the above syntax is > supported, but at least you can put table level CONSTRAINT > clauses into the statement and/or add the constraints later > with ALTER TABLE. I guess I wasn't clear. Let me try to explain again: CREATE TABLE obj_weights ( object_id int4 REFERENCES ( apple_objects(id) OR banana_objects(id) ) weight float4, ) "apple_objects" doesn't necessarily have anything to do with "banana_objects". Ok, don't ask why you would want to store weights of apples and bananas in the same table.. (and if you know, please tell me). This is all actually for someone else's database that I just picked up. They did something like this.. single sequence for the whole database, multiple object tables, and a table(s) referencing objects that could come from any of those tables. Maybe this is just bad design. Thoughts anyone? > > > 2. Can a column reference another column in the same table? eg.. > > > > > > CREATE TABLE bloo ( > > > id int4, > > > p_id int4 REFERENCES bloo (id) > > > -- or > > > --p_id int4 REFERENCES (id) > > > ) > > > > Er ... why would you want to? > > To build a tree structure of nodes. Root nodes have p_id > (meaning parent-id I guess) set to NULL, all others must have > an existing node as parent. Together with ON DELETE CASCADE Exactly :) Having already done this with custom triggers, I now want to know if there is an "easy" way... -Cedar p.s. please CC me on this thread..
Cedar Cox writes: > CREATE TABLE obj_weights ( > object_id int4 REFERENCES ( apple_objects(id) OR banana_objects(id) ) > weight float4, > ) The way I would work this out is like this: CREATE TABLE fruit_objects ( object_id serial PRIMARY KEY, fruit_type text CHECK (fruit_type IN ('apple', 'banana')), weightfloat4, ... other common fruit properties ... ); CREATE TABLE apple_objects ( object_id integer REFERENCES fruit_objects, color text, ... more apple properties ... ); CREATE TABLE banana_objects ( object_id integer REFERENCES fruit_objects, curvature real, ... other banana properties ... ); -- Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter
Cedar, > I guess I wasn't clear. Let me try to explain again: > > CREATE TABLE obj_weights ( > object_id int4 REFERENCES ( apple_objects(id) OR > banana_objects(id) ) > weight float4, > ) > > "apple_objects" doesn't necessarily have anything to do with > "banana_objects". Ok, don't ask why you would want to store weights > of > apples and bananas in the same table.. (and if you know, please tell > me). > This is all actually for someone else's database that I just picked > up. > They did something like this.. single sequence for the whole > database, > multiple object tables, and a table(s) referencing objects that could > come > from any of those tables. Maybe this is just bad design. Thoughts > anyone? That actually makes a *lot* more sense. In fact, I'm doing the same thing with two tables in my database ... one called "mod_data" and another one called "notes". The first stores modifications users and timestamps for 6 different tables, the second stores scrolling user notes for foure different tables. Thus mod_data should look like: CREATE TABLE mod_data ( usq INT NOT NULL REFERENCES (clients(usq) OR candidates(usq) or orders(usq) or ... ) entry_user INT NOT NULL entry_date TIMESTAMP NOT NULL DEFAULT current_timestamp mod_user INT NOT NULL mod_date TIMESTAMP NOT NULL DEFAULT current_timestamp ) But, as you've observed, this is quite impossible. The entire structure of relationality has been constructed around the heirarchy and/or star topology; there is no provision for this kind of relationship. I can think of a number of good reasons not to attempt to implement REFERENCES for this kind of structure. So you can deal with it as I did: 1. Users have no ability to add or modify records in the child-of-many table. They must push data through functions that I have defined, which take care of creating/updating the dependant records. 2. All major tables subscribe to a single "Univeral Sequence" that supplies unique surrogate keys for the six tables. This makes the ID unique not only within but between the 6 tables. The one disadvantage is that it is a postgresql-only implementation. 3. Users cannot modify this "usq". Nor can they delete records. Thus my DB integrity is protected. In a database where user access is less restrained, you may find that the cost of creating all the triggers necessary to deal with user updates and deletes is a lot more than the effort to duplicate a few tables. An alternate approach is for you to define your own updatable views. While quite labor-intensive, this approach takes care of quite a few complex relationship structures by forcing the users to push their inserts and updates through the views. Properly designed, the user would not even realize that banana_weight and apple_weight are in the same table and are in a different table from banana_data and apple_data. Or, perhaps, as a very advanced user, I'm just making some very advanced mistakes ... -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
cedarc@visionforisrael.com (Cedar Cox) wrote in message news:<Pine.LNX.4.21.0108122137590.11622-100000@nanu.visionforisrael.com>... > On Wed, 8 Aug 2001, Jan Wieck wrote: > > Josh Berkus wrote: > > > Cedar, > > > > > > > 1. Can a column reference more than one table? (This assumes you use > > > > a > > > > single sequence to generate the IDs for both "tbla" and "tblb". I > > > > guess > > > > you would also have the problem of enforcing a unique index. Say > > > > what?! > > > > A unique index across multiple tables.. absurd :) eg.. > > > > > > > > CREATE TABLE blah ( > > > > id int4, > > > > f_id int4 REFERENCES tbla (id) REFERENCES tblb (id) > > > > ) > > > > > > I'd reccomend, instead, having blah reference tbla and tbla reference > > > tblb. It'd have the same effect, without forcing you to monkey around > > > with custom triggers. > > > > Nobody said that primary keys are limited to the serial > > datatype. So in case that tbla and tblb could have different > > sets of keys with a possible intersection, and further given > > that blah.f_id shall be limited to values both have in > > common, there's no other way than having multiple foreign key > > constraints on that one column. > > > > Thus, it is possible. I'm not sure if the above syntax is > > supported, but at least you can put table level CONSTRAINT > > clauses into the statement and/or add the constraints later > > with ALTER TABLE. > > I guess I wasn't clear. Let me try to explain again: > > CREATE TABLE obj_weights ( > object_id int4 REFERENCES ( apple_objects(id) OR banana_objects(id) ) > weight float4, > ) > > "apple_objects" doesn't necessarily have anything to do with > "banana_objects". Ok, don't ask why you would want to store weights of > apples and bananas in the same table.. (and if you know, please tell me). > This is all actually for someone else's database that I just picked up. > They did something like this.. single sequence for the whole database, > multiple object tables, and a table(s) referencing objects that could come > from any of those tables. Maybe this is just bad design. Thoughts > anyone? What about this example: Say you want all addresses in one table. This is something that I've wanted. And you want both employees and vendors to reference the address entity. Using the mythical syntax in this thread: CREATE TABLE vendor ( vendor_id integer, name varchar(32), PRIMARY KEY (company_id) ) CREATE TABLE employee ( employee_id integer, first_name varchar(32), last_name varchar(32), PRIMARYKEY (employee_id) ) CREATE TABLE address ( address_id integer, object_id REFERENCES vendor OR REFERENCES employee, address varchar(32), city varchar(32), state varchar(2), zip varchar(9), PRIMARY KEY (address_id) ) This is what I've done: Create an address table, it references no one. CREATE TABLE address ( address_id integer, address varchar(32), city varchar(32), state varchar(2), zip varchar(9), PRIMARY KEY (address_id) ) Assuming an employee has only one address, the employee table references the address table. CREATE TABLE employee ( employee_id integer, first_name varchar(32), last_name varchar(32), address_id integer REFERENCES address PRIMARY KEY (employee_id) ) Assuming that a vendor can have more than one address: CREATE TABLE vendor ( vendor_id integer, name varchar(32), PRIMARY KEY (company_id) ) CREATE TABLE vendor_address ( vendor_id integer REFERENCS vendor, address_id integer REFERNCES address, PRIMARYKEY (vendor_id, address_id) ) Just a thought Alan Gutierrez - alangutierrez@hotmail.com