二つのテーブルを作ってみましょう。capitals というテーブルは 州都を持っており、これは市 (cities) でもあります。capitals テーブル はcity テーブルから継承されるべきだというのが自然な流れでしょう。
CREATE TABLE cities ( name text, population float, altitude int -- (in ft) ); CREATE TABLE capitals ( state char(2) ) INHERITS (cities);この場合、capitals の行は全ての属性(name(名前)、population(人口)、altitude(高度)を親テーブルの cities から継承します。名前の型はPostgres固有の可変長 ASCII 文字列であるtext型です。population の型は float で、倍精度浮動小数点数のためのPostgres固有の型です。州都には更に、state という州を示す属性が追加されます。Postgresでは、テーブルはゼロ以上のテーブルから継承することができ、 問い合わせはテーブルの全ての行、もしくはテーブルとその子孫全ての行を参照することができます。
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 | +----------+----------+
ここでは市の前の"ONLY"は、継承の階層の中の市の下にある テーブルではなく、cities のみで問い合わせが実行されるべきだということを 表しています。これまでに説明してきた沢山のコマンド(SELECT, UPDATE and 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 | +---------+----------+----------+
改善のために仕様変更された部分: Postgresの以前のバージョンでは、 デフォルトでは子テーブルにアクセスすることができませんでした。 これは間違いのもとで、また SQL99 違反でもありました。古い構文では、 サブテーブルを得るためには "*" をテーブル名に付加していました。 例えば下記のようになります。
SELECT * from cities*;現在でも "*" を付加することで子テーブルのスキャンを明確に指定したり、 "ONLY"を書くことで子テーブルをスキャンしないことを明確に することができます。しかしバージョン 7.1 からは、なにも指定されていない テーブル名のデフォルト動作では子テーブルもスキャンします。逆に、以前 のデフォルトはそうしないことでした。以前のデフォルト動作で作業 をしたい場合は設定変更のオプション SQL_Inheritance to off をつけて下さい。下記が例 です。SET SQL_Inheritance TO OFF;もしくは postgresql.conf ファイルにこの行を 追加してください。