PostgreSQL中的派生类型

时间:2015-02-03 08:50:54

标签: sql postgresql types derived-types

是否可以从类型创建“派生类型”?与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

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

2 个答案:

答案 0 :(得分:5)

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

1. Table inheritance

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

create table supertable (
  foo   int,
  bar   text
);

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

2. Construct views using each other

因为视图是(实际上)表格(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,表继承不是标准的类型继承:

  

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)

SQLFiddle

答案 1 :(得分:2)

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

  

CREATE TABLE还会自动创建表示的数据类型   对应于表的一行的复合类型。因此,   表不能与同一个表中的任何现有数据类型具有相同的名称   架构。

您的示例,包含表格:

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

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

使用psql描述表时:

# \d mytype_extended

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

现在让我们在基表中添加一个列,并检查继承的表是否也得到它:

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