2011-12-07 4 views
2

MySQL 데이터베이스를 Postgres로 변환하려고합니다. 실망 스럽지만 꾸준히 진행됩니다. 저를 곤란하게 만들었던 하나의 이슈는 MySQL SET 데이터 타입을 Postgres로 변환하는 것입니다. MySQL의 SET 데이터 유형은 일반 ENUM 유형과 동일하지 않으며 CHECK 제약 조건으로 에뮬레이션 될 수 없습니다.MySQL SET 데이터 형식을 Postgres로 변환

필자가 이해하는 한, SET 유형을 사용하면 열에 집합의 0 개 이상의 값을 저장할 수 있습니다. 그래서,

CREATE TABLE foo (color SET('red','green','blue')); 

MySQL의

에 다음과 같이는 유효한 값

'' 
'red' 
'red,blue' 
'green,red' 

등 다음 중 하나를 수 있습니다. 포스트 그레스에서의 근사치는

CREATE TABLE foo (
    color VARCHAR(10) NOT NULL, 
    CHECK (color IN ('red','green','blue')) 
); 

하지만 위 ', 빨강, 파랑'또는 '녹색, 빨강'등을 허용하지 않습니다.

물론 위의 내용은 단순화 된 것입니다. 실제 데이터베이스는 SET로 정의 된 약 6 개 열로 상당히 복잡합니다.

제안 사항?

당신은 CHECK 제약 조건에 대한 열의 배열과 "is contained by" 연산자를 사용할 수

답변

7

:이 같은

create table pancakes (
    color varchar(10)[] not null, 
    check (color <@ ARRAY['red', 'green', 'blue']::varchar[]) 
); 

그리고 일이 일어날 :

=> insert into pancakes values (ARRAY['red']); 
INSERT 0 1 
=> insert into pancakes values (ARRAY['red','green','blue']); 
INSERT 0 1 
=> insert into pancakes values (ARRAY['red','green','blue','black']); 
ERROR: new row for relation "pancakes" violates check constraint "pancakes_color_check" 
=> select * from pancakes; 
     color  
------------------ 
{red} 
{red,green,blue} 
(2 rows) 

이 열의 {red,red}을하지만 수 ; 또 다른 옵션은 열에서 간단한 스칼라 값과 관련 테이블의 더미 것

create function has_unique_colors(varchar[]) returns boolean as $$ 
    select (select count(distinct c) from unnest($1) as dt(c)) = array_length($1, 1); 
$$ language sql; 

create table pancakes (
    color varchar(10)[] not null, 
    check (color <@ ARRAY['red', 'green', 'blue']::varchar[] and has_unique_colors(color)) 
); 

: {red,red}를 허용하지 않는 것이 중요하다면, 당신은 CHECK 제약 조건을 배열의 고유의 색상 값을 확인하고 조정하는 기능을 추가 할 수 있습니다 . 그러나이 열이 여섯 개인 경우이 작업은 번거로울 수 있습니다. "집합"의 NULL에 대해 걱정할 필요가 있다면 Erwin의 함수 버전을 사용할 수도 있습니다.

create function has_unique_colors(varchar[]) returns boolean as $$ 
    select not exists(select c from unnest($1) dt(c) group by 1 having count(*) > 1); 
$$ language sql; 
+0

좋은 대답입니다. 처음에는 독서가 도움이되지 않습니다. 빨강, 빨강을 허용하기 때문에가 아니라 중괄호로 데이터를 저장하는 것처럼 보이기 때문입니다. 그러나 값을 검색하고 쉼표로 값을 결합 할 수 있다고 생각합니다. 이 우물이 효과가있을 수 있습니다. 나는 연구를 해왔고 다른 해결책은없는 것처럼 보인다. 감사. – punkish

+0

oooohh ... 나는 내 의견을 다시 받아 들인다. 대답은 여전히 ​​훌륭하지만 전혀 작동하지 않습니다. 주된 이유는 실제로 프로세스의 데이터를 변경하지 않고 MySQL의 기존 1 백만 개 행을 Postgres로 변환 할 수 없다는 것입니다. – punkish

+0

@ punkish : 고유성 문제를 해결할 수있는 방법을 추가했습니다. 중괄호는 PostgreSQL이 배열을 표시하는 방법입니다. 단일 문자열로 데이터베이스에서 실제로 나오길 원한다면'array_to_string' 함수가 있습니다. 사용하는 인터페이스가 무엇이든간에 배열을 이해하고 언어로 배열로 변환 할 수 있습니다. –

관련 문제