您可以使用該列的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;
很好的答案。初讀時,它對我沒有幫助;不是因爲它允許紅色,紅色,而是因爲它似乎用那些花括號存儲數據。不過,我想我可以檢索值並用逗號加入它們。這口井可能工作。我一直在研究,似乎沒有任何其他解決方案。謝謝。 – punkish
oooohh ...我回我的評論。答案仍然很好,但對我來說根本不起作用。最主要的原因是,我實際上無法將MySQL中現有的100萬行+行轉換爲Postgres,而實際上並未改變過程中的數據。 – punkish
@punkish:我添加了一個解決唯一性問題的方法。大括號是PostgreSQL顯示數組的方式。如果你真的希望它們以單個字符串的形式出現在數據庫中,有一個'array_to_string'函數。無論您使用的是什麼接口,都可以理解這些數組並將它們轉換爲您的語言的數組。 –