在外键中使用常量的PostgreSQL

在外键中使用常量的PostgreSQL,sql,postgresql,foreign-keys,Sql,Postgresql,Foreign Keys,如中所述,外键的语法包括表A中的一组列引用表B中的一组列 可以在外键声明中使用常量吗 问题是,我有表字典,它包含所有字典值,按类型区分。我知道这不是一个好的设计,但不幸的是,我没有太多要说的,因为DB管理员想要“最小化表的数量” 是否有可能实现这样的目标: CREATE TABLE PERSON ( id integer primary key, country_id integer, ... FOREIGN KEY ('COUNTRY', country_id) REFEREN

如中所述,外键的语法包括表A中的一组列引用表B中的一组列

可以在外键声明中使用常量吗

问题是,我有表字典,它包含所有字典值,按类型区分。我知道这不是一个好的设计,但不幸的是,我没有太多要说的,因为DB管理员想要“最小化表的数量”

是否有可能实现这样的目标:

CREATE TABLE PERSON (
  id integer primary key,
  country_id integer,
  ...
  FOREIGN KEY ('COUNTRY', country_id) REFERENCES DICTIONARIES(TYPE, ID)
)

这将有效地解决这个问题。我知道我可以将列添加到person表中,该表只有一个可能的值'COUNTRY',或者我可以编写触发器,但为了保持设计更简洁,我宁愿避免这样做

外键约束是从一个表的列到另一个表的列,因此,不是

当然,数据库应该有一个表COUNTRY(COUNTRY\u id)。评论人士指出,您的管理员正在实施反模式

很好,您知道可以定义一列并将其设置为所需的值,然后在该列上生成外键。这是一个习惯用法,用于在约束某些子类型方案时避免触发器

至少可以根据DBMS计算“国家”列

您的问题本质上是,请参见问题的结尾以及评论和答案


(许多功能的实现都是微不足道的。可能困难在于(除了忽略消费者之外)任意约束在计算上很快变得昂贵。这可能会让供应商更加恼火。此外,SQL中的优化由于其与关系模型的差异而受阻。)

对于没有计算(或常量)列,您可以使用
DEFAULT
加上(可能)检查将它们强制为固定值列。这可能很难看,但它可以工作:

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

“因为DB管理员想‘最小化表的数量’——这是一个多么愚蠢的DBA。也许你可以告诉他,这是一个众所周知的设计反模式,称为“一个真正的查找表”,而这会给我带来满足感,并给我一个寻找新作品的绝好机会;)有许多应用程序已经使用了一个真正的查找表,所以我需要适应现有的体系结构多么糟糕的数据库设计。据我所知,你不能做你想做的事情。事实上,这样的功能应该很容易实现。已经有一个基于表中的值的检查,它可以很容易地与常量交换,或者因为索引问题而无法交换?是否存在不需要添加额外列的结构(非触发器)替代方案?+1,因为我从您的答案中了解了计算列。没有接触MSSQL,我不知道这个概念。不幸的是,这仍然是一个需要了解的重要术语:)