在Postgresql中使用tableoids作为外键

时间:2016-08-19 00:25:50

标签: postgresql

我想知道是否有可能在继承关系中引用tableoid' s作为外键。例如:

CREATE TABLE employee
(
  name TEXT,
  PRIMARY KEY(name, TABLEOID)
);

CREATE TABLE hourly_employee
(
  hours_worked INT,
  PRIMARY KEY(name)
) INHERITS(employee);

CREATE TABLE salaried_employee
(
  anniversary_date DATE,
  PRIMARY KEY(name)
) INHERITS(employee);

CREATE TABLE employee_training
(
  training_id SERIAL,
  due_date DATE,
  employee_name TEXT,
  emp_oid OID,
  PRIMARY KEY(training_id),
  FOREIGN KEY(employee_name, emp_oid) REFERENCES employee(name, TABLEOID)
);

INSERT INTO hourly_employee (name, hours_worked) VALUES ('Joe Smith', 40);
INSERT INTO salaried_employee(name, anniversary_date) VALUES ('Bob Brown', '2014-02-20');

INSERT INTO employee_training (due_date, employee_name, emp_oid) VALUES ('2016-08-16', 'Bob Brown', 'salaried_employee'::REGCLASS);

在此示例中,创建外键没有问题,但最后一次插入将失败并显示错误Key (employee_name, emp_oid)=(Bob Brown, 16403) is not present in table "employee",即使我可以确认16403是salaried_employee的正确表格。

有没有办法让这项工作?

1 个答案:

答案 0 :(得分:1)

遗憾的是遗产有一些严重的限制。多个元素(包括唯一索引/外键)仅适用于一个表而不适用于子表。就个人而言,我发现它没有我喜欢它那么有用。

我知道建议你重新设计很烦人,但在我看来,你可以选择一个包含可选列而不是父/子关系的表employee

CREATE TABLE employee
(
  name TEXT,
  employee_type TEXT,
  hours_worked INT,
  anniversary_date DATE,
  PRIMARY KEY(name, TABLEOID)
);

从长远来看,您经常会发现代码变得更简单,而且在DBMS之间也可以更加轻松。

您可以使用约束来确保为正确的类型输入了正确的字段,以管理每种类型必须使用哪些字段。

例如:

ALTER TABLE employee ADD CHECK (
    (type = 'hourly' and hours worked is not null) 
 or (type = 'salaried' and anniversary_date is not null))