PostgreSQL中的派生类型

blu*_*ish 8 sql postgresql types derived-types

是否可以从类型中创建"派生类型"?就像extends在Java中一样.

例如,我需要这些类型:

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
);
Run Code Online (Sandbox Code Playgroud)

你可以看到这是多余的.如果将来我会改变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
);
Run Code Online (Sandbox Code Playgroud)

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

有没有办法实现这个目标?

poz*_*ozs 6

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

1.表继承

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

create table supertable (
  foo   int,
  bar   text
);

create table subtable (
  baz   int
) inherits (supertable);
Run Code Online (Sandbox Code Playgroud)

2.使用彼此构建视图

因为视图(实际上)是表(带有规则),所以也为它们中的每一个创建了一个类型:

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

create view subview
  as select superview.*,
            null::int  baz
     from   superview;
Run Code Online (Sandbox Code Playgroud)

3.键入组成

这就是你尝试过的.一般来说,你对这个有更多的控制权:

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);
Run Code Online (Sandbox Code Playgroud)

+1真正的类型继承?

PostgreSQL的文档明确指出,表继承不是标准的类型继承:

SQL:1999及更高版本定义了一种类型继承功能,它在许多方面与此处描述的功能不同.

尽管如此,继承表的自动创建类型确实像真正的继承类型一样工作(可以使用它们,可以使用超类型):

-- 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)
Run Code Online (Sandbox Code Playgroud)

SQLFiddle