외래 키 제약 조건이있는 열을 이미 존재하는 테이블에 추가하는 방법은 무엇입니까?


11

다음 표가 있습니다.

CREATE TABLE users (id int PRIMARY KEY);

-- already exists with data
CREATE TABLE message ();

messages테이블을 어떻게 변경합니까?

  1. 라는 새 열 sender이 추가됩니다
  2. 테이블을 sender참조하는 외래 키는 어디에 있습니까?users

이 작동하지 않았다

# ALTER TABLE message ADD FOREIGN KEY (sender) REFERENCES users;
ERROR:  column "sender" referenced in foreign key constraint does not exist

이 문장도 열을 작성하지 않습니까?


3
열을 참조하기 전에 열을 작성해야합니다. 여기 ALTER TABLE 의 문서를 읽으려고 시도 하고 예제에 매우주의를 기울이십시오.
Kassandry

하산, 나는 DDL을 사용하기 위해이 질문을 정리하고 작동하지 않는 것을 제거했습니다. 이것이 dba.stackexchange.com/a/202564/2639 질문에 대답하는지 확인하십시오 . 이러한 수정 사항을 거부하지 말고 후손을 위해 정리하고 싶었습니다.
Evan Carroll

답변:


18

비교적 쉬운 방법-다른 단계를 추가하면됩니다.

FOREIGN KEY열이 존재하는 그것에게를 만들기 위해 FK. 나는 다음과 같은 (에서 한 여기문서 ) :

CREATE TABLE x(t INT PRIMARY KEY);

CREATE TABLE y(s INT);

ALTER TABLE y ADD COLUMN z INT;    

ALTER TABLE y
  ADD CONSTRAINT y_x_fkey FOREIGN KEY (z)
      REFERENCES x (t)
      ON UPDATE CASCADE ON DELETE CASCADE;

주목해야 할 몇 가지 사항 :

항상 외래 키에 의미있는 이름을 지정하십시오. "SYS_C00308108"키가 위반되었다는 말은 그다지 도움이되지 않습니다. 바이올린을 참조하십시오 여기에 키 이름이 바이올린을 바이올린에 따라 다를 것입니다 이러한 상황에서 오라클의 행동을하지만) _... SYS로 시작하는 어떤 임의의 문자열입니다

당신의 진술을 고려 :

ALTER TABLE message ADD FOREIGN KEY (sender) REFERENCES users;

RDBMS가 참조 된 필드와 일치하는 데이터 유형을 사용하여 원하는 필드를 자동으로 작성할 수있는 경우 "좋아요"입니다. DDL을 변경하는 것은 거의 사용하지 않는 작업이며 정기적으로 수행하고 싶은 작업이 아니라는 것입니다. 또한 이미 상당히 실질적인 문서를 추가 할 위험이 있습니다.

최소한 PostgreSQL은 합리적인 작업을 시도합니다. 테이블 이름, FOREIGN KEY필드 이름 을 연결하고 사람에게 의미가있는 것을 _fkey추가하기도합니다 . 여기에서DETAIL: Key (sender_id)=(56) is not present in table "user_". 바이올린을 보십시오 .


2
외래 키 이름을 지정하지 않습니다. 이름이 자동으로 지정되며 일반적으로 매우 유용합니다. 예를 들어, 해당 컨텍스트의 기본 이름은 "y_z_fkey"입니다. 나는 그보다 더 좋은 이름의 주장 것입니다 y_x_fkey귀하의 위반이있는 거 삽입 열을 말하지 않기 때문 그 오류를 일으키는. 나는 그것이 가리키는 곳에 대해 덜 신경 쓰고 있습니다. 일반적으로 절대로 fkeys의 이름을 지정하지 말고 PostgreSQL의 기본 값으로 처리하십시오.
Evan Carroll

또한, ON UPDATE CASCADE ON DELETE CASCADE;예를 들어 이유없이 기본값을 무시하지 않을 수도 있습니다 . 예제를 더 복잡하게 만들고 그 설명을 귀찮게하지 않습니다. 나는 일반적으로 계단식 삭제를 원하지 않습니다.
Evan Carroll

1
나는 항상 이름을 회사 / 프로젝트를 결정했다는 규칙에 따라, FKS을. 일관성 이있는 한 y_x_fkey또는 y_z_fkey또는 중요하지는 않습니다 x__y_FK.
ypercubeᵀᴹ

