我经常发现自己遇到了像这样的情况(这是人为的,但说明了问题):
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')
);
当然,product_order.type
上的外键约束不起作用,因为customer.type
不是UNIQUE
或主键(我不能使用CHECK CONSTRAINT
在仅存在于另一个表中的列上)。但是,我只希望product_order
客户type = 'business'
条目。
我可以将customer.id
和customer.type
作为复合主键,但是那些只想引用customer.id
的其他表也必须不必要地引用customer.type
。
在这种情况下,最好的方法是什么?
编辑:忘记外键约束product_order.customer_id
!
答案 0 :(得分:2)
您可以为类型创建查找表,并使用FKEY关系强制执行
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)
);
答案 1 :(得分:2)
如果您在customer.type
上创建了唯一的约束,则可以从product_order
表中引用它:
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)
);
答案 2 :(得分:0)
您可以访问product_order作为视图:
create view product_order_vw
as
select po.*
from product_order po
join customer c
on c.customerid = po.customerid
where c.type = 'business'
答案 3 :(得分:0)
我认为你需要另一种类型。此示例采用MS SQL格式:
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) ,
....
);
因此,您的product_order必须在Types表中定义类型。在您的示例中,您只有一个条目“业务”,但您可以根据需要添加任意数量。