【发布时间】:2014-10-28 20:25:40
【问题描述】:
我正在马里兰州的约翰霍普金斯大学参加数据库课程并且有一个问题。我已经给我的教授发了电子邮件,他知道我在这里问这个问题,他对此很满意。所以我正在 Postgres 中开发一个 COOKBOOK 数据库,我在 Postgres 中遇到了一个有趣的问题,我似乎无法构建 PRICE 表。我有一本不错的 Cookbook ERD,但显然要等到我的声誉至少达到 10 时才能发布。我会尽力描述 ERD。有三个与 PRICE 相关的保理表。这些是成分、替代品和价格。
这里是 ERD 的链接(请注意 1:M 表示成分到替代): [ERD]
我可以有一个可能有许多替代品的成分,并且替代品和价格之间可能是一对一的(如果价格已知,则每个替代品一个价格)。如果 PRICE 是已知的,那么 PRICE 就能够定义一个具有复合主键的元组:(price_id, ingredients_id (fk), substitution_id (fk))
我面临的挑战是 Postgres SQL 不允许我建立这种关系,我不确定为什么。我已经将 SUBSTITUTION 中的键设置为具有 UNIQUE 约束,因此这不应该是问题。我唯一能想到的是 SUBSTITUTION 中的成分 ID 是 INGREDIENT 的外键,因此可能不会在 SUBSTITUTION 中物理建立,但我得到的错误并不表明这一点。这就是我在终端中得到的(首先描述 SUBSTITUTION):
cookbook=# \d+ SUBSTITUTION
Table "public.substitution"
Column | Type | Modifiers | Storage | Description
--------------------+-----------------------+--------------------------------------------------------------------------+----------+-------------
substitution_id | integer | not null default nextval('subsitution_substitution_id_seq'::regclass) | plain |
ingredient_id | integer | not null default nextval('subsitution_ingredient_id_seq'::regclass) | plain |
name | character varying(50) | not null | extended |
measurement_ref_id | integer | not null default nextval('subsitution_measurement_ref_id_seq'::regclass) | plain |
metric_unit | character varying(25) | not null | extended |
Indexes:
"subsitution_pkey" PRIMARY KEY, btree (substitution_id, ingredient_id)
"uniqueattributes" UNIQUE, btree (substitution_id, ingredient_id)
Foreign-key constraints:
"subsitution_ingredient_id_fkey" FOREIGN KEY (ingredient_id) REFERENCES ingredient(ingredient_id)
"subsitution_measurement_ref_id_fkey" FOREIGN KEY (measurement_ref_id) REFERENCES measurement_ref(measurement_ref_id)
Has OIDs: no
cookbook=# create table price(
price_id serial not null,
ingredient_id serial references substitution(ingredient_id),
cookbook(# substitution_id serial references substitution(substitution_id),
cookbook(# usdollars smallint not null,
cookbook(# availability season,
cookbook(# seasonal boolean,
cookbook(# primary key (price_id, ingredient_id, substitution_id)
cookbook(# );
NOTICE: CREATE TABLE will create implicit sequence "price_price_id_seq" for serial column "price.price_id"
NOTICE: CREATE TABLE will create implicit sequence "price_ingredient_id_seq" for serial column "price.ingredient_id"
NOTICE: CREATE TABLE will create implicit sequence "price_substitution_id_seq" for serial column "price.substitution_id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "price_pkey" for table "price"
ERROR: there is no unique constraint matching given keys for referenced table "substitution"
【问题讨论】:
-
不知道是不是真的明白了,一个外键在自己的表中必须是唯一的,如果要引用元组:substitition_id和component_id,可以加一列类似@987654323 @ 作为序列到您的
substitution表中,并将其设为主键,此键可以作为price表中的外键引用。 -
@Houari 添加一个键和 FK 并不能阻止从 PRICE(substitution_id,component_id)到 SUBSTITUTION 的约束。您的所有建议只是存在一个 FK,但没有原始所需约束点的效果。
标签: sql postgresql foreign-keys primary-key composite-primary-key