2011-12-07 42 views
2

我想将MySQL数据库转换为Postgres。这是令人沮丧的,但稳步前进。我遇到的一个问题是将MySQL SET数据类型转换为Postgres。 MySQL中的SET数据类型与普通的ENUM类型不同,不能用CHECK约束来模拟。将MySQL SET数据类型转换为Postgres

据我所知,一个SET类型允许从列中存储零个或多个值。因此,像下面这样在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')) 
); 

但上面不允许“红,蓝”或“绿,红”等。

当然,以上只是一个简化。实际的数据库相当复杂,大约6列定义为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}虽然;如果不允许{red,red}是很重要的,那么你可以添加一个函数来检查数组中独特的色彩值,并调整CHECK约束:

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)) 
); 

另一种选择是,在列的简单标量值关联表一堆。但是,如果您有六个这样的列,这可能会很麻烦。你也可以使用Erwin的函数版本,如果你需要担心“套”中的NULL:

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'函数。无论您使用的是什么接口,都可以理解这些数组并将它们转换为您的语言的数组。 –

相关问题