Another Suggestion
Al Davis, January 11, 2005 - 7:47 am UTC
Since c and d are both number data type and one is null when the other is not, why not combine them and call the column c_d and add an indicator column called 'c_or_d' to the index and to the application SQL.
January 11, 2005 - 10:43 am UTC
I am personally not a fan of using a column for two things -- just my 2 cents. It'll cause massive confusion down stream.
Design flaw?
Kevin, January 11, 2005 - 12:14 pm UTC
This looks like a case where two different relationships are being crammed into a single table. R1 is a relation (a,b,c,e) and R2 is a relation (a,b,d,e). Consider using two tables instead (short hand):
CREATE TABLE T1 (a NOT NULL, b NOT NULL, c NOT NULL, e, PK ON (a,b,c));
CREATE TABLE T2 (a NOT NULL, b NOT NULL, d NOT NULL, e, PK ON (a,b,d));
in many cases, you may find this approach (using table structures which more closely match your data) actually simplifies your application design. You don't have to worry about the convoluted "primary keys with nulls" workarounds - you've got pure primary keys right there. The constraint "only one of c and d is populated" is implemented by definition.
And if you're worried about queries out there which need to be backwards compatible, just add a view:
DROP TABLE OLD_TABLE_NAME;
CREATE VIEW OLD_TABLE_NAME AS
SELECT A, B, C, NULL D, E FROM T1 UNION ALL
SELECT A, B, NULL C, D, E FROM T2;
("INSTEAD OF INSERT/UPDATE/DELETE" Triggers can be used for backwards compatibility, if OLD_TABLE_NAME was being modified by other processes).
The only major problem is if a foreign key needed to reference all four columns (a, b, c, d)... honestly, I doubt any such dependency SHOULD exist - much more likely that any such dependency should be on (a,b,c) OR on (a,b,d).
January 11, 2005 - 1:48 pm UTC
you are probably right -- and there is probably even a missing table :)
t (a,b,e,..... )
t1( a,b,c, m,n, foreign key(a,b) points to t)
t2( a,b,d, x,y, foreign key(a,b) points to t)