简体   繁体   English

是否可以将外键引用到父表?

[英]Is it possible to reference a foreign key to parent table?

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

Here is my tables while insertion of sale rows I get this error. 这是我插入销售行时的表格,但出现此错误。

ERROR: insert or update on table "sale" violates foreign key constraint "PK_Product_id" 错误:对表“ sale”的插入或更新违反了外键约束“ PK_Product_id”
SQL state: 23503 SQL状态:23503
Detail: Key (Product_id)=(12) is not present in table "product". 详细信息:表(product)中不存在键(Product_id)=(12)。

It says there is no presence of the row, but I can see them when I view the table: 它说不存在该行,但是当我查看表时可以看到它们:

但是pgAdmin声称表中没有行。

I inserted every product as computer or mobile not as product. 我将每个产品都插入为计算机或移动设备,而不是产品。

You are stumbling over one of the many quirks with inheritance: There are no “global” constraints on an inheritance hierarchy, consequently you cannot have a foreign key to a inheritance hierarchy. 您正在绊倒具有继承性的众多怪癖之一:继承层次结构上没有“全局”约束,因此,您不能拥有继承层次结构的外键。

The primary key you defined on product does not extend to computer . 您在product上定义的主键不会扩展到computer

Even though a SELECT on product will append the results for the inheritance children as well, these are not part of the table parent and consequently cannot be used as target for the foreign key. 即使product上的SELECT也将附加继承子项的结果,但它们也不是表parent一部分,因此不能用作外键的目标。 The foreign key is between sale and product only , the inheritance children are excluded. 外键之间的saleproduct 而已 ,继承子女被排除在外。

There is no proper way to do this with inheritance. 没有适当的方法可以通过继承来实现。

It is better for computer not to be an inheritance child of product, but to have a foreign key to product (with a unique constraint on it), so that the data for a computer object will be split between the two tables. 这是更好地为computer 成为产品的一个继承的孩子,但有一个外键product (与它独特的约束),所以,对于一个计算机对象的数据将在两个表之间进行分割。 This is somewhat inconvenient for queries, but you can have a foreign key that way. 这对于查询来说有点不方便,但是您可以通过这种方式拥有外键。

Here is an example: 这是一个例子:

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

Now there is no direct foreign key reference from sale to computer , but since the product_id of computer and product is identical, you can always find the unique computer for a sale if it exists: 现在没有从salecomputer直接外键引用,但是由于computerproductproduct_id相同,因此如果存在,您总是可以找到要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;

If you have more product “subtypes”, you can add more left joins. 如果您有更多的产品“子类型”,则可以添加更多的左联接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM