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

  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

 

本文版权归作者所有,未经作者同意不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/824469.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

读数据湖仓09读后总结与感想兼导读

读后总结与感想兼导读1. 基本信息 数据湖仓[美]比尔恩门(BillInmon);[美]戴夫拉皮恩(DaveRapien);[美]瓦莱丽特(ValerieBartelt)著人民邮电出版社2024年7月出版1.1. 读薄率 书籍总字数???千字,笔记总字数23238字。 读薄率23238???000≈??% 1.2. 读厚方向构建可…

library官网登录入口,zlibrary中文网及客户端/app

Z-Library是一个全球知名的在线数字图书馆和文件共享网站,以下是它的详细介绍:藏书量丰富:Z-Library拥有超过9,826,996本电子书和84,837,646篇学术期刊文章,覆盖了从经典文学到前沿理工学科,从人文艺术到专业学术论文的广泛领域。 多种格式支持:Z-Library支持多种电子书格…

视频恶劣天气消除的扩散测试时间适应性

实践中的真知灼见:视频恶劣天气消除的扩散测试时间适应性现实世界中的视觉任务经常受到意外恶劣天气条件的影响,包括雨、霾、雪和雨滴。在过去的十年里,卷积神经网络和视觉变换器在单天气视频去除方面取得了突出成果。然而,由于缺乏适当的适应,它们中的大多数无法推广到其…

​【图吧杂谈】谈玄武电源短信轰炸开盒事件

​【图吧杂谈】谈玄武电源短信轰炸开盒事件 老铁们,我图吧老捡垃圾的了,今天谈谈如何评价在群里讨论玄武电源被开盒+短信轰炸? 事情是这样的,之前垃圾佬不是搁群里刷到了玄武代工厂3C认证显示抽检不合格的事吗,这事最近迎来了高潮,也带我们真正走近了这家赛博朋克企业看清…

chapter7

scheduler.py参数中文版第一题问题使用 SJF 和 FIFO 调度程序运行长度为 200 的 3 个作业时,计算响应时间和周转时间。第二题问题现在做同样的事情,但有不同长度的作业,即 100、200 和 300。第三题问题现在做同样的事情,但采用 RR 调度程序,时间片为 1。 输出太长了,不截…

MyBatis-Plus:简化 CRUD 操作的艺术

MyBatis-Plus 是一个基于 MyBatis 的增强工具,它旨在简化 MyBatis 的使用,提高开发效率。一、关于MyBatis-Plus 1.1 简介 MyBatis-Plus 是一个基于 MyBatis 的增强工具,它旨在简化 MyBatis 的使用,提高开发效率。 ​ ‍ ‍ ‍ ​ ‍ 关于Mybatis 简介 MyBatis 是一款流行的…

Redis持久化机制与位图api

持久化机制 将我们的内存数据 通过数据持久化写入磁盘中实现持化、 Redis官方提供了两种不同的持久化方法来将内存的数据存储到硬盘里面分别是:RDB持久化,快照(Snapshot)【默认】 AOF (Append Only File) 只追加日志文件【默认不开启】1.快照(snapshot)(关机慢开机快) redis…

js基础必看系列--2024-10-30总结

好的书写习惯最好不要省略分号,尤其对新手来说 确保 “use strict” 出现在最顶部"use strict"; 代码以现代模式工作【ES5 规范增加了新的语言特性并且修改了一些已经存在的特性。为了保证旧的功能能够使用,大部分的修改是默认不生效的。你需要一个特殊的指令 ——…

数据结构 - 散列表,三探之代码实现

本文介绍散列表代码实现,使用取模方式构建散列函数,实现链式法和开放寻址法(线性探测)解决碰撞,包含初始化、插入、删除、查找等功能,并实现了再散列方法,代码已上传至代码库。书接上回,我们继续来聊散列表的代码实现。相信通过前面两章对散列表的学习,大家应该已经掌…

yolo --- 名词解释

MAP 综合衡量检测结果(所有置信度阈值对应的精度、召回率的平均,即下图红线面积,面积越大,效果越好;理想效果是任何召回率下精度都是1) 置信度:判断为目标的概率(0~1)精度和召回率 TP:正确的判断出目标(目标判断为目标) FP:错误的判断为目标(非目标判断为目标) …

GPT释放的意图识别想象力

一、ChatGPT与GPTChatGPT是一个聊天应用。一个输入框,输入你想问他的任何问题,他会给你一个答案,并且这个答案看起来是经过思考、讲究语法并且正确的。他理解你的语言,并能用你的语言给你答案。 而这背后,就是GPT这个大模型在发挥作用(Generative Pre-trained Transforme…