PostgreSQL外键 - 没有唯一约束条件

11

我有以下情况:

我有一张表格,其中包含各种语言的文本条目。它被定义如下:

    CREATE TABLE text
    (
      textid character varying(70) NOT NULL,
      language character varying(10) NOT NULL,
      content text NOT NULL,
      CONSTRAINT text_pk PRIMARY KEY (textid , language ),
      CONSTRAINT languages_text_fk FOREIGN KEY (language)
          REFERENCES languages (language) MATCH SIMPLE
          ON UPDATE CASCADE ON DELETE RESTRICT
    );

语言表只是一个语言代码列表,与实际情况并不相关。

现在,在另一个表格中,我需要引用一段文本,但我不需要也不知道将使用哪种语言检索该文本。我只知道要检索的文本id。实际语言将由阅读文本的用户在运行时指定。

起初我创建了这个:

    CREATE TABLE content_text
    (
      contentid character varying(70) NOT NULL,
      textid character varying(70) NOT NULL,
      CONSTRAINT content_text_pk PRIMARY KEY (contentid , textid ),
      CONSTRAINT content_text_text_fk FOREIGN KEY (textid)
          REFERENCES text (textid) MATCH SIMPLE
          ON UPDATE CASCADE ON DELETE RESTRICT
    );

出现错误:

ERROR:对于被引用的表“text”,没有匹配给定键的唯一约束条件

我知道为了避免这个错误,我必须创建一个只包含textid的中间表格,该表格将由content和text引用,但我真的觉得这是过度设计了...仅仅为了这个而创建一张表格,尽管textid不是唯一的,但在我的想法中,它不应该被拒绝...

是否有更优雅的方法来解决这个问题?

2个回答

6
我知道为了避免这个错误,我必须创建一个仅包含textid的中间表,该表将被内容和文本引用,但我真的觉得这是过度设计...是否有更优雅的方法来解决这个问题?
不,没有。
据我所知,这也是SQL规范的一部分:外键必须引用唯一列。
此外,您绝对确定这个中介表在某些情况下不会变得有用吗?比如,包含父级text_id等元数据,以防您引入某些层次结构?或者更重要的是:“引用一段文本”而不知道或不需要“检索文本的语言”。

2

由于您已经创建了带有主键(textid,language)的表TEXT,因此您在CONTEXT_TEXT中的外键必须引用相同的主键。 因此:

 CREATE TABLE content_text
    (
      contentid character varying(70) NOT NULL,
      language character varying(10) NOT NULL,
      textid character varying(70) NOT NULL,
      CONSTRAINT content_text_pk PRIMARY KEY (contentid , textid),
      CONSTRAINT content_text_text_fk FOREIGN KEY (textid, language)
          REFERENCES text (textid, language) MATCH SIMPLE
          ON UPDATE CASCADE ON DELETE RESTRICT
    );

或者你可以从TEXT的主键中删除language。相反,你可以创建第二个唯一索引:

  CREATE TABLE text2
    (
      textid character varying(70) NOT NULL,
      language character varying(10) NOT NULL,
      content text NOT NULL,
      CONSTRAINT text_pk PRIMARY KEY (textid),
      CONSTRAINT languages_text_fk FOREIGN KEY (language)
          REFERENCES languages (language) MATCH SIMPLE
          ON UPDATE CASCADE ON DELETE RESTRICT, 
      unique (textid, language)
    );

1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - john16384

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接