ERROR의 원인 : 참조 된 테이블에 대해 주어진 키와 일치하는 고유 제한 조건이 없습니까?


154

아래 예제 테이블 구조는 ERROR를 제공합니다. 참조 테이블에 대해 주어진 키와 일치하는 고유 제한 조건이 없으며 지금까지 응시했지만이 상황 에서이 오류가 발생하는 이유를 알 수 없습니다.

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

답변:


188

테이블 의 name열에 UNIQUE 제약 조건 bar이 없기 때문 입니다.

그래서 당신은 2 개 행이 상상 bar이름을 포함하는 테이블을 'ams'당신은에 행을 삽입 baz'ams'bar_fk에있는 행 bar이 일치하는 두 개의 행이 있기 때문에 참조 할 것?


1
짧고 정확하며 설명을 쉽게 잡을 수 있습니다!
Alex

79

postgresql에서 모든 외래 키는 부모 테이블 의 고유 키 를 참조해야 하므로 bar테이블에는 unique (name)인덱스 가 있어야합니다 .

또한 http://www.postgresql.org/docs/9.1/static/ddl-constraints.html#DDL-CONSTRAINTS-FK를 참조하십시오 .

마지막으로 외래 키는 기본 키이거나 고유 제약 조건 인 열을 참조해야합니다.

강조합니다.


21
선언 된 PK가 고유 제한 조건으로 간주되지 않는 이유는 무엇입니까? 그것은 당신이 비
독특한

2
그렇지 않은 경우 데이터베이스 엔진은 실제로 참조하는 행을 알 수있는 방법이 없기 때문에 "지시"하는 테이블에서 고유해야합니다.
Matteo Tassinari

복합 키? @amphibient
매력적인 로봇

1
부모 테이블의 참조 열에 고유 키를 갖는 것이 postgresql에서만 필요하지 않으며 오라클, SQL Server 등과 같은 다른 RDBMS도 필요하다고 생각합니다.
Mufachir Hossain

2
상위 테이블에서 복합 고유 제한 조건 또는 기본 키가 필요한 복합 외부 키의 경우에도 그 대답이 적용됩니다.
Ninjakannon 2016 년

8

당신이 한 UNIQUE것처럼 테이블 수준 제약 조건으로 할 때 정의가 복합 기본 키와 약간 비슷한 것은 ddl 제약 조건을 참조하십시오 . 여기에는 추출이 있습니다.

"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."

즉, 조합 이 고유하고 외래 키 제약 조건과 일치하지 않으면 두 필드 중 하나에 고유하지 않은 값이있을 수 있습니다 .

제약 조건이 열 수준에 있기를 원할 것입니다. 대신 테이블 수준 제약 조건으로 UNIQUE정의 name VARCHAR(60) NOT NULL UNIQUE하거나 열 정의 끝에 '추가' 하거나 각 필드에 대한 개별 테이블 수준 제약 조건을 지정하십시오.


내 상황에서 열 수준의 제약이 정말 복합 기본 키를 정의해야 작동하지 않지만 JPA로 매핑하기 때문에 그것에서 멀리 백업의 고통 :)의 비트
AMS

6

고유 제한 조건으로 이름 열이 있어야합니다. 다음은 문제를 변경하기위한 3 줄의 코드입니다.

  1. 먼저이 코드를 입력하여 기본 키 제약 조건을 찾으십시오.

    \d table_name

    당신은 하단에 이와 같이 표시됩니다 "some_constraint" PRIMARY KEY, btree (column)

  2. 구속 조건을 삭제하십시오.

    ALTER TABLE table_name DROP CONSTRAINT some_constraint
  3. 기존 키 열을 사용하여 새 기본 키 열을 추가하십시오.

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

그게 다야.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.