应用容器
在 CDB 中,可以为可由 PDB 共享的应用程序数据和元数据创建容器。
-
关于应用程序容器 应用程序容器是用户创建的可选 CDB 组件,用于存储一个或多个应用程序后端的数据和元数据。CDB 包含零个或多个应用程序容器。
-
应用程序公用对象 应用程序公用对象是在应用程序根中的应用程序内创建的公用对象。公用对象是数据链接对象或元数据链接对象。
-
容器映射 容器映射可让连接到应用程序根的会话发出 SQL 语句,这些 SQL 语句根据 SQL 语句中使用的谓词值路由到相应 PDB。
关于应用程序容器
应用程序容器是用户创建的可选 CDB 组件,用于存储一个或多个应用程序后端的数据和元数据。CDB 包含零个或多个应用程序容器。
在 application container(应用程序容器)中, application(应用程序)是存储在应用程序根中的公用数据和元数据的命名版本化集。在应用程序容器的上下文中,“应用程序”一词是指“主应用程序定义”。例如,应用程序可能包括表、视图和程序包的定义。
例如,可以在一个应用程序容器内创建多个与销售相关的 PDB,这些 PDB 共享一个包含一组公用表和表定义的应用程序。可以将多个与 HR 相关的 PDB 存储在一个单独的应用程序容器中,并具有自己的公用表和表定义。
带有 AS APPLICATION CONTAINER 子句的 CREATE PLUGGABLE DATABASE 语句将创建应用程序容器的应用程序根,从而隐式创建应用程序容器本身。首次创建应用程序容器时,它不包含任何 PDB。要创建应用程序 PDB,必须连接到应用程序根,然后执行 CREATE PLUGGABLE DATABASE 语句。
在 CREATE PLUGGABLE DATABASE 语句中,必须指定容器名称(与应用程序根名称相同),例如 saas_sales_ac。应用程序容器名称在 CDB 内以及通过特定监听程序访问其实例的所有 CDB 的范围内必须唯一。每个应用程序容器都有一个与应用程序容器同名的默认服务。
-
应用程序容器的用途在某些方面,应用程序容器在 CDB 内充当特定于应用程序的 CDB。应用程序容器(如 CDB 本身)可以包含多个 PDB,并允许这些 PDB 共享元数据和数据。
-
应用程序根 一个应用程序容器只有一个应用程序根,即容器中应用程序 PDB 的父项。
-
应用程序 PDB 应用程序 PDB 是位于应用程序容器中的 PDB。CDB 中的每个 PDB 都位于零个或一个应用程序容器中。
-
应用程序种子 应用程序种子是在应用程序容器内由用户创建的可选 PDB。应用程序容器具有零个或一个应用程序种子。
应用程序容器的用途
在某些方面,应用程序容器在 CDB 内充当特定于应用程序的 CDB。应用程序容器(如 CDB 本身)可以包含多个 PDB,并允许这些 PDB 共享元数据和数据。
应用程序根使应用程序 PDB 能够共享应用程序,在这种情况下,这意味着一组命名且版本化的公用元数据和数据。典型的应用程序将安装应用程序公用用户、元数据链接公用对象和数据链接公用对象。
-
应用程序容器的主要优势 应用程序容器比将每个应用程序存储在单独的 PDB 中具有多项优势。
-
应用程序容器用例:SaaS 一个 SaaS 部署可以使用多个应用程序 PDB,每个应用程序 PDB 用于共享元数据和数据的单独客户。
-
应用程序容器用例:逻辑数据仓库客户可以使用多个应用程序 PDB 来解决数据主权问题。
应用容器的关键优势
与将每个应用程序存储在单独的 PDB 中相比,应用程序容器具有多项优势。
-
应用程序根存储所有应用程序 PDB 可以共享的元数据和数据。
例如,所有应用程序 PDB 都可以在中央表中共享数据,例如列出默认应用程序角色的表。此外,所有 PDB 都可以共享向其添加特定于 PDB 的行的表定义。
-
在应用程序根中维护主应用程序定义,而不是在每个 PDB 中维护单独的副本。
如果在应用程序根中升级应用程序,则更改会自动传播到所有应用程序 PDB。应用程序后端可能包含 data-linked common object
app_roles,这是一个列出默认角色的表:admin、manager、sales_rep等。连接到任何应用程序 PDB 的用户可以查询此表。 -
应用程序容器可以包括应用程序种子、应用程序 PDB 和代理 PDB(这些 PDB 指其他 CDB 中的 PDB)。
-
可以从应用程序种子快速创建新应用程序 PDB。
-
可以查询报告应用程序容器中所有 PDB 的视图。
-
连接到应用程序根时,可以使用
CONTAINERS函数对多个 PDB 中的对象执行 DML。例如,如果每个应用程序 PDB 中都存在
products表,则可以使用单个SELECT语句连接到应用程序根并查询所有应用程序 PDB 中的产品。 -
可以从应用程序根断开 PDB,然后将其插入到较高 Oracle 数据库发行版中的应用程序根。因此,PDB 在 Oracle 数据库升级中非常有用。
应用容器用例:SaaS
SaaS 部署可以使用多个应用程序 PDB,每个应用程序 PDB 分别用于共享元数据和数据的单独客户。
在纯 SaaS 环境中,主应用程序定义位于应用程序根中,但特定于客户的数据驻留在自己的应用程序 PDB 中。例如,sales_app 是应用程序根中的应用程序模型。名为 cust1_pdb 的应用程序 PDB 仅包含客户 1 的销售数据,而名为 cust2_pdb 的应用程序 PDB 仅包含客户 2 的销售数据。插入、断开、克隆和其他 PDB 级别操作可用于各个客户 PDB。
图 1:SaaS 用例

