2016-09-16 1 views
0

Ich habe eine Zeile in der übergeordneten Tabelle, die ich in der Child-Tabelle haben möchte, aber ohne ein Duplikat in der Eltern erstellen.PostgreSQL-Vererbung: Einfügen einer Eltern-Zeile in das Kind

Erweitertes Beispiel aus dem documentation:

CREATE TABLE cities (
    idcity   serial PRIMARY KEY, 
    name   text, 
    population  float, 
    altitude  int  -- in feet 
); 

INSERT INTO cities VALUES (1, 'San Francisco', 7.24E+5, 63); 
INSERT INTO cities VALUES (2, 'Las Vegas', 2.583E+5, 2174); 
INSERT INTO cities VALUES (3, 'Mariposa', 1200, 1953); 
INSERT INTO cities VALUES (4, 'Sacramento', 3.694E+5, 30); 

-- The capitals table inherits from cities table. 
CREATE TABLE capitals (
    state   char(2) 
) INHERITS (cities); 

Sagen wir, ich habe gerade erfahren, Sacramento ist ein Kapital, so möchte ich es in meinem capitals Tisch. Wenn ich eine normale INSERT INTO capitals verwende, bekomme ich einen doppelten Wert in Städten, was nicht so nützlich ist.

INSERT INTO capitals VALUES (4, 'Sacramento', 3.694E+5, 30, 'CA'); 

SELECT * FROM cities WHERE idcity = 4; 

idcity | name  | population | altitude 
-------+------------+------------+--------- 
4  | Sacramento | 369400  | 30 
4  | Sacramento | 369400  | 30 

(Wie in der Dokumentation angegeben ist, führt das Erbe einen doppelten Wert für den Primärschlüssel zu haben, und das konnte ich vermeiden mit FROM ONLY, aber das ist nicht mein Problem.)

Ich glaube, ich hätte ein Trigger auf capitals, um die Elternzeile zu löschen, wenn ich in das Kind einfügen, aber gibt es nicht eine integrierte Möglichkeit, das zu tun?

+1

Nein, weil Sie die Vererbungslogik dort brechen. Macht die Stadt zu einer Hauptstadt, heißt das, dass sie aufhört, eine Stadt zu sein? Aber wenn Sie das wirklich erreichen müssen, ist Trigger der richtige Weg. –

+0

@AlexeySoshin Ich meine das Gegenteil: Ich möchte eine Stadt zu einer Hauptstadt machen, ohne etwas daran zu ändern, dass sie eine Stadt ist (Name, Bevölkerung, Höhe ...). Wie könnte ich das tun? – Victor

+0

Aber genau das hast du jetzt, ohne irgendwelche Auslöser. –

Antwort

1

Sie können aus dem Plan erklären, dass select * from cities im Grunde eine UNION ALL:

explain 
select * 
from cities; 

Append (cost=0.00..21.27 rows=1027 width=4) 
    -> Seq Scan on cities (cost=0.00..2.07 rows=107 width=4) 
    -> Seq Scan on capitals (cost=0.00..19.20 rows=920 width=4) 

explain select idcity from only cities 
union all 
    select idcity from capitals 

Append (cost=0.00..21.27 rows=1027 width=4) 
    -> Seq Scan on cities (cost=0.00..2.07 rows=107 width=4) 
    -> Seq Scan on capitals (cost=0.00..19.20 rows=920 width=4) 

Daher Optionen entweder verwenden select distinct * from cities, die ähnlich sein wird:

select idcity from only cities 
union 
select idcity from capitals 

oder ein mit Auslöser, wie wir in den obigen Kommentaren diskutiert haben. Aber wir kamen zu dem Schluss, dass Trigger in diesem speziellen Fall keinen Sinn ergeben.

Also, es gibt keinen eingebauten Weg, den ich gefunden habe, um das zu erreichen, außer mit distinct.

Verwandte Themen