PostgreSQL 中的派生类型

Derived type in PostgreSQL

是否可以从类型创建 "derived type"?喜欢 Java 中的 extends

例如我需要这些类型:

create type mytype as (
    f1 int,
    --many other fields...
    fn varchar(10)
);

create type mytype_extended as (
    f1 int,
    --many other fields...
    fn varchar(10),

    fx int --one field more
);

可以看出这是多余的。以后要改mytype,我也要改mytype_extended

我试过这个:

create type mytype as (
    f1 int,
    --many other fields...
    fn varchar(10)
);

create type mytype_extended as (
    mt mytype,

    fx int --one field more
);

但这导致 mytype_extended 只有 2 个字段,mt(我认为是复杂类型)和 fx,而不是 f1, f2... fn, fx.

有办法做到这一点吗?

您可以为此使用 table 继承,因为任何 table 都隐式定义了一个类型。引自 CREATE TABLE:

CREATE TABLE also automatically creates a data type that represents the composite type corresponding to one row of the table. Therefore, tables cannot have the same name as any existing data type in the same schema.

你的例子,tables:

create table mytype  (
    f1 int,
    --many other fields...
    fn varchar(10)
);

create table mytype_extended(
  fx int
) inherits (mytype);

用 psql 描述 table 时:

# \d mytype_extended

       Table "public.mytype_extended"
 Column |         Type          | Modifiers 
--------+-----------------------+-----------
 f1     | integer               | 
 fn     | character varying(10) | 
 fx     | integer               | 
Inherits: mytype

现在让我们向基础 table 添加一列并检查继承的 table 是否也得到它:

alter table mytype add other_column int;
# \d mytype_extended
          Table "public.mytype_extended"
    Column    |         Type          | Modifiers 
--------------+-----------------------+-----------
 f1           | integer               | 
 fn           | character varying(10) | 
 fx           | integer               | 
 other_column | integer               | 
Inherits: mytype

在 PostgreSQL 中,没有直接的类型继承,但您有几个选择:

1. Table inheritance

您可以创建继承 table 来创建继承类型(PostgreSQL 将始终为每个 table 创建一个具有相同名称的复合类型):

create table supertable (
  foo   int,
  bar   text
);

create table subtable (
  baz   int
) inherits (supertable);

2. Construct views using each other

因为视图(实际上)是 tables(rules),所以也为每个视图创建了一个类型:

create view superview
  as select null::int  foo,
            null::text bar;

create view subview
  as select superview.*,
            null::int  baz
     from   superview;

3. Type composition

这就是你试过的。一般来说,您可以更好地控制这个:

create type supertype as (
  foo   int,
  bar   text
);

create type subtype as (
  super supertype,
  baz   int
);

-- resolve composition manually
select get_foo(v),        -- this will call get_foo(subtype)
       get_foo((v).super) -- this will call get_foo(supertype)
from   (values (((1, '2'), 3)::subtype)) v(v);

+1 真类型继承?

PostgreSQL's documentation explicitly says,那个table继承不是标准的类型继承:

SQL:1999 and later define a type inheritance feature, which differs in many respects from the features described here.

然而,继承 table 的自动创建类型确实像真正的继承类型一样工作(它们可以使用,可以使用超类型):

-- if there is a get_foo(supertable) function,
-- but there is no get_foo(subtable) function:

select get_foo((1, '2')::supertable);  -- will call get_foo(supertable)
select get_foo((1, '2', 3)::subtable); -- will also call get_foo(supertable)

SQLFiddle