2つのテーブルを作ってみましょう。capitals というテーブルで保持される州都は、市(cities)でもあります。capitals テーブルは cities テーブルから継承されるべきだというのが自然な流れでしょう。
CREATE TABLE cities ( name text, population float, altitude int -- (in ft) ); CREATE TABLE capitals ( state char(2) ) INHERITS (cities);
この場合、capitalsの行はすべての属性(name(名前)、population(人口)、altitude(高度))を親テーブルの cities から 継承 します。name属性の型は PostgreSQL 固有の可変長 ASCII 文字列である text 型です。population属性の型は PostgreSQL固有の倍精度浮動小数点数用の float 型です。州都にはさらに、state という州を示す属性が追加されます。 PostgreSQLでは、テーブルは 0 個以上のテーブルから継承することができ、問い合わせはテーブルのすべての行を参照することも、テーブルとその子孫すべての行を参照することも可能です。
Note: 継承の階層は非循環有向グラフです。
たとえば、次の問い合わせは、州都を含む、高度が500フィート以上にあるすべての市を見つけます。
SELECT name, altitude FROM cities WHERE altitude > 500;
この結果は以下のようになります。
+----------+----------+ |name | altitude | +----------+----------+ |Las Vegas | 2174 | +----------+----------+ |Mariposa | 1953 | +----------+----------+ |Madison | 845 | +----------+----------+
一方、次の問い合わせは、高度が 500フィート以上にあり州都ではないすべての市を見つけます。
SELECT name, altitude FROM ONLY cities WHERE altitude > 500; +----------+----------+ |name | altitude | +----------+----------+ |Las Vegas | 2174 | +----------+----------+ |Mariposa | 1953 | +----------+----------+
ここで、cities の前の "ONLY" は、この問い合わせは cities のみを対象とし、cities を継承したテーブルは対象外としなければならないことを表します。これまでに説明した多くのコマンド、SELECT、 UPDATE や DELETE は、この "ONLY" という構文をサポートしています。
場合によっては、ある特定のタプルがどのテーブルからきたものか知りたいということがあるかもしれません。それぞれのテーブルには "TABLEOID" という、元になったテーブルを示すシステム列があります。
SELECT c.tableoid, c.name, c.altitude FROM cities c WHERE c.altitude > 500;
この結果は以下のようになります。
+---------+----------+----------+ |tableoid |name | altitude | +---------+----------+----------+ |37292 |Las Vegas | 2174 | +---------+----------+----------+ |37280 |Mariposa | 1953 | +---------+----------+----------+ |37280 |Madison | 845 | +---------+----------+----------+
pg_class と結合することで、テーブルの実際の名前が判ります。
SELECT p.relname, c.name, c.altitude FROM cities c, pg_class p WHERE c.altitude > 500 and c.tableoid = p.oid;
この結果は以下のようになります。
+---------+----------+----------+ |relname |name | altitude | +---------+----------+----------+ |capitals |Las Vegas | 2174 | +---------+----------+----------+ |cities |Mariposa | 1953 | +---------+----------+----------+ |cities |Madison | 845 | +---------+----------+----------+
改善のために仕様変更された部分: PostgreSQL の以前のバージョンでは、デフォルトでは子テーブルにアクセスすることができませんでした。これは間違いのもとで、また SQL99 に違反していました。古い構文では、サブテーブルを得るためには * をテーブル名に付加していました。たとえば下記のようになります。
SELECT * from cities*;現在でも * を付加することで子テーブルのスキャンを明確に指定したり、"ONLY" を書くことで子テーブルをスキャンしないことを明確にすることができます。しかしバージョン 7.1 からは、何も指定されていないテーブル名のデフォルト動作では子テーブルもスキャンします。逆に、以前のデフォルトはそうしないことでした。以前のデフォルト動作で作業をしたい場合は設定オプション SQL_Inheritance をoffにして下さい。以下に例を示します。
SET SQL_Inheritance TO OFF;または、postgresql.conf に1行追加して下さい。
継承機能の制限として、(一意性制約を含む)インデックス、および、外部キーは、そのテーブルのみに適用され、それを継承した子テーブルには適用されないことがあります。従って、上の例で、他のテーブルの列に REFERENCES cities(name) を指定すると、そのテーブルは市の名前を持つことはできますが、州都の名前を持つことはできません。この欠陥は将来のリリースでおそらく修正されます。