Есть несколько основных причин использования наследования таблиц в postgres.
Допустим, у нас есть несколько таблиц, необходимых для статистики, которые создаются и заполняются каждый месяц:
statistics
- statistics_2010_04 (inherits statistics)
- statistics_2010_05 (inherits statistics)
В этом примере у нас есть 2 000 000 строк в каждой таблице. Каждая таблица имеет ограничение CHECK, чтобы убедиться, что в ней хранятся только данные за соответствующий месяц.
Так что же делает наследование классной функцией - почему классно разделять данные?
- ПРОИЗВОДИТЕЛЬНОСТЬ: при выборе данных мы ВЫБИРАЕМ * ИЗ статистики, ГДЕ дата МЕЖДУ x и Y, а Postgres использует только таблицы, где это имеет смысл. Например. SELECT * FROM statistics WHERE date BETWEEN '2010-04-01' AND '2010-04-15' сканирует только таблицу statistics_2010_04, все остальные таблицы не будут затронуты - быстро!
- Размер индекса: у нас нет большой толстой таблицы с большим жирным индексом на дату столбца. У нас есть маленькие таблицы в месяц, с маленькими индексами - более быстрое чтение.
- Обслуживание: мы можем запускать вакуумное полное, переиндексирование, кластер для каждой таблицы за месяц, не блокируя все остальные данные.
Чтобы узнать, как правильно использовать наследование таблиц для повышения производительности, смотрите руководство postgresql. Вам необходимо установить ограничения CHECK для каждой таблицы, чтобы сообщить базе данных, по какому ключу ваши данные разделяются (секционируются).
Я активно использую наследование таблиц, особенно когда дело касается хранения данных журнала, сгруппированных по месяцам. Подсказка: если вы храните данные, которые никогда не изменятся (данные журнала), создайте или индексируйте с помощью CREATE INDEX ON () WITH (fillfactor = 100); Это означает, что в индексе не будет зарезервировано место для обновлений - индекс на диске меньше.
ОБНОВЛЕНИЕ: по умолчанию fillfactor равно 100, из http://www.postgresql.org/docs/9.1/static/sql-createtable.html :
Коэффициент заполнения таблицы - это процент от 10 до 100. 100 (полная упаковка) - значение по умолчанию.
«Наследование таблиц» означает нечто иное, чем «наследование классов», и они служат другим целям.
Postgres - это все об определениях данных. Иногда действительно сложные определения данных. ООП (в обычном понимании вещей цвета Java) - это подчинение поведения определениям данных в единой атомарной структуре. Назначение и значение слова «наследство» здесь существенно различаются.
В области ООП я мог бы определить (здесь очень нечетко с синтаксисом и семантикой):
Таблицы для этого могут выглядеть так:
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);
Но где поведение? Они никуда не подходят. Это не цель «объектов», как они обсуждаются в мире баз данных, потому что базы данных связаны с данными, а не с процедурным кодом. Вы можете писать функции в базе данных для выполнения расчетов за вас (часто очень хорошая идея, но не совсем то, что подходит для этого случая), но функции - это не то же самое, что методы - методы, как они понимаются в форме ООП, о которой вы говорите 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, которая указывает на «следующую» таблицу расширенных данных ( или указывает, что его нет, если подобный тип сам является универсальным). Написание табличных функций, представлений и т. Д. На основе такой схемы настолько просто, что большинство фреймворков ORM делают именно такие вещи в фоновом режиме, когда вы прибегаете к наследованию классов в стиле ООП для создания семейств типов объектов.
источник
mammal JOIN human
, просто потому, что создание соединения каждый раз раздражает. Но не избегайте присоединений . Соединения - это то, что помещает R в СУБД. Если вам не нравятся объединения, вам следует использовать другой тип базы данных.Наследование можно использовать в парадигме ООП, если вам не нужно создавать внешние ключи для родительской таблицы. Например, если у вас есть автомобиль абстрактного класса, хранящийся в таблице транспортных средств, и таблица автомобилей, которая унаследована от нее, все автомобили будут видны в таблице транспортных средств, но внешний ключ из таблицы драйверов в таблице транспортных средств не будет соответствовать тезисам. записи.
Наследование также можно использовать как инструмент разделения . Это особенно полезно, когда у вас есть таблицы, которые должны постоянно расти (таблицы журналов и т. Д.).
источник
В основном наследование используется для разделения, но иногда оно полезно в других ситуациях. В моей базе данных много таблиц, различающихся только внешним ключом. Моя таблица "изображение" абстрактного класса содержит "ID" (первичный ключ для него должен быть в каждой таблице) и растр PostGIS 2.0. Унаследованные таблицы, такие как site_map или artifact_drawing, имеют столбец внешнего ключа (текстовый столбец site_name для site_map, целочисленный столбец artifact_id для таблицы artifact_drawing и т. Д.) И ограничения первичного и внешнего ключей; остальное наследуется от таблицы «image». Я подозреваю, что в будущем мне, возможно, придется добавить столбец «описание» ко всем таблицам изображений, так что это может сэкономить мне довольно много работы, не создавая реальных проблем (ну,
РЕДАКТИРОВАТЬ: еще одно хорошее применение: при обработке двух таблиц незарегистрированных пользователей у других СУБД есть проблемы с обработкой двух таблиц, но в PostgreSQL это просто - просто добавьте,
ONLY
когда вас не интересуют данные в унаследованной таблице «незарегистрированных пользователей».источник
Единственный опыт, который у меня есть с унаследованными таблицами, - это партиционирование. Он отлично работает, но это не самая сложная и простая в использовании часть PostgreSQL.
На прошлой неделе мы искали ту же проблему ООП, но у нас было слишком много проблем с Hibernate (не нравилась наша настройка), поэтому мы не использовали наследование в PostgreSQL.
источник
Я использую наследование, когда у меня есть отношения более чем 1 на 1 между таблицами.
Пример: предположим, вы хотите сохранить местоположения на карте объектов с атрибутами x, y, вращением, масштабом.
Теперь предположим, что у вас есть несколько различных типов объектов для отображения на карте, и каждый объект имеет свои собственные параметры местоположения на карте, и параметры карты никогда не используются повторно.
В этих случаях наследование таблиц было бы весьма полезным, чтобы избежать необходимости поддерживать ненормализованные таблицы или создавать идентификаторы местоположения и ссылаться на них с другими таблицами.
источник
Используйте его как можно реже. И это обычно означает никогда, это сводится к способу создания структур, которые нарушают реляционную модель, например, путем нарушения принципа информации и создания мешков вместо отношений.
Вместо этого используйте разделение таблицы в сочетании с правильным реляционным моделированием, включая другие нормальные формы.
источник