一般的多对多关系问题(Postgresql)

时间:2010-05-11 10:22:30

标签: sql postgresql entity-relationship

我有两张桌子:

CREATE TABLE "public"."auctions" (
"id" VARCHAR(255) NOT NULL, 
"auction_value_key" VARCHAR(255) NOT NULL, 
"ctime" TIMESTAMP WITHOUT TIME ZONE NOT NULL, 
"mtime" TIMESTAMP WITHOUT TIME ZONE NOT NULL,
 CONSTRAINT "pk_XXXX2" PRIMARY KEY("id"), 
);

CREATE TABLE "public"."auction_values" (
 "id" NUMERIC DEFAULT nextval('default_seq'::regclass) NOT NULL, 
 "fk_auction_value_key" VARCHAR(255) NOT NULL, 
 "key" VARCHAR(255) NOT NULL, 
 "value" TEXT, 
 "ctime" TIMESTAMP WITHOUT TIME ZONE NOT NULL, 
 "mtime" TIMESTAMP WITHOUT TIME ZONE NOT NULL,
 CONSTRAINT "pk_XXXX1" PRIMARY KEY("id"), 
);

如果我想在auction_value_key上创建多对多关系,请执行以下操作:

ALTER TABLE "public"."auction_values"
  ADD CONSTRAINT "auction_values_fk" FOREIGN KEY ("fk_auction_value_key")
    REFERENCES "public"."auctions"("auction_value_key")
    ON DELETE NO ACTION
    ON UPDATE NO ACTION
    NOT DEFERRABLE;

我得到了这个SQL错误:

ERROR:  there is no unique constraint matching given keys for referenced table "auctions"

问题:

正如您可能看到的那样,我希望“拍卖价值”能够被不同的拍卖“重复使用”而不会在每次拍卖中重复使用...所以我不希望拍卖表中“id”字段的关键关系...

我在这里想错了或者交易是什么? ;)

由于

3 个答案:

答案 0 :(得分:1)

您需要一个额外的表来建模多对多关系。它将包含拍卖和auction_values之间的映射。它需要两列:auction_id和auction_value_id。

答案 1 :(得分:0)

如果您希望auction_values被不同的拍卖重用,您应该反过来声明一个约束:

ALTER TABLE auctions
ADD CONSTRAINT fk_auction_values
FOREIGN KEY (auction_value_key)
REFERENCES auction_values (id)

答案 2 :(得分:0)

引用wikipedia

  

在关系的背景下   数据库,外键是一个   两者之间的参照约束   tables。1外键标识   一列中的列或一组列   (引用)引用set的表   列中的列(引用)   表。引用中的列   表必须是主键或其他   引用表中的候选键。   一行中的值   引用列必须出现在   引用表中的单行。   因此,引用表中的一行   不能包含不存在的值   在引用的表中(除了   可能是NULL)。这种方式参考   可以链接信息   在一起,这是一个必不可少的部分   数据库规范化。多   引用表中的行可能   参考中的同一行   参考表。大多数时候,它   反映一个(主表,或   参考表)对许多人(孩子   表或引用表)   关系。

正如Quassnoi所指出的那样,听起来好像你想在auctions中的auction_values个引用单行中有多行。

为此,主表或引用表为auction_values,子表或引用表为auction_values。

另一方面,如果Alex是对的,并且您想引用auction_values中的多行,则需要另一个表格。

此表将帮助您将多对多关系(无法在物理数据库级别直接实现)转换为两个一对多关系。

通常,您可以从两个起始表中获取此表存储ID,这样您就可以关联auction_valuesauctions的任何记录组合。

但是,这可能过于笼统,您实际上可能会在表auction_value_keys (auction_value_key)

之后