PostgreSQL继承:将父行插入子进程

时间:2016-09-16 17:45:08

标签: postgresql inheritance

我在父表中有一行我希望在子表中有一行,但没有在父表中创建副本。

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

让我们说我刚刚学会了 Sacramento 是一个资本,所以我想在我的capitals表中。 如果我使用普通INSERT INTO capitals,我会在城市中获得重复值,这不是很有用。

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

(如文档中所述,继承导致主键具有重复值,我可以使用FROM ONLY来避免这种情况,但这不是我的问题。)

我想我可以在capitals上有一个触发器,当我插入孩子时删除父行,但是没有内置的方法吗?

1 个答案:

答案 0 :(得分:1)

您可以从解释计划中看出select * from cities基本上是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)

因此,您的选项要么使用select distinct * from cities,要么类似于:

select idcity from only cities
union
select idcity from capitals

或者使用触发器,正如我们在上面的评论中所讨论的那样。但我们得出结论,触发器在这种特定情况下毫无意义。

所以,除了使用distinct之外,我没有找到实现的内置方式。