postgresql表继承详解

本文详细介绍了PostgreSQL数据库的表继承功能,包括如何创建和操作父表与继承表,如数据继承、结构继承、权限管理等方面,并探讨了多表继承、解除继承以及查询优化等高级用法。此外,还提到了继承与权限、表结构修改和数据操作之间的关系,展示了该特性在实际应用中的灵活性和复杂性。
摘要由CSDN通过智能技术生成

postgresql有个特有的功能,它就是表继承,这是它。下面来研究一下这个“特异功能”。

1. 建立父表和继承表:

create table employee

(   id                     int  not null,
    employee_name          varchar(64),
    salary                   int check(salary>0),
    primary key(id)
);

CREATE INDEX idx_employee_01 ON employee(employee_name);


create table employee_info
(   depart_id   int,
     job_title       varchar(64)
)inherits(employee);

查询继承表:

select * from employee_info;

可以看到id, emplyee_name, salary这3个字段给继承下来。

往employee_info表插入数据:

insert into employee_info
(   id,
    employee_name,
    salary,
    depart_id,
    job_title
)values
(1,
'张三',
10000,
 1001,
'IT manager'),
(2,
'李四',
20000,
 1001,
 'IT engineer')

再执行查询,结果如下:

 可以看到,employee_info 完美地继承了父表employee的字段。

2. 查看父表和继承表的结构

父表:

dbsimple=# \d+ employee;

 再看继承表:

dbsimple=# \d+ employee_info;

 对比父表和继承表,可以看到主键和约束条件和索引没有被继承下来。

如果需要继承主键和约束条件,索引等,则需要在创建的时候加上Including all ;在建表的时候,发现多了"merging constraint"。

dbsimple=#drop table employee_info;

dbsimple=#create table employee_info
                  (   like employee including all
                  ) inherits (employee);

再次查看继承表建表信息:

dbsimple=# \d+ employee_info;

 这次我们可以看到主键,约束和索引都被继承了下来。

除继承父表之外,创建继承表时可以增加自己的字段,这里在继承表增加depart_id和job_title两个字段。

alter table employee_info add column depart_id int;
alter table employee_info add column job_title varchar(64);

 3. 继承只是继承表结构,数据不会继承,也就是说,父表插入的数据,子表是不存在。

往父表employee插入一条数据:

insert into employee
(   id,
    employee_name,
    salary
)values
(1,
'王五',
15000);

结果只看到父表的字段和数据。

查询继承表:

 

没有看到父表插入的数据。

4. 删除掉父表的约束employee_pkey,发现继承表c1的约束还是存在的 。

dbsimple=#alter table employee drop constraint employee_pkey;

dbsimple=# \d+ employee;

父表的主键被删除了。

dbsimple=# \d+ employee_info;

而继承表的主键还存在。

 5. 在查询父表数据的时候,对应的继承表数据也被查询出来,但字段仅是父表创建的字段 。但是查询继承表就不会查询父表 的数据。

dbsimple=# explain select * from employee;

 dbsimple=# explain select * from employee_info;

 

在查询父表数据,如果不要继承表的数据,可以加上only:

dbsimple=# select * from only employee;

6. 修改父表和继承表的数据,对应能查找到的数据也跟随着发生更新。

dbsimple=#update employee
   set salary=30000
  where id=2

查询继承表:

继承表id为2的员工salary也变成了3000.

同样,更新继承表的数据,父表查询也会查到更新后的数据。

7.  修改父表的表结构,继承表也跟随着变化。

 dbsimple=# alter table employee add column join_date date check(join_date>='2022-06-01');

dbsimple=# update employee set join_date='2022-06-10';

dbsimple=# select * from employee_info;

dbsimple=# \d+ employee_info;

 8. 通过继承表修改继承的字段,会被拒绝。

dbsimple=# alter table employee_info drop column join_date;

9. 父表字段的attislocal属性为false的时候 .删掉父表的字段,继承表上的列不会被删除。

 dbsimple=# create table employee_external(like employee)inherits(employee);

dbsimple=# \d+ employee_external;

dbsimple=# select attname,attislocal from pg_attribute where attrelid='employee_external'::regclass;

  继承表employee_info的字段english_nam的attislocal值为True。

dbsimple=# create table employee_base()inherits(employee);

 继承表employee_info的字段english_nam的attislocal值为false。

删除父表的english_name字段。

dbsimple=# alter table employee drop column english_name;

dbsimple=#\d+ employee;

 dbsimple=#\d+ employee_external;

可以看到,employee_externa表字段english_name的attislocal值为True,没有被删除。

dbsimple=#\d+ employee_base;

 

 可以看到,employee_base表字段english_name的attislocal值为False,字段被删除。

在父表再次增加字段english_name;

dbsimple=# alter table employee add column english_name varchar(64);

字段可以被增加。

10. 删除父表。当继承表存在的时候是不能直接删除父表。需要加上 cascade参数。

dbsimple=# drop table employee;

dbsimple=# drop table employee cascade;

 把关联的继承表一起删除。

11. 当在父表上查询数据的时候,想要知道那些出自于主表,哪些出自于继承表。可以利用tableoid,来标识数据来自于那一个表,然后再通过tableoid在pg_class表中找到对用的表 。

select tableoid,* from only employee;

select tableoid,* from employee;

select tableoid,* from employee_info;

 

11. 解除继承。父表的记录都被保存(包括之前来源于继承表的),继承表的字段也只保留之前继承过来的字段,而继承表自己建的字段被删除,同时继承表的所有记录也被清空。

dbsimple=# alter table employee_external no inherit employee;

dbsimple=# select * from employee_external;

 dbsimple=# select * from employee;

 12. 多表继承。一个表可以从多个父表继承,这种情况下它会拥有所有父表的字段。 如果同一个字段名出现在多个父表中,或者同时出现在父表和继承表表的定义里,那么这些字段就会被"融合",这样在子表里面就只有一个这样的字段。要想融合,字段必须是相同的数据类型,否则就会抛出一个错误。融合的字段将会拥有它所继承的字段的所有约束。继承表可以增加自己的字段。

 

create table employee
 (   id         int    not null,
     employee_id int,
     employee_name     varchar(64),
     salary            int     check(salary>0),
     primary key(id)
);

 create table employee_base
 (   id         int    not null,
     employee_id int,
     salary            int     check(salary>0),
     join_date         date,
     primary key(id)
);

 create table employee_external
 (phone varchar(20))inherits (employee,employee_base) 
 ;

dbsimple=# \d+ employee_external;

 13. 继承和权限. 表访问权限并不会自动继承。因此,一个试图访问父表的用户还必须具有访问它的所有子表的权限,或者使用ONLY关键字只从父表中提取数据。

      

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值