2014-10-15 5 views
2

PostgreSQL의 테이블에 대소 문자를 구별하지 않는 외래 키 제약 조건을 추가 할 수 있는지 알아야합니다. MySQL에서 PostgreSQL으로 DB를 변환하려고합니다. 외래 키는 이미 MySQL에서 작성되었으며 MySQL은 대소 문자를 구분하지 않으므로 아무런 문제가 발생하지 않았습니다. MySQL에서 PostgreSQL으로 모든 데이터를로드 한 다음 외래 키를 테이블에 추가하려고하면 Postgres에 오류가 발생합니다. 예를 들어대소 문자를 구별하지 않는 외래 키 PostgreSQL

표 A 2 열했다 : ID (INT) 및 이름 (VARCHAR (25))

Entry1: ID = 1 , Name = 'America' Entry2: ID = 2 , Name = 'Canada'

표 B 2 열했다 : ID (INT) 및 이름 (VARCHAR (25))

Entry1: ID(int) = 10 , Name(Varchar(25)) = 'AmeRiCA' Entry1: ID = 1 , Name = 'Canada'

가있는 MySQL 외래 키 때문에 대소 문자 특성 그러나 포스트 그레스에서 열 "이름"표 A 및 표 B 사이에 생성 된 I g et 오류.

테이블을 변경하고 Varchar를 citext로 변경할 수있는 옵션이 없습니다. 어쨌든 PG에서 대소 문자를 구분하지 않는 외래 키를 정의 할 수 있습니다.

제안 사항?

감사합니다.

+1

당신의 질문은 흥미 롭습니다. 그러나 나는 궁금합니다. 왜 이드 대신에 (fk를 만들기 위해) 이름을 키로 사용 하시겠습니까? –

+1

@JorgeCampos -이 DB를 처음 보았을 때 내 마음에 들었던 것과 같은 질문입니다. 이 DB는 이미 만들어져 나에게 넘겨졌습니다. 그럼, 어쨌든이 일을 성취 할 수 있다고 생각합니까? – WinSupp

+0

citext 옵션을 사용하지 않으면 삽입/업데이트/삭제 전에 해당 행이 하위 또는 상위 기능을 사용하는지 확인하기 위해 트리거를 만들어야한다고 생각합니다. 나는 그 추한 것을 안다! –

답변

1

훨씬 더 좋은 방법은 데이터를 수정하는 것입니다.

create or replace function name_lower_trigger() returns trigger as $$ 
    begin 
    NEW.name_lower=lower(name); 
    return NEW; 
    end; 
$$ language plpgsql; 

create trigger a_name_lower_trigger 
    before insert or update on a 
    for each row execute procedure name_lower_trigger(); 
create trigger b_name_lower_trigger 
    before insert or update on b 
    for each row execute procedure name_lower_trigger(); 

그리고 외국을 만듭니다

는 다음 두 테이블의 추가 열을 생성 할 수 있습니다 받아 들일 수 있다면
update A set name=initcap(name) where name<>initcap(name); 
update B set name=initcap(name) where name<>initcap(name); 

가 자동 트리거를 사용하여 lower(name)로 설정 될 것이다, name_lower 말 :이 같은 예를 들어, 이러한 열을 사용하는 키 제약 조건. 그러나 데이터베이스를 비정규 화하고 저장 공간을 낭비하고 추한 것입니다. 데이터를 수정하는 것이 훨씬 더 좋습니다.

+0

이것은 거의 유일한 합리적인 해결책입니다. 유일한 다른 대안은 강제 소문자 비교 또는 일부를 수행하는 자신의 외래 키 트리거를 구현하는 것입니다. –