定义类型层次结构

下图提供了一个简单类型层次结构的示例,该层次结构包含三个命名行类型。

图: 类型层次结构的示例


有三种类型。顶部是 person_t。person_t 的子代是 employee_t。employee_t 的子代是 sales_rep_t。

类型层次结构顶部的超类型包含一组字段,所有下层子类型都继承这些字段。在可以创建超类型的子类型之前,该超类型必须已存在。以下示例创建图 1 显示的类型层次结构的 person_t 超类型:
CREATE ROW TYPE person_t
(
      name     VARCHAR(30) NOT NULL,
      address  VARCHAR(20),
      city    VARCHAR(20),
      state   CHAR(2),
      zip      INTEGER,
      bdate    DATE
);
要创建子类型,请指定 UNDER 关键字以及子类型继承其属性的超类型的名称。以下示例说明可以如何将 employee_t 定义为继承 person_t 的所有字段的子类型。此示例添加在 person_t 类型中不存在的 salarymanager 字段。
CREATE ROW TYPE employee_t 
(
      salary   INTEGER,
      manager  VARCHAR(30)
) 
UNDER person_t;
重要: 您必须对超类型具有 UNDER 特权,才能创建继承该超类型属性的子类型。有关 UNDER 特权的信息,请参阅对命名行类型的 Under 特权
图 1 的类型层次结构中,sales_rep_temployee_t 的子类型,而 employee_tsales_rep_t 的超类型,就像 person_temployee_t 的超类型一样。以下示例创建 sales_rep_t, 它继承 person_temployee_t 的所有字段并添加了四个新字段。由于对子类型所作的修改不会影响它的超类型,所以 employee_t 不具有对 sales_rep_t 添加的那四个字段。
CREATE ROW TYPE sales_rep_t 
(
rep_num      INT8,
region_num   INTEGER,
commission   DECIMAL,
home_office  BOOLEAN
) 
UNDER employee_t;

sales_rep_t 类型包含 12 个字段:nameaddresscitystatezipbdatesalarymanagerrep_numregion_numcommissionhome_office

employee_tsales_rep_t 类型的实例都继承对 person_t 类型所定义的所有 UDR。 对 employee_t 定义的其他任何 UDR 都自动应用于 employee_t 类型的实例,并应用于其子类型 sales_rep_t 的实例,但不应用于 person_t 的实例。

在前述类型层次结构中,由于每个子类型从单一超类型继承,所以此类型层次结构是单一继承的一个示例。图 2 说明了可以如何在单个超类型下面定义多个子类型。尽管单一继承要求每个子类型都从一个且只从一个超类型继承,但是对定义的类型层次结构的深度或宽度不存在实际限制。

图: 树结构类型层次结构的示例


顶部类型是“person_t”。“person_t”有两个子代:“employee_t”和“customer_t”。 “employee_t”有两个子代:“sales_rep_t” 和“engineer_t”。 “sales_rep_t”和“engineer_t”下面是垂直方向省略号,表示还有层次结构,但此处未显示。 “customer_t”(“employee_t”的兄弟,“person_t”的子代)有两个子代:“us_customer_t”和“non_us_customer_t”。“non_us_customer_t”没有子代。“us_customer_t”有两个子代:“local_customers_t” 和“regional customers_t”。 “local_customers_t”和“regional customers_t”下面是垂直方向省略号,表示还有层次结构,但此处未显示。

任何层次结构的最顶部的类型都称为根超类型。 在图 2 中,person_t 是层次结构的根超类型。除根超类型以外,层次结构中的任何类型都有可能同时既作为超类型又作为子类型。例如:customer_tperson_t 的子类型和 us_customer_t 的超类型。在层次结构中位于较低层的子类型包含根超类型的属性,但不直接从根超类型继承属性。例如:us_customer_t 只有一个超类型 customer_t,但由于 customer_t 本身是 person_t 的子类型,所以,customer_tperson_t 继承的字段和例程也由 us_customer_t 继承。