别再忽视!PostgreSQL Public 模式的风险以及安全迁移
别再忽视!PostgreSQL Public 模式的风险以及安全迁移
作者:桦仔
10余年DBA工作经验
微信:debolop
QQ交流群:740052625
公众号:数据库实战派
问题起因
前几天有群友在群里面咨询
PG12,13,14,public模式是否可以删除或改名?
因为这位群友的公司的PG规范做了修改,不让使用public模式存放数据,但是遗留问题没办法。
另外一位群友说到
你还真不好动public。扩展的插件的函数大多默认都在public 下。


PG中默认的public模式带来的问题
- 安全性问题
public 模式默认对所有数据库用户都开放访问权限。换句话说,所有连接到数据库的用户默认都可以访问 public 模式中的对象(除非你手动修改权限)。
- 命名冲突
public 模式是所有用户和所有扩展默认使用的模式,容易发生命名冲突。
- 可维护性和隔离性
使用 public 模式进行业务操作会使数据库的架构设计显得杂乱无章,随着时间推移,尤其是在大型项目或多个项目共享数据库时,public模式中的对象数量会急剧增加
- 版本和扩展的兼容性问题
许多 PostgreSQL 扩展默认使用 public 模式,如果修改 public 模式或删除它,可能会导致扩展无法正常工作
能否重命名 public 模式
我们能不能通过下面命令对public 模式名重命名 ?
ALTER SCHEMA public RENAME TO you_schema;
实际上重命名 public 模式是不推荐的做法,原因如下
- 依赖性问题:许多扩展、插件和默认的 PostgreSQL 设置都假定 public 模式存在。如果直接修改 public 的名称,会导致这些依赖出现问题。
- 升级问题:未来如果 PostgreSQL 版本升级,系统或新安装的扩展可能仍然依赖于 public 模式存在。
因此,最好的做法是保留 public 模式,但不在业务中使用它。
如何解决这个问题
实际上,我们可以使用迁移的方式,新建一个模式,然后把public模式下的所有业务对象迁移到新建模式下
具体步骤
第一步:创建新的模式
CREATE SCHEMA employee;
第二步:迁移所有对象:对表、视图、函数、存储过程等对象分别执行 SET SCHEMA 操作,将它们从 public 模式迁移到 employee 模式。
迁移对象时小心依赖关系,如外键、索引、函数依赖等,迁移时需要确保这些依赖关系不被破坏
使用以下命令逐个迁移:
-- 迁移所有表
ALTER TABLE public.table_name SET SCHEMA employee;
-- 迁移所有视图
ALTER VIEW public.view_name SET SCHEMA employee;
-- 迁移所有函数
ALTER FUNCTION public.function_name SET SCHEMA employee;
-- 迁移所有存储过程
ALTER PROCEDURE public.procedure_name SET SCHEMA employee;
使用 SQL 动态语句和 PL/pgSQL 编写一个循环来批量迁移 public 模式中的所有表、视图、函数和存储过程到 employee 模式。
DO $$
DECLARE
obj record;
BEGIN
-- 迁移所有表
FOR obj IN
SELECT tablename
FROM pg_tables
WHERE schemaname = 'public'
LOOP
EXECUTE format('ALTER TABLE public.%I SET SCHEMA employee;', obj.tablename);
END LOOP;
-- 迁移所有视图
FOR obj IN
SELECT viewname
FROM pg_views
WHERE schemaname = 'public'
LOOP
EXECUTE format('ALTER VIEW public.%I SET SCHEMA employee;', obj.viewname);
END LOOP;
-- 迁移所有函数
FOR obj IN
SELECT routine_name, routine_schema
FROM information_schema.routines
WHERE specific_schema = 'public'
LOOP
EXECUTE format('ALTER FUNCTION public.%I() SET SCHEMA employee;', obj.routine_name);
END LOOP;
-- 迁移所有存储过程
FOR obj IN
SELECT routine_name, routine_schema
FROM information_schema.routines
WHERE specific_schema = 'public' AND routine_type = 'PROCEDURE'
LOOP
EXECUTE format('ALTER PROCEDURE public.%I() SET SCHEMA employee;', obj.routine_name);
END LOOP;
END $$;
第三步:设置 search_path 通过调整 search_path 让数据库默认使用 employee 模式。
search_path 的设置顺序非常重要。
将 employee 模式放在前面,确保在业务操作时优先查找 employee 模式的对象,而 public 作为备选模式保留(方便扩展和插件的使用)。
可以修改 PostgreSQL 的 postgresql.conf 文件,或者在会话级别设置 search_path:
SET search_path TO employee, public;
第四步:考虑扩展和插件
许多扩展和插件默认使用 public 模式,例如 PostGIS、pgcrypto 等。
为了避免问题,最好不要修改 public 模式,而是保持其作为扩展使用的默认模式。
为什么SQL Server 没有这个问题
SQL Server 没有像 PostgreSQL 那样对 public 模式的强烈依赖,并且其设计理念与 PostgreSQL 的 public 模式存在一些关键区别。
- 权限管理的不同
在 SQL Server 中,dbo 是默认的 schema,所有数据库用户默认情况下并不会拥有对 dbo 这个 schema 中对象的完全访问权限。只有拥有 db_owner 角色的用户才可以完全控制 dbo 这个 schema。
也就是说,除非用户显式授予对 dbo 中对象的访问或修改权限,否则,普通用户是不能随意访问或修改 dbo 这个 schema 下的对象的。
相比之下,PostgreSQL 的 public 这个 schema 在默认情况下是对所有用户开放的。这意味着所有用户都可以在 public 这个 schema 中创建对象,除非手动限制权限。
PostgreSQL的设计会增加意外权限授予和数据泄露的风险,因此在 PostgreSQL 中有时需要避免使用 public schema。
- 模式设计理念的不同
在 PostgreSQL 中,public schema 设计为一个所有用户共享的默认命名空间,因此经常发生命名冲突、权限管理不严等问题。
在 SQL Server 中,dbo 是为拥有数据库完全控制权的用户预留的默认命名空间,通常普通用户和 DBA 可以自行创建自定义 schema 来组织和隔离各自的数据库对象。
参考文章
https://sdwh.dev/posts/2021/03/SQL-Server-What-Is-dbo/
https://www.ibm.com/support/pages/microsoft-sql-server-tables-get-generated-dbo-schema
https://www.postgresql.org/docs/current/ddl-schemas.html
https://www.crunchydata.com/blog/be-ready-public-schema-changes-in-postgres-15