계약을 체결하는 경우 이에 동의합니다. 컨벤션을 선택하고이를 준수하거나 이전에 시스템에서 사용했던 컨벤션을 준수하는지 확인하십시오.
Vérace

@EvanCarroll- PostgreSQL의 컨벤션이 프로젝트의 컨벤션이거나 PostgreSQL이 아닌 시스템에서 이전에 결정된 컨벤션 인 경우 , 시스템은 PostgreSQL의 컨벤션이없는 Oracle 또는 기타 시스템에서 시작되었을 수 있습니다. x_y_z_fk가 오류 발생시 가능한 최대 정보를 제공 할 수 있다고 주장 할 수 있습니다! 무언가를 골라 내 좌우명을 지키 십시오.하지만 RDBMS가 아무리 좋더라도 당신을 위해 협약을 결정하지 마십시오!
Vérace

8

왜 모든 사람이 두 단계로이 작업을 수행해야하는지 잘 모르겠습니다. 사실, 당신은하지 않습니다 . FOREIGN KEY의도적으로 열이 있다고 가정하고 열이 없으면 오류를 발생시키는를 추가하려고 했습니다. 당신이를 추가 할 경우 COLUMN, 당신은 그것을 만들 명시 적으로 할 수 FOREIGN KEY와 생성에 REFERENCES,

ALTER TABLE message
  ADD COLUMN sender INT
  REFERENCES users;  -- or REFERENCES table(unique_column)

잘 작동합니다. 여기 의 구문을 볼 수 있습니다 .ALTER TABLE

ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
action [, ... ]

"행동" 과 같은

ADD [ COLUMN ] [ IF NOT EXISTS ] column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ]

이 예제는 문서에도 있습니다.

ALTER TABLE distributors
  ADD CONSTRAINT distfk
  FOREIGN KEY (address)
  REFERENCES addresses (address);

ALTER TABLE distributors
  ADD CONSTRAINT distfk
  FOREIGN KEY (address)
  REFERENCES addresses (address)
  NOT VALID;

그러나 자동 이름 지정 및 기본 키 확인에 의존 할 수 있기 때문에 필요하지 않습니다 (table-name 만 지정된 경우 기본 키 참조).


0

CASE1 : 새 테이블을 만드는 동안 외래 키를 만들어야하는 경우

CREATE TABLE table1(
id SERIAL PRIMARY KEY,
column1 varchar(n) NOT NULL,
table2_id SMALLINT REFERENCES table2(id)
); 

위의 명령은 이름이 'table1'이고 이름이 'id'(기본 키), 'column1', 'table2_id'(table2의 id 열을 참조하는 table1의 외래 키)라는 세 개의 열이있는 테이블을 만듭니다.

DATATYPE 'serial'은이 데이터 유형을 사용하는 열을 자동 생성 열로 만들며, 테이블에 값을 삽입 할 때이 열을 전혀 언급하지 않아도되거나 값 위치에 따옴표없이 'default'를 지정할 수 있습니다.

기본 키 열은 항상 값이 'tablename_pkey'인 테이블의 인덱스에 추가됩니다.

테이블 작성시 외래 키가 추가되면 CONSTRAINT가 '(present_table_name) _ (foreign_key_id_name) _fkey'패턴으로 추가됩니다.

외래 키를 추가 할 때, 열 이름 옆에 키워드 'REFERENCES'를 입력해야합니다. postgres에이 열이 테이블을 참조한다는 것을 알리고 참조 옆에 참조를 위해 테이블을 제공하고 괄호 안에 참조 된 테이블의 열 이름, 일반적으로 외래 키는 기본 키 열로 제공됩니다.

사례 2 : 기존 열의 기존 테이블에 대한 외래 키를 원하는 경우

ALTER TABLE table1
ADD CONSTRAINT table1_table2_id_id_fkey
FOREIGN KEY (table2_id) REFERENCES table2(id);

참고 : FOREIGN KEY 및 REFERENCES tabel2 뒤에 괄호 '()'가 있어야합니다. 그렇지 않으면 postgres에서 오류가 발생합니다.


0

나는 문제를 안다. 열 이름이 다릅니다. 한 열의 경우 열 이름 뒤에 공백이 추가 될 수 있으므로 열 이름의 이름이 정확히 동일한 지 신중하게 확인하십시오.


1
OP는 물었다 : 이 진술은 또한 열을 창조하지 않습니까? 그가 일어날 것으로 예상 한 것은 분명합니다.
Laurenz Albe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.