PostgreSQL Public 模式的風(fēng)險(xiǎn)及安全遷移問(wèn)題小結(jié)
問(wèn)題起因
前幾天有群友在群里面咨詢(xún)
PG12,13,14,public模式是否可以刪除或改名?
因?yàn)檫@位群友的公司的PG規(guī)范做了修改,不讓使用public模式存放數(shù)據(jù),但是遺留問(wèn)題沒(méi)辦法。
另外一位群友說(shuō)到
你還真不好動(dòng)public。擴(kuò)展的插件的函數(shù)大多默認(rèn)都在public 下。


PG中默認(rèn)的public模式帶來(lái)的問(wèn)題
- 安全性問(wèn)題
public 模式默認(rèn)對(duì)所有數(shù)據(jù)庫(kù)用戶(hù)都開(kāi)放訪(fǎng)問(wèn)權(quán)限。換句話(huà)說(shuō),所有連接到數(shù)據(jù)庫(kù)的用戶(hù)默認(rèn)都可以訪(fǎng)問(wèn) public 模式中的對(duì)象(除非你手動(dòng)修改權(quán)限)。
- 命名沖突
public 模式是所有用戶(hù)和所有擴(kuò)展默認(rèn)使用的模式,容易發(fā)生命名沖突。
- 可維護(hù)性和隔離性
使用 public 模式進(jìn)行業(yè)務(wù)操作會(huì)使數(shù)據(jù)庫(kù)的架構(gòu)設(shè)計(jì)顯得雜亂無(wú)章,隨著時(shí)間推移,尤其是在大型項(xiàng)目或多個(gè)項(xiàng)目共享數(shù)據(jù)庫(kù)時(shí),public模式中的對(duì)象數(shù)量會(huì)急劇增加
- 版本和擴(kuò)展的兼容性問(wèn)題
許多 PostgreSQL 擴(kuò)展默認(rèn)使用 public 模式,如果修改 public 模式或刪除它,可能會(huì)導(dǎo)致擴(kuò)展無(wú)法正常工作
能否重命名 public 模式
我們能不能通過(guò)下面命令對(duì)public 模式名重命名 ?
ALTER SCHEMA public RENAME TO you_schema;
實(shí)際上重命名 public 模式是不推薦的做法,原因如下
- 依賴(lài)性問(wèn)題:許多擴(kuò)展、插件和默認(rèn)的 PostgreSQL 設(shè)置都假定 public 模式存在。如果直接修改 public 的名稱(chēng),會(huì)導(dǎo)致這些依賴(lài)出現(xiàn)問(wèn)題。
- 升級(jí)問(wèn)題:未來(lái)如果 PostgreSQL 版本升級(jí),系統(tǒng)或新安裝的擴(kuò)展可能仍然依賴(lài)于 public 模式存在。
因此,最好的做法是保留 public 模式,但不在業(yè)務(wù)中使用它。
如何解決這個(gè)問(wèn)題
實(shí)際上,我們可以使用遷移的方式,新建一個(gè)模式,然后把public模式下的所有業(yè)務(wù)對(duì)象遷移到新建模式下
具體步驟
第一步:創(chuàng)建新的模式
CREATE SCHEMA employee;
第二步:遷移所有對(duì)象:對(duì)表、視圖、函數(shù)、存儲(chǔ)過(guò)程等對(duì)象分別執(zhí)行 SET SCHEMA 操作,將它們從 public 模式遷移到 employee 模式。
遷移對(duì)象時(shí)小心依賴(lài)關(guān)系,如外鍵、索引、函數(shù)依賴(lài)等,遷移時(shí)需要確保這些依賴(lài)關(guān)系不被破壞
使用以下命令逐個(gè)遷移:
-- 遷移所有表 ALTER TABLE public.table_name SET SCHEMA employee; -- 遷移所有視圖 ALTER VIEW public.view_name SET SCHEMA employee; -- 遷移所有函數(shù) ALTER FUNCTION public.function_name SET SCHEMA employee; -- 遷移所有存儲(chǔ)過(guò)程 ALTER PROCEDURE public.procedure_name SET SCHEMA employee;
使用 SQL 動(dòng)態(tài)語(yǔ)句和 PL/pgSQL 編寫(xiě)一個(gè)循環(huán)來(lái)批量遷移 public 模式中的所有表、視圖、函數(shù)和存儲(chǔ)過(guò)程到 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;
-- 遷移所有函數(shù)
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;
-- 遷移所有存儲(chǔ)過(guò)程
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 $$;第三步:設(shè)置 search_path 通過(guò)調(diào)整 search_path 讓數(shù)據(jù)庫(kù)默認(rèn)使用 employee 模式。
search_path 的設(shè)置順序非常重要。
將 employee 模式放在前面,確保在業(yè)務(wù)操作時(shí)優(yōu)先查找 employee 模式的對(duì)象,而 public 作為備選模式保留(方便擴(kuò)展和插件的使用)。
可以修改 PostgreSQL 的 postgresql.conf 文件,或者在會(huì)話(huà)級(jí)別設(shè)置 search_path:
SET search_path TO employee, public;
第四步:考慮擴(kuò)展和插件
許多擴(kuò)展和插件默認(rèn)使用 public 模式,例如 PostGIS、pgcrypto 等。
為了避免問(wèn)題,最好不要修改 public 模式,而是保持其作為擴(kuò)展使用的默認(rèn)模式。
為什么SQL Server 沒(méi)有這個(gè)問(wèn)題
SQL Server 沒(méi)有像 PostgreSQL 那樣對(duì) public 模式的強(qiáng)烈依賴(lài),并且其設(shè)計(jì)理念與 PostgreSQL 的 public 模式存在一些關(guān)鍵區(qū)別。
- 權(quán)限管理的不同
在 SQL Server 中,dbo 是默認(rèn)的 schema,所有數(shù)據(jù)庫(kù)用戶(hù)默認(rèn)情況下并不會(huì)擁有對(duì) dbo 這個(gè) schema 中對(duì)象的完全訪(fǎng)問(wèn)權(quán)限。只有擁有 db_owner 角色的用戶(hù)才可以完全控制 dbo 這個(gè) schema。
也就是說(shuō),除非用戶(hù)顯式授予對(duì) dbo 中對(duì)象的訪(fǎng)問(wèn)或修改權(quán)限,否則,普通用戶(hù)是不能隨意訪(fǎng)問(wèn)或修改 dbo 這個(gè) schema 下的對(duì)象的。
相比之下,PostgreSQL 的 public 這個(gè) schema 在默認(rèn)情況下是對(duì)所有用戶(hù)開(kāi)放的。這意味著所有用戶(hù)都可以在 public 這個(gè) schema 中創(chuàng)建對(duì)象,除非手動(dòng)限制權(quán)限。
PostgreSQL的設(shè)計(jì)會(huì)增加意外權(quán)限授予和數(shù)據(jù)泄露的風(fēng)險(xiǎn),因此在 PostgreSQL 中有時(shí)需要避免使用 public schema。
- 模式設(shè)計(jì)理念的不同
在 PostgreSQL 中,public schema 設(shè)計(jì)為一個(gè)所有用戶(hù)共享的默認(rèn)命名空間,因此經(jīng)常發(fā)生命名沖突、權(quán)限管理不嚴(yán)等問(wèn)題。
在 SQL Server 中,dbo 是為擁有數(shù)據(jù)庫(kù)完全控制權(quán)的用戶(hù)預(yù)留的默認(rèn)命名空間,通常普通用戶(hù)和 DBA 可以自行創(chuàng)建自定義 schema 來(lái)組織和隔離各自的數(shù)據(jù)庫(kù)對(duì)象。
參考文章
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
到此這篇關(guān)于PostgreSQL Public 模式的風(fēng)險(xiǎn)以及安全遷移的文章就介紹到這了,更多相關(guān)PostgreSQL Public 模式遷移內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PostgreSQL使用執(zhí)行計(jì)劃的入門(mén)到實(shí)戰(zhàn)調(diào)優(yōu)指南
在數(shù)據(jù)庫(kù)性能優(yōu)化領(lǐng)域,執(zhí)行計(jì)劃(Execution?Plan)是開(kāi)發(fā)者與數(shù)據(jù)庫(kù)優(yōu)化器對(duì)話(huà)的翻譯器,PostgreSQL的執(zhí)行計(jì)劃不僅揭示了SQL語(yǔ)句的執(zhí)行路徑,更通過(guò)成本估算、實(shí)際耗時(shí)等關(guān)鍵指標(biāo),,為性能瓶頸定位提供了科學(xué)依據(jù),本文將系統(tǒng)講解PostgreSQL執(zhí)行計(jì)劃的核心機(jī)制與調(diào)優(yōu)方法2026-01-01
Postgresql 數(shù)據(jù)庫(kù)權(quán)限功能的使用總結(jié)
這篇文章主要介紹了Postgresql 數(shù)據(jù)庫(kù)權(quán)限功能的使用總結(jié),具有很好的參考價(jià)值,對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02
PostgreSQL數(shù)據(jù)庫(kù)中如何保證LIKE語(yǔ)句的效率(推薦)
這篇文章主要介紹了PostgreSQL數(shù)據(jù)庫(kù)中如何保證LIKE語(yǔ)句的效率,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
PostgreSQL Partition Pruning(分區(qū)裁剪)的原理、應(yīng)用和性能優(yōu)化指南
本文深入探討PostgreSQL中Partition Pruning(分區(qū)裁剪)技術(shù)的實(shí)現(xiàn)原理、應(yīng)用場(chǎng)景和優(yōu)化方法,通過(guò)詳細(xì)解析分區(qū)裁剪的工作機(jī)制,結(jié)合范圍分區(qū)、列表分區(qū)和哈希分區(qū)的實(shí)際案例,展示如何有效利用這一優(yōu)化技術(shù)提升查詢(xún)性能,需要的朋友可以參考下2025-07-07
PostgreSQL如何選擇合適的數(shù)據(jù)類(lèi)型
本文詳細(xì)介紹了PostgreSQL中各種數(shù)據(jù)類(lèi)型的特性、適用場(chǎng)景、潛在陷阱及最佳實(shí)踐,涵蓋了數(shù)值、字符、時(shí)間、布爾、枚舉、網(wǎng)絡(luò)、JSON、幾何、全文搜索、范圍、自定義類(lèi)型等核心類(lèi)別,并通過(guò)真實(shí)案例說(shuō)明了數(shù)據(jù)類(lèi)型選型的邏輯,感興趣的朋友跟隨小編一起看看吧2026-01-01
解決postgresql無(wú)法遠(yuǎn)程訪(fǎng)問(wèn)的情況
這篇文章主要介紹了解決postgresql無(wú)法遠(yuǎn)程訪(fǎng)問(wèn)的情況,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01

