PostgreSQL:复合类型和独立列之间的外键

时间:2019-02-08 09:55:49

标签: postgresql foreign-keys composite-key compositetype

最小定义:

CREATE TYPE GlobalId AS (
  id1 BigInt,
  id2 SmallInt
);

CREATE TABLE table1 (
  id1 BigSerial NOT NULL,
  id2 SmallInt NOT NULL,
  PRIMARY KEY (id1, id2)
);

CREATE TABLE table2 (
  global_id GlobalId NOT NULL,
  FOREIGN KEY (global_id) REFERENCES table1 (id1, id2)
);

简而言之,我为table2(和许多其他表)使用了复合类型,但是对于主表(table1),我没有直接使用复合类型,因为复合类型没有不支持使用Serial

由于global_idid1, id2之间表面上的不匹配,以上内容产生了以下错误:number of referencing and referenced columns for foreign key disagree

或者,如果我将外键定义为FOREIGN KEY (global_id.id1, global_id.id2) REFERENCES table1 (id1, id2),则在global_id上使用访问器时会出现语法错误。

关于如何定义此外键关系的任何想法?另外,如果table1有一种使用GlobalId复合类型的方式,同时仍然获得id1的串行/顺序行为,那也可以。

1 个答案:

答案 0 :(得分:0)

您可以使用复合类型定义table1,并使用BEFORE触发器填充值:

CREATE TABLE table1 (id globalid PRIMARY KEY);

CREATE SEQUENCE s OWNED BY table1.id;

CREATE FUNCTION ins_trig() RETURNS trigger LANGUAGE plpgsql AS
$$BEGIN
   NEW.id = (nextval('s'), (NEW.id).id2);
   RETURN NEW;
END;$$;

CREATE TRIGGER ins_trig BEFORE INSERT ON table1 FOR EACH ROW
   EXECUTE PROCEDURE ins_trig();

INSERT INTO table1 VALUES (ROW(NULL, 42));

SELECT * FROM table1;
   id   
--------
 (1,42)
(1 row)