«Наследование таблиц» означает нечто отличное от «наследования классов», и они служат различным целям.
Postgres - это все о определениях данных. Иногда действительно сложные определения данных. ООП (в общепринятом смысле цвета Java) - это подчинение поведения определениям данных в единой атомарной структуре. Цель и значение слова «наследование» здесь существенно различаются.
В области ООП я мог бы определить (будучи очень свободным с синтаксисом и семантикой здесь):
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);
Но где поведение? Они никуда не годятся. Это не цель "объектов", как они обсуждаются в мире баз данных, потому что базы данных связаны с данными, а не с процедурным кодом. Вы можете написать функции в базе данных для выполнения вычислений за вас (часто это очень хорошая идея, но не совсем то, что подходит для этого случая), но функции - это не то же самое, что методы - методы, понимаемые в форме ООП, о которой вы говорите. о намеренно менее гибки.
Есть еще одна вещь, которую следует отметить в отношении наследования как схематического устройства: Начиная с 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 делают именно такие вещи в фоновом режиме, когда вы прибегаете к наследованию классов в стиле ООП для создания семейств типов объектов.