Inherit用于设置表的继承,继承表的子表可以完全继承父表结构,也可以在父表结构的基础上添加字段,并且可以继承多父表或进行次级继承。 继承表有一个可设置的guc参数sql_inheritance(默认为on),它控制父表的操作是否可以访问子表,默认情况下父表可以查询包含子表在内的所有数据,关闭它时父表的只能查询/更新自己。
继承表具有以下特点:
- 表访问权限并不会被自动继承。
- 可以用/d+ father来查看父表下所有子表。
- 临时表可以继承临时表和普通表,普通表不能继承临时表。
- 当多个父表的字段相同时会进行融合,不同则会抛出错误。
- 存在子表时无法删除父表,用cascade删除父表的话,子表也会被删除。
- 子表不使用including all子句只会继承父表的非空、默认值和检查三种约束(父表对这几种约束的修改会同步作用于子表)。
- 子表使用including all子句才可以额外继承索引、唯一、主键、外键约束(但父表对这几种约束的修改不会同步作用于子表)。
- 子表不使用like parent_name子句时,父表对列进行删除的话,子表列也会被删除。
- 子表使用like parent_name子句时,子表拥有和父表同名的独立字段,当父表对列进行删除时不会作用于子表。
- 假如外键f_id指定外表t1,而t2是t1的子表,t2中存在id为3的数据,但t1中不存在id为3的数据,那么f_id不能是3,外键约束只包含指定的外表的数据,不包含该外表的子表。
注意事项
- 继承表功能和mysql的多表更新功能冲突,不可以在B库建继承表。
- 不支持继承和分区表或者MOT表(及其他外表)同时存在的情况。
- 支持Ustore和段页式,但这两种情况不能使用"like fathername including all"语句。
- 列存不支持继承表。
1.对象创建(CREATE)
继承使用关键词inherits
create table t1(id int,name varchar(30));
create table t1_kid(age int) inherits(t1);
\d t1_kid
复制
当子表和父表出现字段相同时,字段会被合并
create table t1_kid2(id int,score int) inherits(t1);
\d t1_kid2
复制
在父表中添加的数据只能在父表中查看
insert into t1 values(1,'zhangsan');
select * from t1;
select * from t1_kid;
select * from t1_kid2;
复制
但是在子表中添加的数据可以同步到父表中,继承自同一个父表的两个子表之间没有关系
insert into t1_kid values(2,'lisi',18);
select * from t1;
select * from t1_kid;
select * from t1_kid2;
复制
但是在子表中添加数据时与父表数据冲突时,无论父表是否存在主键/唯一值约束,父表会继续新增一行子表新增的数据(即使存在主键冲突问题)
-- 给父表添加主键约束
alter table t1 add constraint pkey_id primary key(id);
-- 给子表添加一条与父表主键冲突的数据
insert into t1_kid values(1,'zhangsan',20);
-- 查看父表和子表数据
select * from t1;
select * from t1_kid;
复制
但是尝试给父表添加已存在冲突数据时会受到主键约束
insert into t1 values(1,'zhangsan');
复制
2.数据更新(UPDATE)
在父表中将id为2的数据修改为22,子表中的数据也会被同步修改
update t1 set id=22 where id=2;
复制
在子表中将id为1的数据修改为11,父表中由子表新增数据触发新增的记录会被同步修改,但基于父表执行insert添加的数据不受影响
update t1_kid set id=11 where id=1;
复制
基于父表修改与子表有关联数据时也会将修改同步到子表中
update t1 set id=1 where id=11;
复制
3.数据删除(DELETE)
无论在父表还是子表中执行删除操作,只要是两表关联的数据都会被同步操作
-- 在父表中执行删除
delete from t1 where id=1;
复制
-- 在子表中执行删除
delete from t1_kid;
复制
4.对象查询(pg_inherits)
可以基于pg_inherits系统表查看继承关系,由于该系统表只存储对象id,可以通过id连接pg_class获取对象名称
select inhrelid,c1.relname,inhparent,c2.relname,inhseqno from pg_inherits,pg_class c1,pg_class c2 where c1.oid=inhrelid and c2.oid=inhparent;
复制
5.对象更新(ALTER)
在子表中删除从父表继承的字段时,系统不允许删除,如果删除子表新增字段不受影响
alter table t1_kid drop name;
复制
在父表中删除某列时,所有相关子表中继承的列都会被同步删除
alter table t1 drop name;
复制
同时,在父表中新增字段也会同步到子表中
alter table t1 add name varchar(30);
复制
如果字段是子表本来创建的,就算在创建子表时因为与父表字段冲突被合并,在父表删除字段时,子表字段不受影响,但是如果从父表继承的字段会被同步删除
如果想要父表删除字段时子表不受影响,但是数据与父表关联,在创建表时可以使用like tablename语法创建like指定子表创建字段,inherits建立继承关系。
create table t1_kid3(like t1) inherits(t1);
复制
6.对象删除(DROP)
要删除父表时,由于有子表依赖,无法删除成功
drop table t1;
复制
需要使用cascade才能删除,使用cascade会将依赖父表的所有子表级联删除
drop table t1 cascade;
复制