繁体   English   中英

PostgreSQL在外键中使用常量

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM