“表继承”意味着与“类继承”不同的东西,它们有不同的用途。
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 形式理解的方法about 故意降低了灵活性。
关于继承作为示意图设备,还有一件事需要指出:从 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 定义表的表,该表指向扩展数据(如果同类是泛型类型本身,则表示没有)。针对这种模式编写表函数、视图等非常容易,以至于当您诉诸 OOP 风格的类继承来创建对象类型系列时,大多数 ORM 框架都会在后台执行此类操作。