【问题标题】:Derived type in PostgreSQLPostgreSQL 中的派生类型
【发布时间】:2015-04-02 09:39:37
【问题描述】:

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

有没有办法做到这一点?

【问题讨论】:

    标签: sql postgresql types derived-types


    【解决方案1】:

    在 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

    【讨论】:

      【解决方案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 表“public.mytype_extended” 专栏 |类型 |修饰符 --------+-----------+------------ f1 |整数 | fn |字符变化(10) | 外汇 |整数 | 继承:mytype

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

      alter table mytype add other_column int;
      
      # \d mytype_extended 表“public.mytype_extended” 专栏 |类型 |修饰符 --------------+-----------+------------ f1 |整数 | fn |字符变化(10) | 外汇 |整数 | 其他列 |整数 | 继承:mytype

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-02
        • 1970-01-01
        • 1970-01-01
        • 2012-09-08
        • 1970-01-01
        • 2012-10-23
        • 2019-03-02
        • 1970-01-01
        相关资源
        最近更新 更多