PostgreSQL 外键不存在,继承问题?

标签 postgresql inheritance foreign-keys

我正在努力处理数据库中的外键,这可能与继承有关吗?
所以这是基本设置:

-- table address
CREATE TABLE address
(
  pk_address serial NOT NULL,
  fk_gadmid_0 integer NOT NULL, -- this table already exists, no problem here
  street character varying(100),
  zip character varying(10),
  city character varying(50),
  public boolean,
  CONSTRAINT address_primarykey PRIMARY KEY (pk_address),
  CONSTRAINT gadmid_0_primarykey FOREIGN KEY (fk_gadmid_0)
      REFERENCES adm0 (gadmid_0) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);
ALTER TABLE address OWNER TO postgres;  

-- table stakeholder (parent)
CREATE TABLE stakeholder
(
    pk_stakeholder integer DEFAULT nextval('common_stakeholder_seq') NOT NULL,
    fk_stakeholder_type integer NOT NULL, -- this table also exists, no problem here
    name character varying(255) NOT NULL,
    CONSTRAINT stakeholder_primarykey PRIMARY KEY (pk_stakeholder),
    CONSTRAINT stakeholder_fk_stakeholder_type FOREIGN KEY (fk_stakeholder_type)
        REFERENCES stakeholder_type (pk_stakeholder_type) MATCH SIMPLE
        ON UPDATE CASCADE ON DELETE NO ACTION
)
WITH (
    OIDS=FALSE
);
ALTER TABLE stakeholder OWNER TO postgres;  

-- table individual (child of stakeholder)
CREATE TABLE individual
(
    firstname character varying(50),
    fk_title integer, -- this table also exists, no problem here
    email1 character varying (100),
    email2 character varying (100),
    phone1 character varying (50),
    phone2 character varying (50),
    CONSTRAINT individual_primarykey PRIMARY KEY (pk_stakeholder),
    CONSTRAINT title_foreignkey FOREIGN KEY (fk_title)
        REFERENCES title (pk_title) MATCH SIMPLE
        ON UPDATE CASCADE ON DELETE CASCADE
) INHERITS (stakeholder)
WITH (
    OIDS=FALSE
);
ALTER TABLE individual OWNER TO postgres;  

-- link between stakeholder and address
CREATE TABLE l_stakeholder_address
(
    pk_l_stakeholder_address serial NOT NULL,
    fk_stakeholder integer NOT NULL REFERENCES stakeholder,
    fk_address integer NOT NULL REFERENCES address,
    CONSTRAINT l_stakeholder_address_primarykey PRIMARY KEY (pk_l_stakeholder_address),
    CONSTRAINT l_stakeholder_address_fk_stakeholder FOREIGN KEY (fk_stakeholder)
        REFERENCES stakeholder (pk_stakeholder) MATCH SIMPLE
        ON UPDATE CASCADE ON DELETE NO ACTION,
    CONSTRAINT l_stakeholder_address_fk_address FOREIGN KEY (fk_address)
        REFERENCES address (pk_address) MATCH SIMPLE
        ON UPDATE CASCADE ON DELETE NO ACTION
)
WITH (
    OIDS=FALSE
);
ALTER TABLE l_stakeholder_address OWNER TO postgres;

到目前为止,没问题。然后我尝试添加一些值:

INSERT INTO individual (pk_stakeholder, fk_stakeholder_type, name, firstname, fk_title, email1, email2, phone1, phone2) 
  VALUES (1, 8, 'Lastname', 'Firstname', 1, 'me@you.com', '', '', '');
INSERT INTO address (pk_address, fk_gadmid_0, street, zip, city, public)  
  VALUES (1, 126, 'Address', '', 'City', FALSE);
INSERT INTO l_stakeholder_address (pk_l_stakeholder_address, fk_stakeholder, fk_address)  
  VALUES (DEFAULT, 1, 1);

最后我遇到了一个错误(SQL 状态 23503),指出表“stakeholder”中不存在键 (fk_stakeholder)=(1)。
前 2 个插入没问题,我可以在数据库中看到它们:

stakeholder:
pk_stakeholder | ...
----------------------
1              | ...

address:
pk_address | ...
--------------------
1          | ...

我做错了什么?我必须承认我是 PostgreSQL 的新手(使用 8.4),但我什至不确定这是否是 PG 的问题,也许我只是缺乏一些基本的数据库设计理解......
无论哪种方式,到目前为止我几乎尝试了所有我能想到的方法,我还尝试使 FK 可延迟,如 PostgreSQL : Transaction and foreign key problem但不知何故,这也不起作用。

最佳答案

您可以使用附加表individual_pks(individual_pk integer primary key)来解决它,其中包含来自父项和子项的所有主键,这将使用触发器进行维护(非常简单 - 插入 individual_pks 在插入时从中删除,在更新时更新它,如果它更改 individual_pk)。

然后您将外键指向这个附加表而不是子表。会有一些小的性能影响,但仅限于添加/删除行时。

或者忘记继承并以旧方式进行 - 只需一个包含一些可为空列的表。

关于PostgreSQL 外键不存在,继承问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4940974/

相关文章:

ASP.NET页面继承: Controls from base class are not initialized

c++ - 如何使用函数(而非构造函数)将派生类对象分配给基类指针

node.js - Sequelize : Able to create even foreignKey is deleted (paranoid type)

MYSQL 外键设置

ruby-on-rails - 获取一天中特定时间之后创建的记录

php - 找不到 ubuntu php_pgsql.dll

sql - 如何在 PostgreSQL 中获取数组值的索引?

sql - 从包含特定列的所有表中选择行

c++ - "specialize"一个基对象变成派生对象?

mysql - 是否可以让一个包含多个值的 MySQL 列作为外键?