Reputation: 1799
I often find myself running into situations like this one (which is contrived but illustrative of the problem):
CREATE TABLE customer (
id SERIAL PRIMARY KEY,
type TEXT
-- other columns...
);
CREATE TABLE product_order (
id SERIAL PRIMARY KEY,
customer_id INTEGER REFERENCES customer (id),
type TEXT REFERENCES customer (type), -- not actually legitimate
-- other columns...
CHECK (type = 'business')
);
Of course, the foreign key constraint on product_order.type
doesn't work because customer.type
is not UNIQUE
or a primary key (and I can't use a CHECK CONSTRAINT
on a column that only exists in another table). However, I would only like product_order
entries for type = 'business'
customers.
I could make customer.id
and customer.type
a composite primary key, but then any other tables that want to reference just customer.id
must also reference customer.type
unnecessarily.
What's the best approach in this situation?
EDIT: Forgot the foreign key constraint product_order.customer_id
!
Upvotes: 1
Views: 184
Reputation:
If you create a unique constraint on the customer.type
you can reference it from the product_order
table:
CREATE TABLE customer (
id SERIAL PRIMARY KEY,
type TEXT,
-- other columns...
constraint unique_cust_type unique (id, type) -- this makes the combination id/type "referencable"
);
CREATE TABLE product_order
(
id SERIAL PRIMARY KEY,
customer_id INTEGER,
type TEXT default 'business',
CHECK (type = 'business'),
foreign key (customer_id, type) references customer (id, type)
);
Upvotes: 2
Reputation: 1173
You could make a lookup table for types, and use the FKEY relationship to enforce
CREATE TABLE type (
id integer, PRIMARY KEY,
name TEXT
);
CREATE TABLE customer (
id SERIAL PRIMARY KEY,
type_id INTEGER, NOT NULL
-- other columns...
FOREIGN KEY (type_id) REFERENCES type(id)
);
CREATE TABLE product_order (
id SERIAL PRIMARY KEY,
type_id INTEGER, NOT NULL
-- other columns...
FOREIGN KEY (type_id) REFERENCES type(id)
);
Upvotes: 2
Reputation: 2583
I think you need another type for the type. This sample is in MS SQL format:
CREATE TABLE TYPES (ctype varchar(10) NOT NULL PRIMARY KEY,
name varchar(50) not null
);
CREATE TABLE product_order (
id SERIAL PRIMARY KEY,
type varchar(10) NOT NULL REFERENCE TYPES (ctype) ,
....
);
So your product_order must have types defined in Types table. In your sample, you have only one entry 'business' but you can add as many as you want.
Upvotes: 0
Reputation: 36555
You could access product_order as a view:
create view product_order_vw
as
select po.*
from product_order po
join customer c
on c.customerid = po.customerid
where c.type = 'business'
Upvotes: 0