PostgreSQL:复合类型和独立列之间的外键
PostgreSQL: Foreign key between composite type and independent columns
最小定义:
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
(以及许多其他 table)使用复合类型,但对于主要的 table(table1
),我不不要直接使用复合类型,因为复合类型不支持使用 Serial
.
由于 global_id
和 id1, 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
的 serial/sequence 行为,那也行得通。
您可以使用复合类型定义 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)
最小定义:
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
(以及许多其他 table)使用复合类型,但对于主要的 table(table1
),我不不要直接使用复合类型,因为复合类型不支持使用 Serial
.
由于 global_id
和 id1, 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
的 serial/sequence 行为,那也行得通。
您可以使用复合类型定义 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)