2011-12-07 41 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'函數。無論您使用的是什麼接口,都可以理解這些數組並將它們轉換爲您的語言的數組。 –

相關問題