Oracle:无法创建两个复合键

时间:2012-12-07 18:08:16

标签: sql oracle foreign-keys composite-key

我的一个表有一个由三个外键组成的复合键(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)
);

这甚至可以吗?

2 个答案:

答案 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)
);