首页 > 解决方案 > 是否可以将外键引用到父表?

问题描述

CREATE TABLE Product 
(
    "Product_id" int,
    "Stock_quantity" int,
    "Product_name" varchar(50),
    "Model" varchar(50),
    "Average_rating" float(3),
    "RAM" int,
    "Color" varchar(20),
    "Price" float(10),
    PRIMARY KEY ("Product_id")
);

CREATE TABLE Sale 
(
    "Sale_id" int,
    "Sale_date" date,
    "Employee_id" int,
    "Customer_id" int,
    "Product_id" int,
    "Product_quantity" int,
    "Rating" int,
    PRIMARY KEY ("Sale_id"),
    FOREIGN KEY("Employee_id") REFERENCES Employee("Employee_id") ,
    FOREIGN KEY("Customer_id") REFERENCES Customer("Customer_id") ,
    FOREIGN KEY("Product_id") REFERENCES Product("Product_id")
);

CREATE TABLE Computer  
(
    "Type" varchar(10),
    "Processor" varchar(20),
    "Monitor_size" int
)  inherits(Product);

CREATE TABLE Mobile 
(
    "Os" varchar(30),
    "Screen_size" int
) inherits(Product);

这是我的表格,在插入销售行时出现此错误。

错误:在表“sale”上插入或更新违反了外键约束“PK_Product_id”
SQL 状态:23503
详细信息:表“产品”中不存在键 (Product_id)=(12)。

它说不存在该行,但是当我查看表格时可以看到它们:

但是 pgAdmin 声称表中没有行。

我将每个产品都作为计算机或移动设备插入,而不是作为产品插入。

标签: sqlpostgresql

解决方案


您遇到了继承的许多怪癖之一:继承层次结构没有“全局”约束,因此您不能拥有继承层次结构的外键。

product您定义的主键扩展到computer.

即使 a SELECTonproduct也会附加继承子级的结果,但这些不是表的一部分,parent因此不能用作外键的目标。外键是 between saleand product only,不包括继承子项。

没有适当的方法可以通过继承来做到这一点。

最好computer 不要成为 product 的继承子级,而是有一个外键product(带有唯一约束),以便计算机对象的数据将在两个表之间拆分。这对于查询来说有点不方便,但是您可以通过这种方式拥有一个外键。

这是一个例子:

CREATE TABLE product (
   product_id integer PRIMARY KEY,
   prodname text NOT NULL
);

CREATE TABLE computer (
   product_id integer PRIMARY KEY,
   processor text NOT NULL,
   FOREIGN KEY (product_id) REFERENCES product(product_id)
);

CREATE TABLE sale (
   sale_id integer PRIMARY KEY,
   product_id integer NOT NULL REFERENCES product(product_id)
);

现在没有来自saleto的直接外键引用computer,但是由于product_idofcomputer和是相同的,如果存在producta ,您总是可以找到唯一的计算机:sale

SELECT p.prodname, c.processor
FROM sale s
   JOIN product p USING (product_id)
   LEFT JOIN computer c USING (product_id)
WHERE sale_id = 42;

如果您有更多产品“子类型”,则可以添加更多左连接。


推荐阅读