残荷 發表於 2025-9-21 19:20:00

MySQL的Schema是什么?

<p>本文已收录在Github,<strong>关注我,紧跟本系列专栏文章,咱们下篇再续!</strong></p>
<ul>
<li>🚀 魔都架构师 | 全网30W技术追随者</li>
<li>🔧 大厂分布式系统/数据中台实战专家</li>
<li>🏆 主导交易系统百万级流量调优 &amp; 车联网平台架构</li>
<li>🧠 AIGC应用开发先行者 | 区块链落地实践者</li>
<li>🌍 以技术驱动创新,我们的征途是改变世界!</li>
<li>👉 实战干货:编程严选网</li>
</ul>
<h2 id="1-schema概念">1 Schema概念</h2>
<p><img alt="" loading="lazy" src="https://img2024.cnblogs.com/other/1097393/202509/1097393-20250921192047113-2053234129.png" class="lazyload"></p>
<p>schema在数据库领域,表示数据库对象的集合,包含各种对象如:表、视图、存储过程和索引等。</p>
<h3 id="sql-标准">SQL 标准</h3>
<p>一个数据库(Database)可包含多个模式(Schema),模式是数据库对象的逻辑容器。</p>
<h3 id="oracle">Oracle</h3>
<p>Schema 与用户(User)强绑定。创建用户时就等于创建了一个同名 Schema。用户(user)就是 schema 的拥有者,用户名称与 schema 名通常一致。一般一个用户对应一个集合,为了区分,需给不同集合起名。其实一个用户/角色可拥有多个 schema,多个用户也可以访问同一个 schema(通过权限授权)。</p>
<p>用户的schema名相当于用户名,并作为该用户的缺省schema。所以schema集合看上去像用户名。如访问一个数据表时,若该表未指明属于哪个schema,系统会自动加上默认schema:</p>
<p><img alt="" loading="lazy" src="https://img2024.cnblogs.com/other/1097393/202509/1097393-20250921192047776-2146730127.png" class="lazyload"></p>
<h3 id="postgresql">PostgreSQL</h3>
<p>schem是数据库内的命名空间,可由任一角色拥有;数据库中常见的 <code>public</code> schema 与角色不一一对应,角色可以拥有多个 schema,schema 名不等于用户名。解析未限定对象时依赖 <code>search_path</code>(搜索路径)。</p>
<h3 id="sql-server">SQL Server</h3>
<p>自 SQL Server 2005 起,<strong>schema 与数据库用户分离</strong>(schema 是命名空间,用户可有默认 schema,如 <code>dbo</code>)。所以 username ≠ schema name(尽管历史上两者关系紧密)。用户可以有默认 Schema,但 Schema 本身是独立对象。</p>
<h3 id="mysql">MySQL</h3>
<p>把 <code>database</code> 与 <code>schema</code> 视作同义词(<code>CREATE SCHEMA</code> = <code>CREATE DATABASE</code>);MySQL 没有像 PostgreSQL 那样的 schema 命名空间概念。</p>
<h2 id="2-schema的创建">2 Schema的创建</h2>
<p>在不同数据库中要创建的Schema方法不一,但共同点是都支持CREATE SCHEMA语句。MySQL中可通过CREATE SCHEMA创建一个数据库。</p>
<p>不同 DBMS 的 <code>CREATE SCHEMA</code> 语义和可用选项不同,如:</p>
<ul>
<li>PostgreSQL 支持 <code>CREATE SCHEMA name AUTHORIZATION owner</code></li>
<li>Oracle 的 <code>CREATE SCHEMA</code> 语法存在但不常用于创建用户,通常用 <code>CREATE USER</code> 来建立 schema 所属的用户)</li>
</ul>
<p>Oracle / PostgreSQL / MySQL / SQL Server 在 schema 概念、默认行为和常用语法上的差异:</p>
<ul>
<li><strong>PostgreSQL</strong></li>
</ul>
<pre><code class="language-sql">CREATE SCHEMA myschema AUTHORIZATION myrole;
SET search_path TO myschema, public;
-- unqualified object -&gt; 按 search_path 解析
</code></pre>
<ul>
<li><strong>SQL Server</strong></li>
</ul>
<pre><code class="language-sql">CREATE SCHEMA Sales AUTHORIZATION dbo;
ALTER USER alice WITH DEFAULT_SCHEMA = Sales;
-- 未限定的表名先在 alice 的默认 schema 中查找,再到 dbo 等
</code></pre>
<ul>
<li><strong>MySQL</strong></li>
</ul>
<pre><code class="language-sql">CREATE DATABASE mydb;   -- 或 CREATE SCHEMA mydb;
USE mydb;
CREATE TABLE t1 (...);
</code></pre>
<ul>
<li><strong>Oracle(常见用法)</strong></li>
</ul>
<pre><code class="language-sql">CREATE USER scott IDENTIFIED BY tiger;
GRANT CONNECT, RESOURCE TO scott;
-- scott 有自己的 schema(对象以 scott. 开头)
</code></pre>
<h2 id="3-默认解析规则">3 默认解析规则</h2>
<p>不同数据库在你未显式指定 Schema 时,解析对象名的方式不同:</p>
<h3 id="postgresql-1">PostgreSQL</h3>
<p>使用 <code>search_path</code> 参数决定解析顺序:</p>
<pre><code class="language-sql">SET search_path TO myschema, public;
SELECT * FROM mytable;-- 优先在 myschema 中查找
</code></pre>
<p>默认包含 <code>"$user", public</code>,即先尝试与当前用户名同名的 Schema,再找 <code>public</code>。</p>
<h3 id="sql-server-1">SQL Server</h3>
<p>用户有一个 <strong>默认 Schema</strong>:</p>
<pre><code class="language-sql">ALTER USER alice WITH DEFAULT_SCHEMA = Sales;
SELECT * FROM Orders;   -- 会先到 Sales.Orders 查找
</code></pre>
<p>如果对象在默认 Schema 不存在,会尝试 <code>dbo</code>。</p>
<h3 id="mysql-1">MySQL</h3>
<p>使用 <code>USE dbname</code> 设置当前数据库:</p>
<pre><code class="language-sql">USE mydb;
SELECT * FROM mytable;-- 实际为 mydb.mytable
</code></pre>
<p>没有独立的 Schema 概念。</p>
<h3 id="oracle-1">Oracle</h3>
<p>登录用户的名字就是 Schema:</p>
<pre><code class="language-sql">CONNECT scott/tiger;
SELECT * FROM emp;-- 实际为 scott.emp
</code></pre>
<p>若要访问其他用户对象,需要显式加前缀(如 <code>hr.employees</code>)并具备权限。</p>
<h2 id="4-权限与所有权">4 权限与所有权</h2>
<h3 id="创建-schema">创建 Schema</h3>
<p>PostgreSQL</p>
<pre><code class="language-sql">CREATE SCHEMA myschema AUTHORIZATION alice;
</code></pre>
<p><code>alice</code> 拥有该 Schema,对象默认归她所有。</p>
<p>SQL Server</p>
<pre><code class="language-sql">CREATE SCHEMA Sales AUTHORIZATION dbo;
</code></pre>
<p>MySQL</p>
<pre><code class="language-sql">CREATE DATABASE mydb;-- 或 CREATE SCHEMA mydb;
</code></pre>
<p>Oracle<br>
通常通过 <code>CREATE USER</code> 创建用户即可间接创建 Schema。</p>
<h3 id="授权访问">授权访问</h3>
<p>PostgreSQL</p>
<pre><code class="language-sql">GRANT USAGE ON SCHEMA myschema TO bob;
GRANT SELECT ON ALL TABLES IN SCHEMA myschema TO bob;
</code></pre>
<p>SQL Server</p>
<pre><code class="language-sql">GRANT SELECT ON SCHEMA::Sales TO bob;
</code></pre>
<p>Oracle</p>
<pre><code class="language-sql">GRANT SELECT ON scott.emp TO hr;
</code></pre>
<p><strong>修改默认 Schema / 搜索路径</strong>:</p>
<ul>
<li>PostgreSQL:<code>SET search_path</code></li>
<li>SQL Server:<code>ALTER USER … WITH DEFAULT_SCHEMA</code></li>
<li>MySQL:<code>USE dbname</code></li>
<li>Oracle:无直接机制,登录用户默认使用自身 Schema</li>
</ul>
<h2 id="5-schema-vs-database-vs-catalog">5 Schema vs Database vs Catalog</h2>
<h3 id="database">Database</h3>
<ul>
<li>SQL 标准:数据库是 Catalog 的一种实现,包含多个 Schema。</li>
<li>实际上,不同产品语义不同:
<ul>
<li>PostgreSQL:一个 <strong>Database</strong> 包含多个 Schema。</li>
<li>SQL Server:一个 <strong>Database</strong> 包含多个 Schema。</li>
<li>Oracle:一个数据库实例通常只包含一组用户 Schema。</li>
<li>MySQL:<strong>Database 与 Schema 等价</strong>。</li>
</ul>
</li>
</ul>
<h3 id="schema">Schema</h3>
<p>命名空间,组织数据库对象。</p>
<h3 id="catalog">Catalog</h3>
<p>SQL 标准中的更大逻辑容器,常对应一个数据库实例。实际中较少直接使用。</p>
<h2 id="6-总结">6 总结</h2>
<p>四大主流数据库 Schema 特性对照:</p>
<table>
<thead>
<tr>
<th>特性</th>
<th><strong>Oracle</strong></th>
<th><strong>PostgreSQL</strong></th>
<th><strong>SQL Server</strong></th>
<th><strong>MySQL</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Schema 与用户关系</strong></td>
<td>用户 = Schema(1:1),创建用户即创建 Schema</td>
<td>Schema 独立于用户,用户可拥有多个 Schema</td>
<td>自 2005 起,Schema 与用户分离;用户有默认 Schema</td>
<td>Schema = Database;无独立 Schema 概念</td>
</tr>
<tr>
<td><strong>默认 Schema 行为</strong></td>
<td>登录用户即默认 Schema,例如 <code>scott.emp</code></td>
<td>由 <code>search_path</code> 决定,默认 <code>"$user", public</code></td>
<td>用户默认 Schema(可改),否则 fallback 到 <code>dbo</code></td>
<td><code>USE dbname</code> 设定当前数据库,表解析为 <code>dbname.table</code></td>
</tr>
<tr>
<td><strong>创建方式</strong></td>
<td><code>CREATE USER scott IDENTIFIED BY pwd;</code>(即创建 Schema)</td>
<td><code>CREATE SCHEMA myschema AUTHORIZATION alice;</code></td>
<td><code>CREATE SCHEMA Sales AUTHORIZATION dbo;</code></td>
<td><code>CREATE DATABASE mydb;</code> 或 <code>CREATE SCHEMA mydb;</code></td>
</tr>
<tr>
<td><strong>跨 Schema 访问</strong></td>
<td><code>hr.employees</code>(需权限)</td>
<td><code>other_schema.table</code>(需 <code>USAGE</code> 权限)</td>
<td><code>Sales.Orders</code>(需权限)</td>
<td><code>otherdb.table</code>(需权限)</td>
</tr>
<tr>
<td><strong>权限控制</strong></td>
<td><code>GRANT SELECT ON scott.emp TO hr;</code></td>
<td><code>GRANT USAGE ON SCHEMA myschema TO bob;``GRANT SELECT ON ALL TABLES IN SCHEMA myschema TO bob;</code></td>
<td><code>GRANT SELECT ON SCHEMA::Sales TO bob;</code></td>
<td><code>GRANT SELECT ON mydb.mytable TO 'bob'@'host';</code></td>
</tr>
<tr>
<td><strong>修改默认 Schema</strong></td>
<td>不支持(用户即 Schema)</td>
<td><code>SET search_path TO myschema, public;</code></td>
<td><code>ALTER USER alice WITH DEFAULT_SCHEMA = Sales;</code></td>
<td><code>USE dbname;</code></td>
</tr>
<tr>
<td><strong>术语说明</strong></td>
<td>Schema ≈ User</td>
<td>Database ⊃ Schema</td>
<td>Database ⊃ Schema</td>
<td>Schema = Database</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>Oracle</strong>:用户就是 Schema</li>
<li><strong>PostgreSQL</strong>:Schema 是独立命名空间,靠 <code>search_path</code> 解析</li>
<li><strong>SQL Server</strong>:Schema 独立,用户有默认 Schema,常见是 <code>dbo</code></li>
<li><strong>MySQL</strong>:Schema = Database,没有独立命名空间</li>
</ul>
<blockquote>
<p>本文由博客一文多发平台 OpenWrite 发布!</p>
</blockquote><br><br>
来源:https://www.cnblogs.com/JavaEdge/p/19104009
頁: [1]
查看完整版本: MySQL的Schema是什么?