[英]PostgreSQL using constants in foreign key
如官方文檔中所述,外鍵的語法包括表A中的列集引用表B中的列集。
是否可以在外鍵聲明中使用Constant?
問題是,我有表DICTIONARIES,它包含所有字典值,由TYPE區分。 我知道這不是好設計,但不幸的是,我沒有太多話要說,因為數據庫管理員希望'盡量減少表的數量'......
是否有可能實現這樣的目標:
CREATE TABLE PERSON (
id integer primary key,
country_id integer,
...
FOREIGN KEY ('COUNTRY', country_id) REFERENCES DICTIONARIES(TYPE, ID)
)
它將有效地解決這個問題。 我知道我可以向表人添加列,這個列只有一個可能的值'COUNTRY',或者我可以寫一個觸發器,但我寧願避免這樣做以保持設計更清潔。
外鍵約束是從一個表的列到另一個列的列,因此,沒有。
當然,數據庫應該有一個表COUNTRY(country_id)。 評論者指出,您的管理員正在強加反模式。
好的,您知道您可以定義一個列並將其設置為您想要的值並在其上創建外鍵。 這是用於避免限制某些子類型方案的觸發器的習慣用法。
您可以至少根據您的DBMS計算“COUNTRY”列。
您的問題基本上就是這個問題,請參閱問題的結尾以及評論和答案。
(許多功能實現起來都很簡單。也許困難(除了消費者的無知)是任意約束在計算上變得非常昂貴。這可能只會讓供應商變得更加惡化。而且,SQL的優化受到與對等模型的差異的阻礙。 )
對於沒有計算(或常量)列的Posrgres,可以使用DEFAULT
plus(可能)檢查將它們強制為固定值列。 這可能很難看,但它有效:
CREATE TABLE dictionaries
( id integer primary key
, typename varchar NOT NULL CHECK ( typename IN ('person' ,'animal' ,'plant' ))
, content varchar NOT NULL
-- ...
, UNIQUE (typename, id)
, UNIQUE (typename, content)
);
CREATE TABLE person
( id integer primary key
, typename varchar NOT NULL DEFAULT 'person' CHECK( typename IN ('person' ))
, species_id integer
-- ...
, FOREIGN KEY (typename, species_id) REFERENCES dictionaries(typename, id) -- DEFERRABLE INITIALLY DEFERRED
);
INSERT INTO dictionaries( id, typename, content) VALUES
( 1 , 'person' , 'Bob')
,( 2 , 'person' , 'Alice')
,( 11 , 'animal' , 'monkey')
,( 12 , 'animal' , 'cat')
,( 13 , 'animal' , 'dog')
,( 21 , 'plant' , 'cabbage')
;
SELECT * FROM dictionaries;
-- this should succeed
INSERT INTO person( id, species_id) VALUES
( 1,1 )
,( 2,2 )
;
-- this should fail
INSERT INTO person( id, species_id) VALUES
( 3,11 )
,( 4,12 )
;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.