继承
继承案例:
create table test.cities(
name text,
population float,
altitude int
);
create table capitals(
state char(2)
) inherits (cities);
其中capitals 表继承它的父表cities中的所有属性。
在postgresql里,一个表可以从零个或者多个其它表中继承属性,而且一个查询既可以引用一个表中的所有行,也可以引用一个表及其所有后代表的行。
找出不包括首府的所有的海拔超过500英尺的城市。
select name ,altitude from only cities where altitude >500;
cities前面的only表明该查询应该只针对cities 而不包含其后代。select ,update,update都支持only关键字。
在表后面写一个*显示指定包括所有后代表。
select name,altitude from cities* where altitude>500;
写*并不是必须的,
不过写在表后面 写 乘号可以用于强调搜索额外的表。
假使我们想知道某个行版本来自哪个表。
在每个表里我们都有一个tableoid系统属性可以告诉你源表是谁
select c.tableoid,c.name,c.altitude
from cities c
where c.altitude >500;
我们会的到不同的OID:
可以通过和pg_class 做一个关联,这样就可以看到实际的表名字:
select p.relname,c.tableoid,c.name,c.altitude
from all_cities c,pg_class p
where c.altitude >20 and c.tableoid=p.oid;
可以看到结果来源于两个表。
当我们向子表中插入数据的时候,附表中也会增加一条数据。
所有父表的检查约束和非空约束都会自动被字表继承。不过其他类型的约束(唯一,主键,外键约束)不会被继承。
一个字表可以从多个父表继承,这种情况下,它将拥有所有父表字段的总和,并且字表中定义的字段也会加入其中。
如果同一个字段名出现在多个父表中,或者同时出现在父表和子表的定义里,那么这些字段就会被融合,这样在子表里就只有一个这样的字段。要想融合,字段的数据类型必须相同,否则就会抛出错误。 融合的字段将会拥有其父字段的所有检查约束 并且如果某个父字段存在非空约束,那么融合后的字段也必须是非空的。
表继承通常使用 inherits 子句的 create table语句定义。
另外一个已经用此方法定义的子表可以使用 inherit 的 alter table 命令添加一个新父表。
注意:该子表必须已经包含新父表的所有字段,并且类型一致,此外新父表的每个约束的名字及其表达式都必须包含在此子表中。
同样,一个继承链可以使用带 no inherit 的 alter table 命令从子表上删除。
允许动态添加和删除继承链对基于继承关系的表分区很有用。
创建一个将要作为子表的新表的便利途径是使用like 子句的create table 命令。它将创建一个与源表字段相同的新表。如果源表中存在约束,那么应该指定like 的 includeing constraints 选项,因为子表必须包含源表中的check约束。
任何存在子表的父表都不能被删除,同样,子表中任何从父表继承的字段或约束也不能被删除或修改。如果我们想杀出一个表以及其所有后代,最简单的方式是使用cascade选项删除父表。
alter table 会把所有数据定义和检查约束传播到后代里面去。另外只有在使用cascade 选项的情况下,才能删除依赖于其它表的字段。
alter table 在重复字段融合和拒绝方面和 create table 的规则相同。
请注意表访问权限是如何处理的。访问父表会自动访问在子表中的数据,而不需要更多的访问权限检查。这保留了父表中数据的表现。然而,直接访问子表不会自动允许访问父表,要访问父表需要更进一步的权限被授予。
继承的一个严重局限性是索引(包括唯一约束)和外键约束只能用于单个表,而不能包括他们的子表,