| PostgreSQL 7.4 文檔 | ||||
|---|---|---|---|---|
| Prev | Fast Backward | Chapter 5. 數據定義 | Fast Forward | Next |
讓我們創建兩個表。首府表包含每個州的首府,它們也是 城市。通常,首府表應該從城市表中繼承過來。
CREATE TABLE cities (
name text,
population float,
altitude int -- (單位:英尺)
);
CREATE TABLE capitals (
state char(2)
) INHERITS (cities);在這種情況下,一行首府從它的父表,城市表中繼承所有屬性(名字, 人口以及海拔)。name 的類型是 text,它是 PostgreSQL 的本生類型,用于變長 ASCII 字串。population 的類型是float, PostgreSQL 用于雙精度浮點數的本生類型。 州首府有一個額外的屬性,state,顯示它們所在的州。在 PostgreSQL 裡, 一個表可以從零個或多個其它表中繼承屬性,而且一個查詢既可以 引用一個表中的所有行,也可以引用一個表的所有行加上所有其 後代表的行。
注意: 繼承層次實際上是有向開環圖。
比如,下面的查詢查找所有海拔 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 ----------+-----------+---------- 139793 | Las Vegas | 2174 139793 | Mariposa | 1953 139798 | Madison | 845
(如果你想復現這個例子,你可能會得到不同的數字 OID.) 通過和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 ----------+-----------+---------- cities | Las Vegas | 2174 cities | Mariposa | 1953 capitals | Madison | 845
廢棄: 以前版本的 PostgreSQL 裡,缺省是不訪問 子表.我們發現這樣是容易出錯的而且違背 SQL99 標準.在舊語法裡面,要訪問 子表,你需要附加一個 * 到表名後面.例如
SELECT * from cities*;你仍然可以通過附加*明確聲明需要掃描子表, 也可以通過寫 "ONLY" 聲明明確聲明不掃描子表. 不過,從版本 7.1 開始,對那些不帶修飾的表名子的缺省行為是 同時掃描它的子表,而以前的缺省是正相反.要獲得老的缺省行為, 把配置選項 SQL_Inheritance 關閉,也就是︰
SET SQL_Inheritance TO OFF;或者向你的 postgresql.conf 文件裡面加一行.
繼承特性的一個局限性是索引(包括唯一約束)和外鍵約束只施用于 單個表,而不包括它們的繼承的子表.因此,在上面的例子裡, 聲明另外一個表的字段 REFERENCES cities(name) 將允許其它表包含城市名但不含首府名.這個缺陷可能在未來的 某個版本中得到修補.