Sql 导致错误的原因:没有唯一的约束匹配引用表的给定键?

Sql 导致错误的原因:没有唯一的约束匹配引用表的给定键?,sql,postgresql,Sql,Postgresql,下面的示例表结构给出了一个错误:并没有唯一的约束匹配引用表的给定键,并且已经盯着它看了一段时间,现在我不明白为什么在这种情况下会出现这个错误 BEGIN; CREATE TABLE foo ( name VARCHAR(256) PRIMARY KEY ); CREATE TABLE bar( pkey SERIAL PRIMARY KEY, foo_fk VARCHAR(256) NOT NULL REFEREN

下面的示例表结构给出了一个错误:并没有唯一的约束匹配引用表的给定键,并且已经盯着它看了一段时间,现在我不明白为什么在这种情况下会出现这个错误

BEGIN;

CREATE TABLE foo (
    name                VARCHAR(256) PRIMARY KEY
);

CREATE TABLE bar(
    pkey        SERIAL PRIMARY KEY,
    foo_fk      VARCHAR(256) NOT NULL REFERENCES foo(name), 
    name        VARCHAR(256) NOT NULL, 
    UNIQUE (foo_fk,name)
);

CREATE TABLE baz(   
    pkey            SERIAL PRIMARY KEY,
    bar_fk          VARCHAR(256) NOT NULL REFERENCES bar(name),
    name            VARCHAR(256)
);

COMMIT;
运行上面的代码会出现以下错误,这对我来说没有意义,有人能解释为什么会出现这个错误吗。我正在使用postgres 9.1

NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"
NOTICE:  CREATE TABLE will create implicit sequence "bar_pkey_seq" for serial column "bar.pkey"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "bar_pkey" for table "bar"
NOTICE:  CREATE TABLE / UNIQUE will create implicit index "bar_foo_fk_name_key" for table "bar"
NOTICE:  CREATE TABLE will create implicit sequence "baz_pkey_seq" for serial column "baz.pkey"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "baz_pkey" for table "baz"
ERROR:  there is no unique constraint matching given keys for referenced table "bar"


********** Error **********

ERROR: there is no unique constraint matching given keys for referenced table "bar"
SQL state: 42830

在postgresql中,所有外键都必须引用父表中的唯一键,因此在
bar
表中必须有
unique(name)
索引

另见具体内容:

最后,我们应该提到,外键必须引用列 是主键或形成唯一约束。


强调我。

这是因为
表上的
名称
列没有唯一约束


因此,假设您在
bar
表上有两行,其中包含名称
'ams'
,您在
baz
上插入一行,其中
'ams'
位于
bar\u fk
上,由于有两行匹配,它将引用
栏上的哪一行?

当您将
唯一
作为表级约束时,您的定义有点像复合主键请参见,这里是一个摘录

"This specifies that the *combination* of values in the indicated columns is unique across the whole table, though any one of the columns need not be (and ordinarily isn't) unique."
这意味着,如果组合
是唯一的且与外键约束不匹配,则任一字段都可能具有非唯一值


您很可能希望约束位于列级别。因此,与其将它们定义为表级约束,不如在列定义的末尾加上“append”
UNIQUE
,如
name VARCHAR(60)NOT NULL UNIQUE
,或者为每个字段指定单独的表级约束。

您应该将name column作为唯一约束。这里有3行代码来更改您的问题

  • 首先通过键入以下代码找出主键约束

    \d table_name
    
    在底部“some_constraint”主键btree(column)
  • 删除约束:

    ALTER TABLE table_name DROP CONSTRAINT some_constraint
    
  • 使用现有主键列添加新的主键列:

    ALTER TABLE table_name ADD CONSTRAINT some_constraint PRIMARY KEY(COLUMN_NAME1,COLUMN_NAME2);
    

  • 仅此而已。

    列级约束在我的情况下不起作用我真的应该定义一个复合主键,但我放弃了它,因为将它映射到JPA有点麻烦:)为什么声明的PK不被视为唯一约束?这不是说你可以有一个非唯一的PK…它在它“指向”的表上必须是唯一的,因为如果不是,数据库引擎将无法知道你实际引用的是哪一行。复合键@我认为在父表的引用列上具有唯一键不仅在postgresql中是必需的,而且在其他RDBMS(如oracle、sql server等)中也是必需的。请注意,对于复合外键,答案也是正确的,其中父表上需要复合唯一约束或主键。