别再忽视!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 模式是不推荐的做法,原因如下

  1. 依赖性问题:许多扩展、插件和默认的 PostgreSQL 设置都假定 public 模式存在。如果直接修改 public 的名称,会导致这些依赖出现问题。
  2. 升级问题:未来如果 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 模式存在一些关键区别。

  1. 权限管理的不同

在 SQL Server 中,dbo 是默认的 schema,所有数据库用户默认情况下并不会拥有对 dbo 这个 schema 中对象的完全访问权限。只有拥有 db_owner 角色的用户才可以完全控制 dbo 这个 schema。

也就是说,除非用户显式授予对 dbo 中对象的访问或修改权限,否则,普通用户是不能随意访问或修改 dbo 这个 schema 下的对象的。

相比之下,PostgreSQL 的 public 这个 schema 在默认情况下是对所有用户开放的。这意味着所有用户都可以在 public 这个 schema 中创建对象,除非手动限制权限。

PostgreSQL的设计会增加意外权限授予和数据泄露的风险,因此在 PostgreSQL 中有时需要避免使用 public schema。

  1. 模式设计理念的不同

在 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 模式的风险以及安全迁移的更多相关文章

  1. PostgreSQL学习----模式schema

    PostgreSQL学习---模式schema 小序 接触PostgreSQL也有好长时间了,知识不总结梳理,似乎总不是自己的,继续努力吧少年!以此记录我的软件工艺之路! 模式(Schema) 一个 ...

  2. PostgreSQL的模式、表、空间、用户间的关系

    在平时的工作中,我们经常接触到数据库表和用户以及角色的使用,由于经常使用默认的数据库表空间和模式(Schema),所以我们往往忽略了数据库表空间和模式的概念以及作用. 接下来,先介绍一下模式和表空间的 ...

  3. 理解PostgreSQL的模式、表、空间、用户间的关系

    在平时的工作中,我们经常接触到数据库表和用户以及角色的使用,由于经常使用默认的数据库表空间和模式(Schema),所以我们往往忽略了数据库表空间和模式的概念以及作用. 接下来,先介绍一下模式和表空间的 ...

  4. [转载]再谈PostgreSQL的膨胀和vacuum机制及最佳实践

    本文转载自 www.postgres.cn 下的文章: 再谈PostgreSQL的膨胀和vacuum机制及最佳实践http://www.postgres.cn/news/viewone/1/390 还 ...

  5. 不能再忽视了!宝宝不肯吃粥的N个原因,你避免了几个?

    辅食不懂怎么添加? 宝宝吃饭爱挑食? 营养均衡和多样化的辅食 在这里你都能找到 宝宝辅食微课堂 不能再忽视了!宝宝不肯吃粥的N个原因,你避免了几个? 2017-10-09 09:35 辅食不懂怎么添加 ...

  6. javaIO系统----再看装饰者模式

    javaIO系统拥有各种各样的类,尤其是每次要进行读写操作时,总会一层套一层的new,以前不明白为什么要这样做,不过学习了适配器模式后,对于这种做法立刻了解了:动态扩展IO的功能,使之符合使用者的习惯 ...

  7. 再谈 X-UA-Compatible 兼容模式

    如何理解 IE 的文档兼容模式(X-UA-Compatible)? IE 浏览器支持多种文档兼容模式,得以因此改变页面的渲染效果. IE9 模式支持全范围的既定行业标准,包括 HTML5(草案), W ...

  8. CodeFirst模式,容易引发数据迁移问题(不建议使用)

    code first 模式 .模型类需要数据契约绑定[DataContract] .模型参数需要[DataMember]-----(可以序列化) .(同上)也可以在类的上面增加[Table(" ...

  9. PostgreSQL表空间、数据库、模式、表、用户/角色之间的关系

    看PostgreSQL9的官方文档,我越看越迷糊,这表空间,数据库,模式,表,用户,角色之间的关系怎么在PostgreSQL里这么混乱呢?经过中午的一个小实验,我逐渐理清了个中来龙去脉.下面我来还原我 ...

  10. PostgreSQL表空间、模式、表、用户/角色之间的关系

    PostgreSQL表空间.模式.表.用户/角色之间的关系是本文我们主要要介绍的内容,表空间,数据库,模式,表,用户,角色之间的关系到底是怎样的呢?接下来我们就开始介绍这一过程. 实验出角色与用户的关 ...

随机推荐

  1. python学习之---迭代器与生成器

    什么是迭代器 可迭代对象: 可以通过for循环来实现遍历,例如list.string.dict 迭代器: 不仅可以使用for循环,还可以使用next()方法.__iter__() next():获取容 ...

  2. AI阅读助手ChatDOC:基于 AI 与文档对话、重新定义阅读方式的AI文献阅读和文档处理工具

    让 AI 真正成为你的生产力超级助手 AI 时代降临,我们需要积极拥抱 AI 工具 在过去的 2 个多月里,以 ChatGPT 为代表的 AI 风靡全球.随着 GPT 模型的不断优化,ChatGPT ...

  3. C语言实现url解析小实例

    一.前言 前面一口君写了一篇关于url的文章: <一文带你理解URI 和 URL 有什么区别?> 本篇在此基础上,编写一个简单的用于解析url的小例子, 最终目标是解析出URL中所有的数据 ...

  4. Devexpress 控件学习记录(一:BarManager 控件、XtraTabbedMdiManager 控件)

    BarManager 控件 最终实现的效果如下: 首先在窗体中拖出BarManager控件,窗体Bar add地方点击添加 设置BarManager的属性 设置出现的窗体的底部[DockStyle=B ...

  5. CD、VCD、DVD、BD 傻傻分不清楚?

    CD 激光唱片(Compact Disk, CD),于 1982 年面世,最初用于存储数字音频.容量约 700 MB(80 分钟音频). 激光唱片 | 维基百科 VCD 影音光盘(Video Comp ...

  6. Mac 使用远程 Ubuntu 机器进行时间备份

    设置 SMB 服务 首先在 Ubuntu 中配置 SMB 服务.可以参考 Ubuntu 设置 SMB 服务. 创建 APFS 磁盘映像 我们在 Ubuntu 上创建出的 SMB 共享文件夹可以用来存放 ...

  7. idea 的Tomcat 的简单配置

    不限速网盘下载: https://kohler.lanzouv.com/iSSfc0akw3vc 官网下载: https://tomcat.apache.org/download-80.cgi 正常解 ...

  8. webpack笔记-webpack初识与构建工具发展(一)

    为什么需要构建工具? 转换 ES6 语法 转换 JSX CSS 前缀补全/预处理器 压缩混淆 图片压缩 前端构建演变之路 ant + YUI Tool grunt gulp.fis3 webpack. ...

  9. RxJS 系列 – Observable to Subject (Hot, Cold, Warm, connectable, share)

    前言 前两篇介绍了 Observable 和 Subject.它们有一个重大区别当 multiple subscribe 的时候. Observable 每一次 subscribe 都会调用初始化方法 ...

  10. ASP.NET Core – 网站发布要做的事儿 Publish, Minification, Compression, Cache, HSTS, URL Rewrite Https & www, Close IIS Feature

    前言 要发布网站需要做一些优化, 比如 cache, compression, minification 等等. 以前有写过相关的文章: Asp.net core 学习笔记 ( IIS, static ...