2011-12-07 10 views
2

MySQLデータベースをPostgresに変換しようとしています。それはイライラしていますが、着実に進行しています。私が困惑している問題の1つは、MySQL SETデータ型をPostgresに変換することです。 MySQLのSETデータ型は、通常のENUM型と同じではなく、CHECK制約でエミュレートすることはできません。MySQL SETデータ型をPostgresに変換する

私が理解する限り、SET型では、列のセットの0個以上の値を格納できます。だから、MySQLの

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

に次のようなものはそうで次のように有効な値

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

とのいずれかを許可します。 Postgresの中の近似は

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

であるが、上記「赤、青」または「緑色、赤色」などはできません。

もちろん、上記は単純化したものです。実際のデータベースは、SETと定義される約半ダースの列でかなり複雑です。

提案?

答えて

7

あなたは列の配列とCHECK制約の"is contained by"演算子使用することができます

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制約を配列のユニークな色の値をチェックし、調整する機能を追加することができます。ただし、これらの列が6つある場合は、これは面倒です。 "セット"の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の既存の100万行以上をPostgresに変換することはできません。 – punkish

+0

@punkish:私は、一意性問題を回避する方法を追加しました。中カッコはPostgreSQLが配列をどのように表示するかだけです。あなたが本当にそれらが単一の文字列としてデータベースから出てくるようにするには、 'array_to_string'関数があります。使用しているインタフェースが何であれ、配列を理解し、それらを配列言語に変換することもできます。 –

関連する問題