我的一个表有一个由三个外键组成的复合键(order_no,product_code和product_size)。
在Product_size是主键的表中,我想要一个由Product_size和product_code组成的复合键。如果我确实将它们作为复合键,那么单独的product_size将不是PK,因此我无法在创建由三个外键组成的复合键时引用它。
create table product_stock
(
Product_Code varchar2(6) constraint productcode_fk references product(Product_Code),
Product_Size char(1) constraint size_chk check (Product_Size in
('L', 'l', 'M', 'm', 'S', 's' )),
Product_Unitprice number(7,2) not null,
Stock_Quantity number(4) not null,
constraint prodstock_comp primary key (product_code,product_size)
);
create table orderline
(
Order_No number(4) constraint orderno_fk references order_detail(Order_No),
Product_Code varchar2(6) constraint productcode2_fk references product(Product_Code),
Product_Size char(1) constraint productsize_fk references product_stock(product_size),
Product_Quantity number(4) not null,
constraint orderline_comp primary key (Order_No,Product_Code, Product_Size)
);
这甚至可以吗?
答案 0 :(得分:3)
单独的product_size不会是PK,因此我无法引用它
想象一下,product_stock
表中有两行具有相同的product_size
(和不同的product_code
)。现在想象一下这些行中的一行(但不是另一行)被删除了。
orderline
行引用它? product_stock
行,orderline
行也引用?(ON DELETE CASCADE / SET NULL以及UP更新PK时也存在类似问题。)
为了避免这些歧义,DBMS不允许您创建外键,除非您可以唯一标识父行,这意味着您必须在FK的REFERENCES子句后使用整个键
话虽这么说,你可以创造两个......
FOREIGN KEY (product_code)
REFERENCES product (product_code)
...和...
FOREIGN KEY (product_code, product_size)
REFERENCES product_stock (product_code, product_size)
虽然如果你有后者,前者可能多余。
事实上,(因为你已经有了FK product_stock -> product
),同时拥有两个FK会创建一个“菱形”依赖。顺便说一句,有些DMBS对菱形FK有限制(MS SQL Server不支持级联参考动作)。
答案 1 :(得分:1)
取决于您的特定DBMS,但您可以使用单独的约束子句在多个列上定义外键,如下所示:
create table orderline (
Order_No number(4) constraint orderno_fk references order_detail(Order_No),
Product_Code varchar2(6) constraint productcode2_fk references product(Product_Code),
Product_Size char(1) constraint productsize_fk references product_stock(product_size),
Product_Quantity number(4) not null,
constraint orderline_comp primary key (Order_No,Product_Code, Product_Size),
constraint fk_product_stock foreign key (product_code, product_size) references product_stock (product_code, product_size)
);