是否可以将外键引用到父表? [英] Is it possible to reference a foreign key to parent table?
问题描述
创建表Product
(
Product_id int,
Stock_quantity int,
Product_name varchar(50),
模型 varchar(50),
Average_rating float(3),
RAM int,
颜色 varchar(20),
价格 float(10),
主键( Product_id)
);
创建表Sale
(
Sale_id int,
Sale_date日期,
Employee_id int,
Customer_id int,
Product_id int,
Product_quantity int,
Rating int,
PRIMARY KEY( Sale_id),
FOREIGN KEY( Employee_id )参考Employee( Employee_id),
FOREIGN KEY( Customer_id)参考Customer( Customer_id),
FOREIGN KEY( Product_id)参考Product( Product_id)
);
创建表计算机
(
Type varchar(10),
Processor varchar(20),
Monitor_size int
)Inherits(产品);
创建表移动
(
Os varchar(30),
Screen_size int
)Inherits(Product);
这是我插入销售行时的表,但出现此错误。
错误:对表 sale的插入或更新违反了外键约束 PK_Product_id
SQL状态:23503
详细信息:表(product)表中不存在键(Product_id)=(12)。
它表示不存在行,但在查看表时可以看到它们:
我将每个产品作为计算机或移动设备插入,而不是作为产品插入。
您正在绊倒具有继承性的众多怪癖之一:没有 global约束对继承层次结构的约束,因此,您不能具有继承层次结构的外键。
在产品$ c上定义的主键$ c>不会扩展到
计算机
。
即使<$ c 产品
上的$ c> SELECT 还将附加继承子项的结果,这些都不属于表父
,因此不能用作外键的目标。外键介于 sale
和 product
之间,不包括继承子项。 / p>
没有通过继承来完成此操作的方法。
对于更好计算机
不是是产品的继承子级,但是具有 product
的外键(具有唯一约束) ),以便将计算机对象的数据在两个表之间分配。这对于查询来说有点不方便,但是您可以通过这种方式获得外键。
这里是一个示例:
< pre class = lang-sql prettyprint-override>
创建表产品(
product_id整数PRIMARY KEY,
产品名文本NOT NULL
);
创建表计算机(
product_id整数PRIMARY KEY,
处理器文本NOT NULL,
FOREIGN KEY(product_id)参考product(product_id)
);
CREATE TABLE sale(
sale_id整数PRIMARY KEY,
product_id整数NOT NULL引用product(product_id)
);
现在,出售$ c $没有直接的外键引用c>到
计算机
,但由于计算机
的 product_id
并且产品
是相同的,如果存在销售
,您总是可以找到唯一的计算机:
SELECT p.prodname,c.processor
FROM sale s
JOIN product p USING(product_id)
LEFT使用(product_id)
JOIN计算机c在哪里sale_id = 42;
如果您有更多的产品子类型,则可以添加更多的左联接。
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"
SQL state: 23503
Detail: Key (Product_id)=(12) is not present in table "product".
It says there is no presence of the row, but I can see them when I view the table:
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
.
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. The foreign key is between sale
and product
only, the inheritance children are excluded.
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. 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:
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.
这篇关于是否可以将外键引用到父表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!