纯 SaaS 配置具有以下优点:
-
性能
-
安全性
-
支持多个客户
每个客户的数据都驻留在自己的容器中,但会经过整合,以便您可以共同管理许多客户。此模型将多项管理的规模经济扩展到应用程序管理员,而不仅仅是 DBA。
应用容器用例:逻辑数据仓库
客户可以使用多个应用程序 PDB 来解决数据主权问题。
在示例用例中,公司将特定于每个财务季度的数据放在一个单独的 PDB 中。例如,名为 sales_ac 的应用程序容器包括 q1_2016_pdb、q2_2016_pdb、q3_2016_pdb 和 q4_2016_pdb。在 PDB 中定义与关联季度对应的每个事务处理。要生成一个聚合一年性能的报告,可使用 CONTAINERS() 子句跨四个 PDB 进行聚合。
这种逻辑仓库设计的好处包括:
-
特定于单个 PDB 的数据的 ETL 不会影响其他 PDB。
-
执行计划更高效,因为它们基于实际数据分布。
应用程序根
应用程序容器只有一个 application root ,即容器中应用程序 PDB 的父项。
作为应用程序根的属性是在创建时建立的,无法更改。应用程序根所属的唯一容器是 CDB 根。应用程序根在某些方面类似于 CDB 根,而在其他方面类似于 PDB:
-
与 CDB 根一样,应用程序根充当插入该根的 PDB 的父容器。连接到应用程序根时,可以管理公用用户和权限、创建应用程序 PDB、切换容器以及发出适用于应用程序容器中所有 PDB 的 DDL。
-
与 PDB 类似,使用
CREATE PLUGGABLE DATABASE语句创建应用程序根,使用ALTER PLUGGABLE DATABASE更改该根,并使用STARTUP和SHUTDOWN更改其可用性。可以使用 DDL 插入、断开和删除应用程序根。应用程序根有自己的服务名称,用户可以以连接到 PDB 的方式连接到应用程序根。
应用程序根不同于 CDB 根和标准 PDB,因为它可以存储用户创建的公用对象,这些公用对象称为应用程序公用对象。应用程序公用对象可由插入到应用程序根的应用程序 PDB 访问。应用程序公用对象对于 CDB 根、其他应用程序根或不属于该应用程序根的 PDB 不可见。
示例 3-1 创建应用程序根
在此示例中,您以管理公用用户 c##system 的身份登录到 CDB 根。您可以创建一个名为 saas_sales_ac 的应用程序容器,然后打开与容器同名的应用程序根。
-- Create the application container called saas_sales_ac
CREATE PLUGGABLE DATABASE saas_sales_ac AS APPLICATION CONTAINER
ADMIN USER saas_sales_ac_adm IDENTIFIED BY manager;
-- Open the application root
ALTER PLUGGABLE DATABASE saas_sales_ac OPEN;
将当前容器设置为 saas_sales_ac,然后验证此容器是否为应用程序根:
-- Set the current container to saas_sales_ac
ALTER SESSION SET CONTAINER = saas_sales_ac;
COL NAME FORMAT a15
COL ROOT FORMAT a4
SELECT CON_ID, NAME, APPLICATION_ROOT AS ROOT,
APPLICATION_PDB AS PDB,
FROM V$CONTAINERS;
CON_ID NAME ROOT PDB
---------- --------------- ---- ---
3 SAAS_SALES_AC YES NO
对于应用程序容器,您可以在 SYS_CONTEXT 函数的 USERENV 名称空间中指定以下两个参数。
SYS_CONTEXT('USERENV', 'IS_APPLICATION_ROOT')
SYS_CONTEXT('USERENV', 'IS_APPLICATION_PDB')
应用程序根中 SYS_CONTEXT('USERENV', 'IS_APPLICATION_ROOT') 的值如下所示:
SQL> select sys_context('USERENV', 'IS_APPLICATION_ROOT') from dual;
SYS_CONTEXT('USERENV','IS_APPLICATION_ROOT')
--------------------------------------------------------------------------------
YES
请注意,SYS_CONTEXT('USERENV', 'IS_APPLICATION_ROOT') 的值与 V$PDBS 视图中的列 APPLICATION_ROOT 匹配。
SQL> select application_root from v$pdbs where con_id=sys_context('USERENV', 'CON_ID');
APP
---
YES
应用程序 PDB
应用程序 PDB 是位于应用程序容器中的 PDB。CDB 中的每个 PDB 都位于零个或一个应用程序容器中。
例如,saas_sales_ac 应用程序容器可能支持多个客户,每个客户应用程序将其数据存储在单独的 PDB 中。应用程序 PDB cust1_sales_pdb 和 cust2_sales_pdb 可能位于 saas_sales_ac 中,在这种情况下,它们不属于其他应用程序容器(尽管它们必然也属于 CDB 根的 PDB)。
连接到应用程序根时,通过执行 CREATE PLUGGABLE DATABASE 创建应用程序 PDB。可以从种子创建应用程序 PDB,也可以克隆 PDB 或插入断开的 PDB。与插入到 CDB 根的 PDB 类似,您可以克隆、断开或删除应用程序 PDB。但是,应用程序 PDB 必须始终属于应用程序根。
应用产品种子
应用程序种子是在应用程序容器内由用户创建的可选 PDB。应用程序容器具有零个或一个应用程序种子。
通过应用程序种子,可以快速创建应用程序 PDB。它在应用程序容器中发挥的作用与 PDB$SEED 在 CDB 本身中发挥的作用相同。
应用程序种子名称始终为 application_container_name$SEED,其中 application_container_name 是应用程序容器的名称。例如,使用 CREATE PDB ... AS SEED 语句在 saas_sales_ac 应用程序容器中创建 saas_sales_ac$SEED。
应用程序公用对象
应用程序公用对象是在应用程序根中的应用程序内创建的公用对象。公用对象是数据链接对象或元数据链接对象。
对于数据链接公用对象,应用程序 PDB 共享一组数据。例如,saas_sales_ac 应用程序容器的应用程序名为 saas_sales_app,具有版本 1.0,并包含数据链接 usa_zipcodes 表。在这种情况下,行在应用程序根的表中存储一次,但在所有应用程序 PDB 中都可见。
对于元数据链接公用对象,应用程序 PDB 仅共享元数据,但包含不同的数据集。例如,元数据链接 products 表在每个应用程序 PDB 中具有相同的定义,但行本身特定于 PDB。名为 cust1pdb 的应用程序 PDB 可能具有包含工作簿的 products 表,而名为 cust2pdb 的应用程序 PDB 可能具有包含自动部件的 products 表。
-
关于 CDB 中的公用性在 CDB 或应用程序根中定义的公用现象在插入到此根的所有容器中都是相同的。
-
创建应用程序公用对象要创建公用对象,请连接到应用程序根,然后执行指定共享属性的
CREATE语句。 -
元数据链接的应用程序公用对象 元数据链接是字典对象,它支持引用应用程序容器中所有 PDB 共享的公用元数据并授予对这些元数据的权限。
-
数据链接应用程序公用对象 数据链接对象是其元数据和数据位于应用程序根中的对象,可以从此应用程序容器中的所有应用程序 PDB 进行访问。
-
扩展数据链接应用程序对象 扩展数据链接对象是数据链接对象和元数据链接对象的混合体。另请参见:“公用和本地对象”以了解公用对象
关于 CDB 中的公用性
CDB 或应用程序根中定义的常见现象在插入到此根的所有容器中都是相同的。
-
公用性原则在 CDB 中,一种现象在系统容器(CDB 本身)或特定应用程序容器中可能是常见的。
-
CDB 中的名称空间在 CDB 中,每个对象的名称空间都限定在其容器中。
共同性原则
在 CDB 中,一种现象在系统容器(CDB 本身)或特定应用程序容器中可能是常见的。
例如,如果在连接到 CDB$ROOT 时创建公用用户帐户,则此用户帐户对 CDB 中的所有 PDB 和应用程序根是公用的。但是,如果在连接到应用程序根时创建应用程序公用用户帐户,则此用户帐户仅对该应用程序容器中的 PDB 公用。
在 CDB$ROOT 或应用程序根的上下文中,通用性原则如下:
-
在每个现有和未来的容器中,一种常见的现象是相同的。
因此,在 CDB 根中定义的公用用户在插入到 CDB 根的每个 PDB 中具有相同的身份;在应用程序根中定义的公用用户在插入到此应用程序根的每个应用程序 PDB 中具有相同的身份。相比之下,本地现象仅限于一个现有容器。
-
只有普通用户才能改变常见现象的存在。
更准确地说,只有登录到 CDB 根或应用程序根的公用用户才能创建、销毁或修改当前容器公用的用户、角色或对象的属性。
CDB 中的名称空间
在 CDB 中,每个对象的名称空间都限定在其容器中。
以下原则概括了范围规则:
-
从应用程序角度来看,PDB 是不同于任何其他 PDB 的单独数据库。
-
本地现象在单个容器内创建并限制在单个容器内。
注:在本主题中,“现象”一词是指“用户帐户、角色或数据库对象”。
-
常见现象在 CDB 根或应用程序根中定义,并存在于已插入或将插入到此根的所有 PDB 中。
上述原则对地方和共同现象有影响。
当地现象
本地现象必须唯一地命名为在容器内,但不能在 CDB 的所有容器中命名。不同容器中同名的局部现象是不同的。例如,一个 PDB 中的本地用户 sh 与另一个 PDB 中的本地用户 sh 不冲突。
CDB$ROOT 常见现象
CDB$ROOT 中定义的常见现象存在于多个容器中,并且必须在每个名称空间中唯一。例如,CDB 根包括预定义的公用用户,例如 SYSTEM 和 SYS。为了确保名称空间分离,Oracle AI Database 阻止在另一个容器中创建 SYSTEM 用户。
要确保名称空间分隔,CDB 根中由用户创建的公用现象的名称必须以 COMMON_USER_PREFIX 初始化参数指定的值开头。缺省前缀为 c## 或 C##。所有其他用户创建的现象的名称不得以 c## 或 C## 开头。例如,无法在名为 c##hr 的 hrpdb 中创建本地用户,也无法在名为 hr 的 CDB 根中创建公用用户。
应用程序常见现象
在应用程序容器中,本地和应用程序常见现象的名称不得冲突。
-
应用程序公用用户和角色
这些原则同样适用于应用程序公用用户,也适用于 CDB 公用用户。不同之处在于,对于 CDB 公用用户,公用用户前缀的默认值是
c##或C##,而在应用程序根中,公用用户前缀的默认值是空字符串。多租户体系结构假定您从应用程序根创建应用程序 PDB,或者将单租户应用程序转换为多租户应用程序。
-
应用程序公用对象
多租户体系结构假定您在应用程序根中创建应用程序公用对象。稍后,在应用程序 PDB 内本地添加数据。但是,Oracle AI Database 支持在应用程序 PDB 中创建本地表。在这种情况下,本地表与应用程序 PDB 中的应用程序公用对象位于相同的名称空间中。
另请参阅:Oracle AI Database Security Guide 以了解有关公用用户和角色的更多信息
创建应用程序公用对象
要创建公用对象,请连接到应用程序根,然后执行指定共享属性的 CREATE 语句。
您只能在应用程序安装、升级或修补过程中创建或更改应用程序公用对象。您可以通过以下方式指定共享:
-
DEFAULT_SHARING初始化参数该设置是在根中创建的受支持类型的所有数据库对象的默认共享属性。
-
SHARING子句可以在
CREATE语句本身中指定此子句。在 SQL 语句中包括SHARING子句时,它优先于DEFAULT_SHARING初始化参数中指定的值。可能的值为METADATA、DATA、EXTENDED DATA和NONE。
下表显示了应用程序公用对象的类型以及数据和元数据的存储位置。
表 1 应用程序公用对象
| 对象类型 | 共享值 | 元数据存储 | 数据存储 |
|---|---|---|---|
| 数据链接 | DATA |
应用程序的根 | 应用程序的根 |
| 扩展数据链接 | EXTENDED DATA |
应用程序的根 | 应用产品根和应用 PDB |
| 元数据链接 | METADATA |
应用程序的根 | 应用程序 PDB |
另请参阅:Oracle AI Database Security Guide 以了解如何管理公用对象的权限
元数据链接的应用程序公用对象
元数据链接是字典对象,支持引用应用程序容器中所有 PDB 共享的公用元数据并授予其权限。
在 SHARING 子句或 DEFAULT_SHARING 初始化参数中指定 METADATA 值可指定指向对象元数据的链接,称为元数据链接公用对象。对象的元数据在应用程序根中存储一次。
表、视图和代码对象(例如 PL/SQL 过程)可以共享元数据。在此上下文中,“元数据”包括列定义、约束条件、触发器和代码。例如,如果 sales_mlt 是元数据链接公用表,则所有应用程序 PDB 都会通过元数据链接访问此表的相同定义,该定义存储在应用程序根中。sales_mlt 中的行在每个应用程序 PDB 中有所不同,但列定义相同。
通常,应用程序中的大多数对象都将进行元数据链接。因此,只需维护一个主应用程序定义。此方法集中管理多个应用程序 PDB 中的应用程序。
示例 3-2 创建元数据链接的公用对象
在此示例中,SYSTEM 用户登录到 saas_sales_ac 应用程序容器。SYSTEM 在版本 1.0 中安装名为 saas_sales_app 的应用程序。此应用程序创建名为 saas_sales_adm 的公用用户帐户。方案包含一个名为 sales_mlt 的元数据链接公用表。
-- Begin the install of saas_sales_app
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app BEGIN INSTALL '1.0';
-- Create the tablespace for the app
CREATE TABLESPACE saas_sales_tbs DATAFILE SIZE 100M AUTOEXTEND ON NEXT 10M MAXSIZE 200M;
-- Create the user account saas_sales_adm, which will own the app
CREATE USER saas_sales_adm IDENTIFIED BY ****** CONTAINER=ALL;
-- Grant necessary privileges to this user account
GRANT CREATE SESSION, DBA TO saas_sales_adm;
-- Makes the tablespace that you just created the default for saas_sales_adm
ALTER USER saas_sales_adm DEFAULT TABLESPACE saas_sales_tbs;
-- Now connect as the application owner
CONNECT saas_sales_adm/******@saas_sales_ac
-- Create a metadata-linked table
CREATE TABLE saas_sales_adm.sales_mlt SHARING=METADATA
(YEAR NUMBER(4),
REGION VARCHAR2(10),
QUARTER VARCHAR2(4),
REVENUE NUMBER);
-- End the application installation
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app END INSTALL '1.0';
可以使用 ALTER PLUGGABLE DATABASE APPLICATION ... SYNC 语句同步应用程序 PDB,以使用相同的主应用程序定义。这样,每个应用程序 PDB 都有指向 saas_sales_adm.sales_mlt 公用表的元数据链接。在名为 cust1_pdb 的 PDB 中更新 sales_mlt 的中间层代码在 cust1_pdb 中向此表中添加行,而在 cust2_pdb 中更新 sales_mlt 的中间层代码在 cust2_pdb 中向此表的副本中添加行。仅共享存储在应用程序根中的表元数据。注:Oracle AI Database Security Guide,详细了解授予的对象权限的工作原理
- 元数据链接 对于元数据链接的应用程序公用对象,该对象的元数据将一次存储在应用程序根中。元数据链接是一个字典对象,其对象类型与其共享的元数据相同。
元数据链接
对于元数据链接的应用程序公用对象,对象的元数据将一次存储在应用程序根中。元数据链接是一个字典对象,其对象类型与其共享的元数据相同。
元数据链接的说明存储在创建该链接的 PDB 的数据字典中。元数据链接必须由应用程序公用用户拥有。只能使用元数据链接在 CDB 根或应用程序根中共享其创建者拥有的公用对象的元数据。
与数据链接不同,元数据链接仅依赖于公用数据。例如,如果应用程序在应用程序根中包含本地表 dow_close_lt 和 nasdaq_close_lt,则公用用户无法创建指向这些对象的元数据链接。但是,名为 sales_mlt 的应用程序公用表可以进行元数据链接。
例如,如果特权公用用户更改了 sales_mlt 的元数据,则会将列添加到表中,则此更改将传播到元数据链接。应用程序 PDB 用户不能更改元数据链接中的元数据。例如,管理名为 cust1_pdb 的应用程序 PDB 的 DBA 不能仅向此 PDB 中的 sales_mlt 添加列:此类元数据更改只能在应用程序根中进行。
数据链接的应用程序公用对象
数据链接对象是其元数据和数据位于应用程序根中的对象,可以从此应用程序容器中的所有应用程序 PDB 进行访问。
在 SHARING 子句或 DEFAULT_SHARING 初始化参数中指定 DATA 值可指定指向公用对象的链接,称为数据链接公用对象。数据仓库中的维表通常是数据链接公用表的理想候选项。
数据链接是一个功能与同义词非常相似的字典对象。例如,如果 countries 是应用程序公用表,则所有应用程序 PDB 均可通过数据链接访问此表的相同副本。如果向此表中添加了一行,则该行在所有应用程序 PDB 中都可见。
数据链接必须归应用程序公用用户所有。该链接从它所指向的对象继承对象类型。数据链接的说明存储在创建该链接的 PDB 的字典中。例如,如果应用程序容器包含 10 个应用程序 PDB,并且每个 PDB 都包含指向 countries 应用程序公用表的链接,则所有 10 个 PDB 都包含此链接的字典定义。
示例 3-3 创建数据链接的对象
在此示例中,SYSTEM 连接到 saas_sales_ac 应用程序容器。SYSTEM 将名为 saas_sales_app 的应用程序从版本 1.0 升级到 2.0。此应用程序升级以公用用户 saas_sales_adm 的身份登录容器,创建名为 countries_dlt 的数据链接表,然后向其中插入行。
-- Begin an upgrade of the application
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app BEGIN UPGRADE '1.0' to '2.0';
-- Connect as application owner to application root
CONNECT saas_sales_adm/manager@saas_sales_ac
-- Create data-linked table named countries_dlt
CREATE TABLE countries_dlt SHARING=DATA
(country_id NUMBER,
country_name VARCHAR2(20));
-- Insert records into countries_dlt
INSERT INTO countries_dlt VALUES(1, 'USA');
INSERT INTO countries_dlt VALUES(44, 'UK');
INSERT INTO countries_dlt VALUES(86, 'China');
INSERT INTO countries_dlt VALUES(91, 'India');
-- End application upgrade
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app END UPGRADE TO '2.0';
使用 ALTER PLUGGABLE DATABASE APPLICATION ... SYNC 语句将应用程序 PDB 与应用程序根同步。这样,每个同步的应用程序 PDB 都有指向 saas_sales_adm.countries_dlt 数据链接表的数据链接。
扩展的数据链接应用程序对象
扩展数据链接对象是数据链接对象和元数据链接对象的混合。
在扩展数据链接对象中,存储在应用程序根中的数据对所有应用程序 PDB 公用,所有 PDB 都可以访问此数据。但是,在应用程序根中共享公用数据时,每个应用程序 PDB 都可以创建自己的特定于 PDB 的数据。因此,PDB 使用自己的数据补充公用数据。
例如,销售应用程序可能支持多个应用程序 PDB。所有应用程序 PDB 都需要美国的邮政编码。在这种情况下,您可以在应用程序根中创建 zipcodes_edt 扩展数据链接表。应用程序根存储美国的邮政编码,因此所有应用程序 PDB 都可以访问这些邮政编码。但是,一个应用程序 PDB 需要美国和加拿大的邮政编码。此应用程序 PDB 可以在应用程序 PDB 中的扩展数据链接对象(而不是应用程序根)中存储加拿大的邮政编码。
通过连接到应用程序根并在 CREATE 语句中指定 SHARING=EXTENDED DATA 关键字来创建扩展的数据链接对象。
示例 3-4 创建扩展数据对象
在此示例中,SYSTEM 连接到 saas_sales_ac 应用程序容器,然后将名为 saas_sales_app 的应用程序(在“示例 3-2 ”)从版本 2.0 升级到 3.0。此应用程序以公用用户 saas_sales_adm 的身份登录容器,创建名为 zipcodes_edt 的扩展数据链接表,然后向其中插入行。
-- Begin an upgrade of the app
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app BEGIN UPGRADE '2.0' to '3.0';
-- Connect as app owner to app root
CONNECT saas_sales_adm/manager@saas_sales_ac
-- Create a common-data table named zipcodes_edt
CREATE TABLE zipcodes_edt SHARING=EXTENDED DATA
(code VARCHAR2(5),
country_id NUMBER,
region VARCHAR2(10));
-- Load rows into zipcodes_edt
INSERT INTO zipcodes_edt VALUES ('08820','1','East');
INSERT INTO zipcodes_edt VALUES ('10005','1','East');
INSERT INTO zipcodes_edt VALUES ('44332','1','North');
INSERT INTO zipcodes_edt VALUES ('94065','1','West');
INSERT INTO zipcodes_edt VALUES ('73301','1','South');
COMMIT;
-- End app upgrade
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app END UPGRADE TO '3.0';
使用 ALTER PLUGGABLE DATABASE APPLICATION ... SYNC 语句将应用程序 PDB 与应用程序同步。这样,每个同步的应用程序 PDB 都有指向 saas_sales_adm.zipcodes_edt 数据链接表的数据链接。连接到这些 PDB 的应用程序可以查看在应用程序升级期间插入到 zipcodes_edt 中的邮政编码,但也可以将自己的邮政编码插入到此表中。
容器映射
容器映射可让连接到应用程序根的会话发出 SQL 语句,这些 SQL 语句根据 SQL 语句中使用的谓词值路由到相应 PDB。
映射表指定元数据链接公用表中的列,并使用分区将不同的应用程序 PDB 与不同的列值关联。通过这种方式,如果数据没有在表级别进行物理分区,则容器映射可在 PDB 级别对数据执行分区。
使用容器映射的关键组件包括:
-
元数据链接表
此表用于使用容器映射进行查询。例如,可以创建名为
countries_mlt的元数据链接表,该表在每个应用程序 PDB 中存储不同的数据。在amer_pdb中,countries_mlt.cname列存储北美国家/地区名称;在euro_pdb中,countries_mlt.cname列存储欧洲国家/地区名称;在asia_pdb中,countries_mlt.cname列存储亚洲国家/地区名称。 -
地图表
在应用程序根中,创建按列表、散列或范围分区的单列映射表。通过映射表,可以使用容器映射启用的分区策略来查询元数据链接表。映射对象表中的分区名称必须与应用程序容器中应用程序 PDB 的名称相匹配。
例如,名为
pdb_map_tbl的映射表可以按cname列上的列表进行分区。名为amer_pdb、euro_pdb和asia_pdb的分区对应于应用程序 PDB 的名称。每个分区中的值是国家(地区)的名称,例如PARTITION amer_pdb VALUES ('US','MEXICO','CANADA')。从 Oracle Database 18c 开始,要使用映射的
CONTAINERS()查询,映射表中的分区列不需要与元数据链接表中的列匹配。假设已为容器映射pdb_map_tbl启用表sh.sales,并且cname是映射表的分区列。尽管sh.sales不包含cname列,但映射表仍将以下查询路由到相应的 PDB:SELECT * FROM CONTAINERS(sh.sales) WHERE cname = 'US' ORDER BY time_id。 -
容器图
容器映射是指定映射表的数据库属性。要设置该属性,请连接到应用程序根并执行
ALTER PLUGGABLE DATABASE SET CONTAINER_MAP=map_table语句,其中map_table是映射表的名称。
示例 3-5 创建元数据链接的表、映射表和容器映射:第 1 部分
在此示例中,您以应用程序管理员身份登录到应用程序根。假设一个应用程序容器有三个应用程序 PDB:amer_pdb、euro_pdb 和 asia_pdb。每个应用程序 PDB 存储不同区域的国家/地区名称。名为 oe.countries_mlt 的元数据链接表具有存储国家/地区名称的 cname 列。对于此分区策略,可以使用按列表划分的分区来创建名为 salesadm.pdb_map_tbl 的映射对象,该映射对象为每个区域创建一个分区。国家/地区名称确定区域。
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app BEGIN INSTALL '1.0';
-- Create the metadata-linked table.
CREATE TABLE oe.countries_mlt SHARING=METADATA (
region VARCHAR2(30),
cname VARCHAR2(30));
-- Create the partitioned map table, which is list partitioned on the
-- cname column. The names of the partitions are the names of the
-- application PDBs.
CREATE TABLE salesadm.pdb_map_tbl (cname VARCHAR2(30) NOT NULL)
PARTITION BY LIST (cname) (
PARTITION amer_pdb VALUES ('US','MEXICO','CANADA'),
PARTITION euro_pdb VALUES ('UK','FRANCE','GERMANY'),
PARTITION asia_pdb VALUES ('INDIA','CHINA','JAPAN'));
-- Set the CONTAINER_MAP database property to the map object.
ALTER PLUGGABLE DATABASE SET CONTAINER_MAP='salesadm.pdb_map_tbl';
-- Enable the container map for the metadata-linked table to be queried.
ALTER TABLE oe.countries_mlt ENABLE CONTAINER_MAP;
-- Ensure that the table to be queried is enabled for the
-- CONTAINERS clause.
ALTER TABLE oe.countries_mlt ENABLE CONTAINERS_DEFAULT;
-- End the application installation.
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app END INSTALL '1.0';
注:虽然使用分区语法创建容器映射,但数据库不使用分区功能。定义容器映射不需要 Oracle Partitioning。
在前面的脚本中,ALTER TABLE oe.countries_mlt ENABLE CONTAINERS_DEFAULT 语句指定在应用程序根中发出的查询和 DML 语句默认情况下必须对数据库对象使用 CONTAINERS() 子句。
示例 3-6 同步应用程序和添加数据:第 2 部分
此示例从上一个示例继续。连接到应用程序根时,依次将当前容器切换到每个 PDB、同步 saas_sales_app 应用程序,然后将特定于 PDB 的数据添加到 oe.countries_mlt 表。
ALTER SESSION SET CONTAINER=amer_pdb;
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app SYNC;
INSERT INTO oe.countries_mlt VALUES ('AMER','US');
INSERT INTO oe.countries_mlt VALUES ('AMER','MEXICO');
INSERT INTO oe.countries_mlt VALUES ('AMER','CANADA');
COMMIT;
ALTER SESSION SET CONTAINER=euro_pdb;
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app SYNC;
INSERT INTO oe.countries_mlt VALUES ('EURO','UK');
INSERT INTO oe.countries_mlt VALUES ('EURO','FRANCE');
INSERT INTO oe.countries_mlt VALUES ('EURO','GERMANY');
COMMIT;
ALTER SESSION SET CONTAINER=asia_pdb;
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app SYNC;
INSERT INTO oe.countries_mlt VALUES ('ASIA','INDIA');
INSERT INTO oe.countries_mlt VALUES ('ASIA','CHINA');
INSERT INTO oe.countries_mlt VALUES ('ASIA','JAPAN');
COMMIT;
示例 3-7 查询元数据链接表:第 3 部分
此示例从上一个示例继续。连接到应用程序根,然后多次查询 oe.countries_mlt,在 WHERE 子句中指定不同的国家/地区。该查询从 oe.countries_mlt.region 列返回正确的值。
ALTER SESSION SET CONTAINER=saas_sales_ac;
SELECT region FROM oe.countries_mlt WHERE cname='MEXICO';
REGION
------
AMER
SELECT region FROM oe.countries_mlt WHERE cname='GERMANY';
REGION
------
EURO
SELECT region FROM oe.countries_mlt WHERE cname='JAPAN';
REGION
------
ASIA
跨容器操作
跨容器操作是一次影响多个容器的 DDL 或 DML 语句。
只有连接到 CDB 根或应用程序根的公用用户才能执行跨容器操作。跨容器操作可能会影响:
-
CDB 本身
-
CDB 中的多个容器
-
在多个容器中表示的多个现象,例如公用用户或公用角色
-
当前未连接发出 DDL 或 DML 语句的用户的容器
跨容器 DDL 操作的示例包括:将公用权限授予其他公用用户的用户 SYSTEM,以及应用于整个 CDB 的 ALTER DATABASE . . . RECOVER 语句。
连接到 CDB 根或应用程序根时,可以执行单个 DML 语句来修改容器内多个 PDB 中的表或视图。数据库根据 DML 语句中指定的 CON_ID 列的值推断目标 PDB。如果未指定 CON_ID,则数据库使用 ALTER PLUGGABLE DATABASE CONTAINERS DEFAULT TARGET 语句指定的 CONTAINERS_DEFAULT_TARGET 属性。
示例 3-8 更新单个 DML 语句中的多个 PDB
在此示例中,您的目标是将 country_name 列设置为 sh.sales 表中的值 USA。此表存在于两个单独的 PDB 中,容器 ID 为 7 和 8。这两个 PDB 都位于名为 saas_sales_ac 的应用程序容器中。您可以以管理员身份连接到应用程序根,然后按如下方式进行更新:
CONNECT sales_admin@saas_sales_ac
Password: *******
UPDATE CONTAINERS(sh.sales) sal
SET sal.country_name = 'USA'
WHERE sal.CON_ID IN (7,8);
在前面的 UPDATE 语句中,sal 是 CONTAINERS(sh.sales) 的别名。
另请参见:“通用用户账户”