'오류 : 중복 키 값이 고유 제한 조건을 위반 함'을 피하도록 테이블 구조 수정


15

이런 식으로 만들어진 테이블이 있습니다.

--
-- Table: #__content
--
CREATE TABLE "jos_content" (
  "id" serial NOT NULL,
  "asset_id" bigint DEFAULT 0 NOT NULL,
   ...
  "xreference" varchar(50) DEFAULT '' NOT NULL,
  PRIMARY KEY ("id")
);

나중에 id를 지정하여 일부 행이 삽입됩니다.

INSERT INTO "jos_content" VALUES (1,36,'About',...)

나중에 일부 레코드가 ID없이 삽입되고 오류가 발생하여 실패합니다 Error: duplicate key value violates unique constraint.

분명히 ID는 시퀀스로 정의되었습니다.

여기에 이미지 설명을 입력하십시오

실패한 각 삽입은 더 이상 존재하지 않고 쿼리가 성공할 때까지 포인터를 시퀀스에서 증가시킵니다.

SELECT nextval('jos_content_id_seq'::regclass)

테이블 정의에 어떤 문제가 있습니까? 이것을 고치는 현명한 방법은 무엇입니까?


PostgreSQL에서는 열과 테이블 이름이 모두 소문자 인 경우 인용 할 필요가 없습니다.
로드리고

답변:


19

테이블 정의에 문제가 없습니다.
(내가 사용하는 것 모자를 제외하고 jos_content_id또는 대신 비 설명 열 이름의 무언가 id.
그리고 나는 아마 것 사용 text대신에varchar(50) .

당신의 INSERT진술은 문제입니다.

id열을로 정의 하면에 대한 serial수동 값을 삽입해서는 안됩니다 id. 그것들은 연관된 시퀀스의 다음 값과 충돌 할 수 있습니다.

목표 컬럼의 명시 적 목록을 제공하고 (항상 지속 INSERT명령문에 대해 항상 좋은 아이디어 임) 직렬 컬럼을 완전히 생략하십시오 .

INSERT INTO jos_content(asset_id, some_column, ...)
VALUES (36,'About',...);

자동으로 생성 된 열의 값이 즉시 필요한 경우 다음 RETURNING절을 사용하십시오 .

INSERT ...
RETURNING id;  -- possibly more

SO에 대한이 관련 답변에 대한 자세한 내용 :

serial나중에 충돌 할 수 있는 열에 수동 항목이있는 경우 시퀀스를 현재 최대 값 id으로 설정하여 이를 한 번 수정 하십시오 .

SELECT setval('jos_content_id_seq', max(id))
FROM   jos_content;

의 열이 기본 열에서 이미 발견 된 jos_content_id_seq의 기본 이름은 어디입니까 jos_content.id? xhzt8_content_id_seq귀하의 경우 에있는 것 같습니다 .


업데이트 : 비슷한 문제가 SO에 나타 났으며 새로운 해결책을 찾았습니다.


varchar (50)보다 텍스트가 느리지 않습니까?
로드리고

2
@Rodrigo : Postgres에 없습니다. dba.stackexchange.com/a/21496/3684 보다 자세한 설명을 위해 위 링크가 있습니다 . 아니면 여기 dba.stackexchange.com/a/89433/3684
Erwin Brandstetter 1

마지막 테스트 < depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text >는 크기 제한이 편리한 대부분의 필드에서 varchar (n)이 더 빠르다는 것을 확신했습니다 (사람) 이름, 이메일, 주소, 종 이름 등). 길이를 확인하지 않으면 텍스트가 더 빠릅니다 (또는 같습니다).
로드리고
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.