2015-02-03 9 views
6

Ist es möglich, einen "abgeleiteten Typ" von einem Typ zu erstellen? Wie extends in Java.Abgeleiteter Typ in PostgreSQL

Zum Beispiel muss ich diese Typen:

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 
); 

Sie können sehen, dass dies überflüssig ist. Wenn ich in Zukunft mytype ändern werde, muss ich auch mytype_extended ändern.

Ich habe versucht, dieses:

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

create type mytype_extended as (
    mt mytype, 

    fx int --one field more 
); 

aber dies führt mytype_extended nur 2 Felder zu haben, mt (ein komplexer Typ, glaube ich) und fx, statt f1, f2... fn, fx.

Gibt es eine Möglichkeit, dies zu erreichen?

Antwort

5

In PostgreSQL, gibt es keine direkte Art Vererbung ist, aber Sie haben ein paar Optionen:

1. Table inheritance

Sie Tabellen geerbt erstellen, um vererbte Typen zu erstellen (PostgreSQL immer einen zusammengesetzten Typ für jede Tabelle erstellen, mit dem gleichen Namen):

create table supertable (
    foo int, 
    bar text 
); 

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

2. Construct views using each other

Weil Ansichten sind (in Wirklichkeit) Tabellen (mit rules) ist ein Typ für jeden von ihnen zu erstellt:

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

Dies ist, was haben Sie versucht. Sie haben mehr Kontrolle mit diesem im Allgemeinen:

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 Truetype-Erbe?

PostgreSQL's documentation explicitly says, ist, dass Tabelle Vererbung nicht der Typ Vererbung der Standard:

SQL: 1999 und später eine Art Vererbung definieren, die sich aus den Merkmalen in vielerlei Hinsicht unterscheidet hier beschrieben.

Dennoch geerbt Tabelle der automatisch erstellten Typen wirklich wie echte geerbt Typen arbeiten (sie verwendet werden können, wo der Super-Typ verwendet werden kann):

-- 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

Sie können Tabellenvererbung dafür verwenden, da jede Tabelle implizit einen Typ definiert. Zitiert aus CREATE TABLE:

CREATE TABLE erstellt auch automatisch einen Datentyp, der den Verbundtyp einer Zeile der Tabelle entspricht, darstellt. Daher können Tabellen nicht den gleichen Namen wie alle vorhandenen Datentypen im selben Schema haben.

Ihr Beispiel mit Tabellen:

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

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

Bei der Beschreibung der Tabelle mit psql:

 
# \d mytype_extended 

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

Lassen Sie uns jetzt eine Spalte der Tabelle Basis hinzufügen und überprüfen, ob die geerbte Tabelle wird es zu:

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