2012-08-08 57 views
3

我有一些SQL代码的问题。PostgreSQL中的继承和关系

序列和表格的创建,一些数据中插入:

CREATE SEQUENCE tmp_id_places START 1; 
CREATE SEQUENCE tmp_id_books START 1; 

CREATE TABLE tmp_places (
    id int PRIMARY KEY DEFAULT nextval('tmp_id_places'), 
    name text 
); 

CREATE TABLE tmp_cities (population int) INHERITS (tmp_places); 
CREATE TABLE tmp_rivers (lenght int) INHERITS (tmp_places); 

INSERT INTO tmp_cities (name, population) VALUES 
    ('Moscow', 15), 
    ('St. Petersburg', 9); 

INSERT INTO tmp_rivers (name, lenght) VALUES 
    ('Volga', 115), 
    ('Angara', 319); 

CREATE TABLE tmp_books (
    id int PRIMARY KEY DEFAULT nextval('tmp_id_books'), 
    id_place int REFERENCES tmp_places(id), 
    title text 
); 

Вut验证码输入有误:

INSERT INTO tmp_books (title, id_place) VALUES 
    ('Some book about Moscow', 1), 
    ('Another book about Angara', 4); 

tmp_books包含有关地点的信息。但我无法在其中插入数据,因为主表tmp_places(子表中的所有数据)中没有任何数据。

因此,这可以解决吗?

回答

2

丹尼斯,

继承不INSERT传播和复制Postgres的语句。

1

在PostgreSQL中,你不应该为父表创建一个外键,因为正如你刚才发现的那样,这个表的行为几乎是一个视图而不是一个表(因为实际数据在它们各自的子节点中)。现在只能通过触发器来解决。

您可以看到这种“触发器类型”的example

4

仔细看看PostrgeSQL文档中的this section。如果你将数据插入到子表中,那么在子表中将发现数据只有。另一方面,插入到主表中也会在所有子表中显示新行。所以你必须总是第一手在主表上工作。

前段时间我一直在继承工作,也面临同样的问题。 我结束了以下内容:

  1. INSERT新进入tmp_places;
  2. UPDATE额外的字段,例如,在tmp_cities与他们各自的价值观。

返回7.4倍我必须为这些活动创建一组函数。 现在可以使用RETURNING clause of INSERT声明和CTEs with UPDATE(也SQL Fiddle):

WITH theid AS (
    INSERT INTO tmp_places (name) VALUES ('Moscow') RETURNING id 
) 
UPDATE tmp_cities tc SET population = 15 
    FROM theid 
WHERE tc.id = theid.id; 

你也应该小心的约束,因为不是所有的人继承。