“表继承”的含义不同于“类继承”,并且它们具有不同的用途。
Postgres都是关于数据定义的。有时确实是非常复杂的数据定义。OOP(在一般的Java颜色意义上来说)是关于将行为从属于单个原子结构中的数据定义。“继承”一词的目的和含义在这里有很大的不同。
在OOP领域中,我可能会定义(此处的语法和语义非常宽松):
import life
class Animal(life.Autonomous):
metabolism = biofunc(alive=True)
def die(self):
self.metabolism = False
class Mammal(Animal):
hair_color = color(foo=bar)
def gray(self, mate):
self.hair_color = age_effect('hair', self.age)
class Human(Mammal):
alcoholic = vice_boolean(baz=balls)
表格如下所示:
CREATE TABLE animal
(name varchar(20) PRIMARY KEY,
metabolism boolean NOT NULL);
CREATE TABLE mammal
(hair_color varchar(20) REFERENCES hair_color(code) NOT NULL,
PRIMARY KEY (name))
INHERITS (animal);
CREATE TABLE human
(alcoholic boolean NOT NULL,
FOREIGN KEY (hair_color) REFERENCES hair_color(code),
PRIMARY KEY (name))
INHERITS (mammal);
但是这些行为在哪里呢?它们不适合任何地方。这不是数据库世界中讨论的“对象”的目的,因为数据库关注的是数据,而不是过程代码。您可以在数据库中编写函数来为您做计算(通常是一个很好的主意,但实际上并不适合这种情况),但是函数与方法并不相同,即您所谈论的OOP形式的方法故意降低灵活性。
关于作为一种原理性设备的继承,还有一点要指出:从Postgres 9.2开始,无法立即在所有分区/表族成员之间引用外键约束。您可以编写检查来执行此操作或以其他方式解决它,但是它不是内置功能(实际上归结为复杂索引的问题,而且没有人编写使该功能自动化的必要位)。除了为此目的使用表继承之外,数据库中对象继承的更好匹配通常是对表进行示意图扩展。像这样:
CREATE TABLE animal
(name varchar(20) PRIMARY KEY,
ilk varchar(20) REFERENCES animal_ilk NOT NULL,
metabolism boolean NOT NULL);
CREATE TABLE mammal
(animal varchar(20) REFERENCES animal PRIMARY KEY,
ilk varchar(20) REFERENCES mammal_ilk NOT NULL,
hair_color varchar(20) REFERENCES hair_color(code) NOT NULL);
CREATE TABLE human
(mammal varchar(20) REFERENCES mammal PRIMARY KEY,
alcoholic boolean NOT NULL);
现在,我们有一个动物实例的规范引用,可以可靠地用作外键引用,并且我们有一个“ ilk”列,它引用了xxx_ilk定义表,该表指向扩展数据的“下一个”表(或表示如果ilk是泛型类型本身则不存在)。针对这种模式编写表函数,视图等非常容易,以至于大多数ORM框架在诉诸OOP样式类继承来创建对象类型族时,都会在后台执行此类操作。