<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Namespace on Tarragon</title><link>https://tarrragon.github.io/blog/tags/namespace/</link><description>Recent content in Namespace on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Mon, 31 Aug 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/namespace/index.xml" rel="self" type="application/rss+xml"/><item><title>Schema（命名空間義）</title><link>https://tarrragon.github.io/blog/backend/01-database/sql/knowledge-cards/schema-namespace/</link><pubDate>Mon, 31 Aug 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/backend/01-database/sql/knowledge-cards/schema-namespace/</guid><description>&lt;p>在 PostgreSQL 這類資料庫裡，schema 是資料庫底下的一層命名空間，表、索引、序列這些物件都住在某一個 schema 裡。預設的那一個叫 &lt;code>public&lt;/code>。它與&lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/privilege-model/" data-link-title="SQL.16 SQL 的權限模型：角色、GRANT 的授權單位與最小權限" data-link-desc="新角色的預設權限、讀寫各自授權與收回的方式、建立物件的權限落在 schema 這一層，以及最小權限在應用程式帳號上成立的前提">權限&lt;/a>是分層的：對表的授權管的是讀寫那張表，對 schema 的授權管的是能不能在裡面建立新物件——而表是一種 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/knowledge-cards/relation/" data-link-title="Relation（關係）" data-link-desc="看到 SQL 教材說「組成一個關係」而不確定它指的是不是資料表時">relation&lt;/a>。&lt;/p>
&lt;p>&lt;strong>這個字有另一個常見的所指——「表結構」，也就是有哪些表、每張表有哪些欄位、型別與約束是什麼。&lt;/strong> 兩者不同層：命名空間是容器，表結構是被裝的東西。談 schema migration 的時候用的是後者，談 &lt;code>permission denied for schema public&lt;/code> 的時候用的是前者。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>分層在錯誤訊息上看得出來。一個角色被拒絕讀某張表，訊息是 &lt;code>permission denied for table 顧客&lt;/code>；同一個角色被拒絕建新表，訊息是 &lt;code>permission denied for schema public&lt;/code>——擋的位置不同，要授的權也不同。被擋住的那些物件裡最常見的是表，而表是一種 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/knowledge-cards/relation/" data-link-title="Relation（關係）" data-link-desc="看到 SQL 教材說「組成一個關係」而不確定它指的是不是資料表時">relation&lt;/a>。&lt;/p>
&lt;p>PostgreSQL 15 之後 &lt;code>public&lt;/code> schema 預設不再開放給所有人建立物件，在那之前這個操作會成功。同一段 SQL 在不同版本上的結果因此不同，而差別在預設值不在語法。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>&lt;code>information_schema&lt;/code> 本身就是一個 schema，裡面裝著描述其他物件的視圖。查自己有哪些授權用的 &lt;code>information_schema.role_table_grants&lt;/code> 就是「schema 名.表名」這個兩段式的寫法。&lt;/p>
&lt;p>不是每個資料庫都有這一層。SQLite 沒有 schema 也沒有使用者，整個資料庫是一個檔案，存取由檔案系統決定。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>看到這個字先判它在哪一層。判斷方法是看它旁邊的動詞：跟「建立物件」「授權」「限定名稱」一起出現的是命名空間；跟「欄位」「型別」「遷移」「版本」一起出現的是表結構。&lt;/p>
&lt;p>兩者在部署上也分工：命名空間常用來把不同租戶或不同應用的物件隔開，而表結構的演進是另一組問題——雙寫、回填、切流與回滾，那些在 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同一個資料庫引擎內 schema 演進與資料變更的分段驗證流程：expand-contract、回填、驗證查詢、切流與回滾；換資料庫引擎的遷移不在範圍內">backend 模組一的資料庫轉換實作&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>在 PostgreSQL 這類資料庫裡，schema 是資料庫底下的一層命名空間，表、索引、序列這些物件都住在某一個 schema 裡。預設的那一個叫 <code>public</code>。它與<a href="/blog/backend/01-database/sql/privilege-model/" data-link-title="SQL.16 SQL 的權限模型：角色、GRANT 的授權單位與最小權限" data-link-desc="新角色的預設權限、讀寫各自授權與收回的方式、建立物件的權限落在 schema 這一層，以及最小權限在應用程式帳號上成立的前提">權限</a>是分層的：對表的授權管的是讀寫那張表，對 schema 的授權管的是能不能在裡面建立新物件——而表是一種 <a href="/blog/backend/01-database/sql/knowledge-cards/relation/" data-link-title="Relation（關係）" data-link-desc="看到 SQL 教材說「組成一個關係」而不確定它指的是不是資料表時">relation</a>。</p>
<p><strong>這個字有另一個常見的所指——「表結構」，也就是有哪些表、每張表有哪些欄位、型別與約束是什麼。</strong> 兩者不同層：命名空間是容器，表結構是被裝的東西。談 schema migration 的時候用的是後者，談 <code>permission denied for schema public</code> 的時候用的是前者。</p>
<h2 id="概念位置">概念位置</h2>
<p>分層在錯誤訊息上看得出來。一個角色被拒絕讀某張表，訊息是 <code>permission denied for table 顧客</code>；同一個角色被拒絕建新表，訊息是 <code>permission denied for schema public</code>——擋的位置不同，要授的權也不同。被擋住的那些物件裡最常見的是表，而表是一種 <a href="/blog/backend/01-database/sql/knowledge-cards/relation/" data-link-title="Relation（關係）" data-link-desc="看到 SQL 教材說「組成一個關係」而不確定它指的是不是資料表時">relation</a>。</p>
<p>PostgreSQL 15 之後 <code>public</code> schema 預設不再開放給所有人建立物件，在那之前這個操作會成功。同一段 SQL 在不同版本上的結果因此不同，而差別在預設值不在語法。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p><code>information_schema</code> 本身就是一個 schema，裡面裝著描述其他物件的視圖。查自己有哪些授權用的 <code>information_schema.role_table_grants</code> 就是「schema 名.表名」這個兩段式的寫法。</p>
<p>不是每個資料庫都有這一層。SQLite 沒有 schema 也沒有使用者，整個資料庫是一個檔案，存取由檔案系統決定。</p>
<h2 id="設計責任">設計責任</h2>
<p>看到這個字先判它在哪一層。判斷方法是看它旁邊的動詞：跟「建立物件」「授權」「限定名稱」一起出現的是命名空間；跟「欄位」「型別」「遷移」「版本」一起出現的是表結構。</p>
<p>兩者在部署上也分工：命名空間常用來把不同租戶或不同應用的物件隔開，而表結構的演進是另一組問題——雙寫、回填、切流與回滾，那些在 <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同一個資料庫引擎內 schema 演進與資料變更的分段驗證流程：expand-contract、回填、驗證查詢、切流與回滾；換資料庫引擎的遷移不在範圍內">backend 模組一的資料庫轉換實作</a>。</p>
]]></content:encoded></item></channel></rss>