暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

GBase 8c 视图依赖的DDL操作合集

ClickHouse周边 2025-07-03
152

1. 背景说明

       GBase 8c 多模多态企业级分布式数据库具备高性能、高可用、弹性伸缩、高安全性等特性。想了解更多产品架构信息,请点击 GBase 8c 多模多态分布式数据库简介与安装 。

       如果日常使用中表被视图引用的话,特定场景下,部分DDL操作是不能直接执行的,比如修改被视图引用的字段的类型,删除表等,而新增字段是可以操作,主要原因是视图引用了表的字段,修改的话视图也需要变化。下面演示一下这部分内容,被视图引用的表进行DDL操作会有什么表现。然后再看看怎么操作才能修改表字段等。

2.创建实验环境
创建2张测试表
CREATE TABLE t1 (id int,name varchar(20));
CREATE TABLE t2 (id int,name varchar(20));

三张视图,所有视图都是使用了t1的字段,没有使用t2的字段。
CREATE OR REPLACE VIEW v1 as select * from t1;
CREATE OR REPLACE VIEW v2 as select a.* from t1 a inner join t2 b on a.id = b.id;

CREATE OR REPLACE VIEW v3 as select a.* from v1 a inner join v2 b on a.id = b.id inner join t1 c on a.id = c.id;

2.1 删除表

drop table t1;
drop table t2;

       从执行结果提示来看,DROP TABLE是没有执行成功的,因为有视图依赖。可以通过DROP ...CASCADE来一起将依赖的视图删除,但是一般情况下我们不想将视图删除。

2.2 修改字段

ALTER TABLE T1 MODIFY NAME VARCHAR(30);
ALTER TABLE T2 MODIFY NAME VARCHAR(30);

       从执行结果的提示来看,t1t2表都修改成功了,t2很好理解,因为没有视图使用到t2的字段,虽然视图使用了t2表,但只是用来关联,视图的字段并没有使用t2表的字段,所以t2表的字段类型能修改成功。t1表能修改成功是因为级联也修改了v2视图的定义,解决了被视图引用的表定义不能修改的情况

插入数据测试视图查询结果如下

insert into t1 values(1,'12345678901234567890');
insert into t2 values(2,'09876543210987654321');
insert into t1 values(11,'123456789012345678901234567890');
insert into t2 values(22,'098765432109876543210987654321');
insert into t2 values(1,'098765432109876543210987654321');
select * from t1;

select * from t2;

select * from v1;



select * from v2;




2.3 新增字段

ALTER TABLE  T1 ADD COMMENT VARCHAR(30);
ALTER TABLE  T2 ADD COMMENT VARCHAR(30);

       新增字段没有任何限制,因为视图建立的时候,没办法引用还没有的字段。我们审视视图的定义CREATE VIEW v1 AS SELECT * FROM t1; 那此时v1会有新增的字段信息吗?答案是否定的,视图需要重新刷新才会有新增的字段。
select * from v2;
CREATE OR REPLACE VIEW v2 as select a.* from t1 a inner join t2 b on a.id = b.id;
select * from v2;

2.4 查找t2表关联的视图

       通过with recursive xx as循环语句获取所有相关视图。

with recursive rec_view as(
    select c.nspname as schemaname,b.relname,rel_oid,b.relkind,d.oid as ori_oid,d.relname ori_name
,0as level  --level防止死循环
from(
    select unnest(regexp_matches(ev_action::text,':relid (\d+)','g'))::oid  rel_oid,ev_class --rel_oid 被依赖对象 ,ev_class 视图名称
    from pg_rewrite 
    union 
    select unnest(regexp_matches(ev_action::text,':resorigtbl (\d+)','g'))::oid,ev_class
    from pg_rewrite 
) deptbl                   --pg_write获取依赖关系
    inner join pg_class b       --被依赖对象获取表名等信息
    on deptbl.rel_oid = b.oid
    inner join pg_namespace c
    on b.relnamespace = c.oid
    inner join pg_class d     --视图获取视图名等信息,且用于排除pg_write获取的自身对象,即rel_oid <> ev_class
    on deptbl.ev_class = d.oid
    and deptbl.rel_oid <> d.oid
    where  b.relname ='t2'--指定表名t2
union all
    select c.nspname,b.relname,deptbl.rel_oid,b.relkind,d.oid as ori_oid,d.relname ori_name,level+1
from(
    select unnest(regexp_matches(ev_action::text,':relid (\d+)','g'))::oid  rel_oid,ev_class
    from pg_rewrite 
  union 
    select unnest(regexp_matches(ev_action::text,':resorigtbl (\d+)','g'))::oid,ev_class
    from pg_rewrite 
) deptbl 
    inner join pg_class b
    on deptbl.rel_oid = b.oid
    inner join pg_namespace c
    on b.relnamespace = c.oid
    inner join pg_class d
    on deptbl.ev_class = d.oid
    and deptbl.rel_oid <> d.oid
    inner join rec_view e          --循环语句关联条件
    on deptbl.rel_oid = e.ori_oid
    where level <=10--level防止死循环
)
select * from rec_view;

       从结果看,t2表相关视图是v2,v3两个视图,假如需要备份v2,v3到文本中,可以使用gs_dump的方式。

gs_dump postgres --t v2 -t v3 --f view.ddl -p 5432


声明
       因小编个人水平有限,专栏中难免存在错漏之处,请勿直接复制文档中的参数、命令或方法应用于线上环境中操作。

近期文章推荐
GBase 8c 多模多态分布式数据库简介与安装
GBase 8c 配置大小写和中英文排序

文章转载自ClickHouse周边,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论