本文版权归作者所有,未经作者同意不得转载。
别再忽视!PostgreSQL Public 模式的风险以及安全迁移的更多相关文章
- PostgreSQL学习----模式schema
PostgreSQL学习---模式schema 小序 接触PostgreSQL也有好长时间了,知识不总结梳理,似乎总不是自己的,继续努力吧少年!以此记录我的软件工艺之路! 模式(Schema) 一个 ...
- PostgreSQL的模式、表、空间、用户间的关系
在平时的工作中,我们经常接触到数据库表和用户以及角色的使用,由于经常使用默认的数据库表空间和模式(Schema),所以我们往往忽略了数据库表空间和模式的概念以及作用. 接下来,先介绍一下模式和表空间的 ...
- 理解PostgreSQL的模式、表、空间、用户间的关系
在平时的工作中,我们经常接触到数据库表和用户以及角色的使用,由于经常使用默认的数据库表空间和模式(Schema),所以我们往往忽略了数据库表空间和模式的概念以及作用. 接下来,先介绍一下模式和表空间的 ...
- [转载]再谈PostgreSQL的膨胀和vacuum机制及最佳实践
本文转载自 www.postgres.cn 下的文章: 再谈PostgreSQL的膨胀和vacuum机制及最佳实践http://www.postgres.cn/news/viewone/1/390 还 ...
- 不能再忽视了!宝宝不肯吃粥的N个原因,你避免了几个?
辅食不懂怎么添加? 宝宝吃饭爱挑食? 营养均衡和多样化的辅食 在这里你都能找到 宝宝辅食微课堂 不能再忽视了!宝宝不肯吃粥的N个原因,你避免了几个? 2017-10-09 09:35 辅食不懂怎么添加 ...
- javaIO系统----再看装饰者模式
javaIO系统拥有各种各样的类,尤其是每次要进行读写操作时,总会一层套一层的new,以前不明白为什么要这样做,不过学习了适配器模式后,对于这种做法立刻了解了:动态扩展IO的功能,使之符合使用者的习惯 ...
- 再谈 X-UA-Compatible 兼容模式
如何理解 IE 的文档兼容模式(X-UA-Compatible)? IE 浏览器支持多种文档兼容模式,得以因此改变页面的渲染效果. IE9 模式支持全范围的既定行业标准,包括 HTML5(草案), W ...
- CodeFirst模式,容易引发数据迁移问题(不建议使用)
code first 模式 .模型类需要数据契约绑定[DataContract] .模型参数需要[DataMember]-----(可以序列化) .(同上)也可以在类的上面增加[Table(" ...
- PostgreSQL表空间、数据库、模式、表、用户/角色之间的关系
看PostgreSQL9的官方文档,我越看越迷糊,这表空间,数据库,模式,表,用户,角色之间的关系怎么在PostgreSQL里这么混乱呢?经过中午的一个小实验,我逐渐理清了个中来龙去脉.下面我来还原我 ...
- PostgreSQL表空间、模式、表、用户/角色之间的关系
PostgreSQL表空间.模式.表.用户/角色之间的关系是本文我们主要要介绍的内容,表空间,数据库,模式,表,用户,角色之间的关系到底是怎样的呢?接下来我们就开始介绍这一过程. 实验出角色与用户的关 ...
随机推荐
- python学习之---迭代器与生成器
什么是迭代器 可迭代对象: 可以通过for循环来实现遍历,例如list.string.dict 迭代器: 不仅可以使用for循环,还可以使用next()方法.__iter__() next():获取容 ...
- AI阅读助手ChatDOC:基于 AI 与文档对话、重新定义阅读方式的AI文献阅读和文档处理工具
让 AI 真正成为你的生产力超级助手 AI 时代降临,我们需要积极拥抱 AI 工具 在过去的 2 个多月里,以 ChatGPT 为代表的 AI 风靡全球.随着 GPT 模型的不断优化,ChatGPT ...
- C语言实现url解析小实例
一.前言 前面一口君写了一篇关于url的文章: <一文带你理解URI 和 URL 有什么区别?> 本篇在此基础上,编写一个简单的用于解析url的小例子, 最终目标是解析出URL中所有的数据 ...
- Devexpress 控件学习记录(一:BarManager 控件、XtraTabbedMdiManager 控件)
BarManager 控件 最终实现的效果如下: 首先在窗体中拖出BarManager控件,窗体Bar add地方点击添加 设置BarManager的属性 设置出现的窗体的底部[DockStyle=B ...
- CD、VCD、DVD、BD 傻傻分不清楚?
CD 激光唱片(Compact Disk, CD),于 1982 年面世,最初用于存储数字音频.容量约 700 MB(80 分钟音频). 激光唱片 | 维基百科 VCD 影音光盘(Video Comp ...
- Mac 使用远程 Ubuntu 机器进行时间备份
设置 SMB 服务 首先在 Ubuntu 中配置 SMB 服务.可以参考 Ubuntu 设置 SMB 服务. 创建 APFS 磁盘映像 我们在 Ubuntu 上创建出的 SMB 共享文件夹可以用来存放 ...
- idea 的Tomcat 的简单配置
不限速网盘下载: https://kohler.lanzouv.com/iSSfc0akw3vc 官网下载: https://tomcat.apache.org/download-80.cgi 正常解 ...
- webpack笔记-webpack初识与构建工具发展(一)
为什么需要构建工具? 转换 ES6 语法 转换 JSX CSS 前缀补全/预处理器 压缩混淆 图片压缩 前端构建演变之路 ant + YUI Tool grunt gulp.fis3 webpack. ...
- RxJS 系列 – Observable to Subject (Hot, Cold, Warm, connectable, share)
前言 前两篇介绍了 Observable 和 Subject.它们有一个重大区别当 multiple subscribe 的时候. Observable 每一次 subscribe 都会调用初始化方法 ...
- ASP.NET Core – 网站发布要做的事儿 Publish, Minification, Compression, Cache, HSTS, URL Rewrite Https & www, Close IIS Feature
前言 要发布网站需要做一些优化, 比如 cache, compression, minification 等等. 以前有写过相关的文章: Asp.net core 学习笔记 ( IIS, static ...