<?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>Dml on Tarragon</title><link>https://tarrragon.github.io/blog/tags/dml/</link><description>Recent content in Dml on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Tue, 01 Sep 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/dml/index.xml" rel="self" type="application/rss+xml"/><item><title>DDL 與 DML（定義結構與動資料）</title><link>https://tarrragon.github.io/blog/backend/01-database/sql/knowledge-cards/ddl-dml/</link><pubDate>Tue, 01 Sep 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/backend/01-database/sql/knowledge-cards/ddl-dml/</guid><description>&lt;p>SQL 的語句按它改動的對象分成兩類。&lt;strong>DDL&lt;/strong>（Data Definition Language）改的是結構——&lt;code>CREATE&lt;/code>、&lt;code>ALTER&lt;/code>、&lt;code>DROP&lt;/code>，它動的是有哪些表、每張表有哪些欄位。&lt;strong>DML&lt;/strong>（Data Manipulation Language）改的是結構裡裝的資料——&lt;code>INSERT&lt;/code>、&lt;code>UPDATE&lt;/code>、&lt;code>DELETE&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;code>SELECT&lt;/code> 只讀不改，各家文件有的把它算進 DML、有的另立一類。&lt;/p>
&lt;h2 id="這條線在權限上有實際後果">這條線在權限上有實際後果&lt;/h2>
&lt;p>兩類的&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>是分開的，而它們在日常運行裡的頻率差很多：應用程式跑起來之後幾乎只做 DML，DDL 只在部署或遷移的時候用一次。這讓最小權限有一個明確的切法——常態運行的帳號不給 DDL，遷移用另一個帳號。&lt;/p>
&lt;p>代價的形狀也不同。一句 DML 寫錯影響的是那些列，可以用另一句 DML 補回來；一句 DDL 寫錯（&lt;code>DROP TABLE&lt;/code> 那一類）拿掉的是結構，補救要靠備份。&lt;/p>
&lt;h2 id="兩類的擋法不在同一層">兩類的擋法不在同一層&lt;/h2>
&lt;p>DML 的權限掛在表上——&lt;code>GRANT SELECT ON 顧客&lt;/code>。DDL 的權限多數掛在更上面一層：能不能建新表由 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/knowledge-cards/schema-namespace/" data-link-title="Schema（命名空間義）" data-link-desc="看到 permission denied for schema、或想確認這個字指的是表結構還是命名空間時">schema&lt;/a> 那一層決定，不是由某一張表決定，因為建的時候那張表還不存在。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>這條線切的是語句改動的對象，而 SQL 的其餘概念多數只活在 DML 這一側——&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;a href="https://tarrragon.github.io/blog/backend/01-database/sql/knowledge-cards/outer-join/" data-link-title="Outer Join（外連接）" data-link-desc="想確認 LEFT / RIGHT / FULL 各自保護哪一側、或連接之後有些人從名單上消失時">外連接&lt;/a>、分組、&lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/knowledge-cards/subquery/" data-link-title="Subquery（子查詢）" data-link-desc="看到括號裡還有一個 SELECT、想知道它什麼時候算、算幾次時">子查詢&lt;/a> 全部是在既有結構上取資料的方式。DDL 決定那個結構長什麼樣，它跑完之後才輪到那些概念。&lt;/p>
&lt;p>兩類在時間上的分布因此完全不同：DDL 集中在部署那幾分鐘，DML 散在系統活著的每一秒。權限、備份策略與事故的補救方式都跟著這條線分。&lt;/p>
&lt;h2 id="往下走">往下走&lt;/h2>
&lt;p>授權的單位與最小權限的具體切法在 &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 這一層，以及最小權限在應用程式帳號上成立的前提">SQL.16 SQL 的權限模型：角色、GRANT 的授權單位與最小權限&lt;/a>。DDL 權限實際被用到的場合（雙寫、回填、切流、回滾）在 &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、回填、驗證查詢、切流與回滾；換資料庫引擎的遷移不在範圍內">資料庫轉換實作&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>SQL 的語句按它改動的對象分成兩類。<strong>DDL</strong>（Data Definition Language）改的是結構——<code>CREATE</code>、<code>ALTER</code>、<code>DROP</code>，它動的是有哪些表、每張表有哪些欄位。<strong>DML</strong>（Data Manipulation Language）改的是結構裡裝的資料——<code>INSERT</code>、<code>UPDATE</code>、<code>DELETE</code>，表還是那張表，變的是裡面有哪些列（列與欄這兩個字在本站的用法見 <a href="/blog/backend/01-database/sql/knowledge-cards/relation/" data-link-title="Relation（關係）" data-link-desc="看到 SQL 教材說「組成一個關係」而不確定它指的是不是資料表時">relation</a>）。<code>SELECT</code> 只讀不改，各家文件有的把它算進 DML、有的另立一類。</p>
<h2 id="這條線在權限上有實際後果">這條線在權限上有實際後果</h2>
<p>兩類的<a href="/blog/backend/01-database/sql/privilege-model/" data-link-title="SQL.16 SQL 的權限模型：角色、GRANT 的授權單位與最小權限" data-link-desc="新角色的預設權限、讀寫各自授權與收回的方式、建立物件的權限落在 schema 這一層，以及最小權限在應用程式帳號上成立的前提">授權</a>是分開的，而它們在日常運行裡的頻率差很多：應用程式跑起來之後幾乎只做 DML，DDL 只在部署或遷移的時候用一次。這讓最小權限有一個明確的切法——常態運行的帳號不給 DDL，遷移用另一個帳號。</p>
<p>代價的形狀也不同。一句 DML 寫錯影響的是那些列，可以用另一句 DML 補回來；一句 DDL 寫錯（<code>DROP TABLE</code> 那一類）拿掉的是結構，補救要靠備份。</p>
<h2 id="兩類的擋法不在同一層">兩類的擋法不在同一層</h2>
<p>DML 的權限掛在表上——<code>GRANT SELECT ON 顧客</code>。DDL 的權限多數掛在更上面一層：能不能建新表由 <a href="/blog/backend/01-database/sql/knowledge-cards/schema-namespace/" data-link-title="Schema（命名空間義）" data-link-desc="看到 permission denied for schema、或想確認這個字指的是表結構還是命名空間時">schema</a> 那一層決定，不是由某一張表決定，因為建的時候那張表還不存在。</p>
<h2 id="概念位置">概念位置</h2>
<p>這條線切的是語句改動的對象，而 SQL 的其餘概念多數只活在 DML 這一側——<a href="/blog/backend/01-database/sql/knowledge-cards/relation/" data-link-title="Relation（關係）" data-link-desc="看到 SQL 教材說「組成一個關係」而不確定它指的是不是資料表時">relation</a>、<a href="/blog/backend/01-database/sql/knowledge-cards/outer-join/" data-link-title="Outer Join（外連接）" data-link-desc="想確認 LEFT / RIGHT / FULL 各自保護哪一側、或連接之後有些人從名單上消失時">外連接</a>、分組、<a href="/blog/backend/01-database/sql/knowledge-cards/subquery/" data-link-title="Subquery（子查詢）" data-link-desc="看到括號裡還有一個 SELECT、想知道它什麼時候算、算幾次時">子查詢</a> 全部是在既有結構上取資料的方式。DDL 決定那個結構長什麼樣，它跑完之後才輪到那些概念。</p>
<p>兩類在時間上的分布因此完全不同：DDL 集中在部署那幾分鐘，DML 散在系統活著的每一秒。權限、備份策略與事故的補救方式都跟著這條線分。</p>
<h2 id="往下走">往下走</h2>
<p>授權的單位與最小權限的具體切法在 <a href="/blog/backend/01-database/sql/privilege-model/" data-link-title="SQL.16 SQL 的權限模型：角色、GRANT 的授權單位與最小權限" data-link-desc="新角色的預設權限、讀寫各自授權與收回的方式、建立物件的權限落在 schema 這一層，以及最小權限在應用程式帳號上成立的前提">SQL.16 SQL 的權限模型：角色、GRANT 的授權單位與最小權限</a>。DDL 權限實際被用到的場合（雙寫、回填、切流、回滾）在 <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同一個資料庫引擎內 schema 演進與資料變更的分段驗證流程：expand-contract、回填、驗證查詢、切流與回滾；換資料庫引擎的遷移不在範圍內">資料庫轉換實作</a>。</p>
]]></content:encoded></item></channel></rss>