如果只有一个数据库用户或者几个用户合作共享数据库,使用单个架构即可。但在许多情况下,需要使用更多架构来让用户及其应用程序能在单独的命名空间中创建和访问表。例如,使用更多架构将允许:
-
许多用户在不相互干扰的情况下访问数据库。
对各个架构进行配置,以便授予特定用户对该架构及其表的访问权限,同时限制其他用户。
-
使用第三方应用程序来创建在不同架构中名称相同的表,从而防止表冲突。
与其他 RDBMS 不同,Vertica 数据库中的架构不是绑定到一个用户的对象集合。
如果只有一个数据库用户或者几个用户合作共享数据库,使用单个架构即可。但在许多情况下,需要使用更多架构来让用户及其应用程序能在单独的命名空间中创建和访问表。例如,使用更多架构将允许:
许多用户在不相互干扰的情况下访问数据库。
对各个架构进行配置,以便授予特定用户对该架构及其表的访问权限,同时限制其他用户。
使用第三方应用程序来创建在不同架构中名称相同的表,从而防止表冲突。
与其他 RDBMS 不同,Vertica 数据库中的架构不是绑定到一个用户的对象集合。
本部分提供有关何时以及如何使用多个架构分离数据库用户的示例。这些示例分为两类:使用多个专用架构;组合使用专用架构(即仅限单个用户的架构)和共享架构(即跨多个用户共享的架构)。
使用多个专用架构可以在涉及敏感信息时有效地将数据库用户彼此分离。通常,用户仅被授予一个架构及其内容的访问权限,从而提供架构级别的数据库安全性。数据库用户可以同时运行不同的应用程序、同一应用程序的多个副本,甚至同一应用程序的多个实例。这样一来,您便可以合并一个数据库上的应用程序,从而减少管理开销,同时更有效地利用资源。以下示例突出强调使用多个专用架构。
使用多个架构分离用户及其唯一的应用程序
在本示例中,两位数据库用户都为同一家公司工作。一位用户 (HRUser) 使用人力资源 (HR) 应用程序访问敏感的个人资料(如工资),而另一位用户 (MedUser) 通过医疗保健管理应用程序访问与公司医疗保健成本有关的信息。HRUser 不应能够访问公司医疗保健成本信息,而 MedUser 不应能够查看员工个人资料。
为了允许这些用户访问他们需要的数据,同时限制他们查看不应看到的数据,我们创建了两个具有适当用户访问权限的架构,如下所示:
HRSchema — 此架构归 HRUser 所有,且通过 HR 应用程序进行访问。
HRSchema — 此架构归 MedUser 所有,且通过医疗保健管理应用程序进行访问。
使用多个架构支持多租户
本示例与最后一个示例相类似,它也是通过将用户分离到不同的架构中,限制对敏感数据的访问。但在这种情况下,每位用户都使用同一应用程序的一个虚拟实例。
一个相关示例是零售市场分析公司,该公司向大型零售商提供数据和“软件即服务”(SaaS),帮助他们确定使用哪些促销方法能够最有效地推动客户销售额。
在本示例中,每位数据库用户相当于一位零售商,且每位用户只能访问自己的架构。零售市场分析公司需向每位零售客户提供同一应用程序的一个虚拟实例,且每个实例指向该用户的特定架构,以便在其中创建和更新表。这些架构中的表是由同一应用程序的实例创建的,所以使用相同名称,但由于它们处于单独的架构中,因此不会发生冲突。
此数据库中的架构示例可以是:
MartSchema — 归一家大型连锁百货商店 MartUser 所有的架构。
PharmSchema — 归一家大型连锁药店 PharmUser 所有的架构。
使用多个架构迁移至应用程序的新版本
使用多个架构是迁移至新软件应用程序版本的一种有效方法。在这种情况下,需创建一个新架构来支持软件的新版本,原有架构将保留到不再需要为止,以支持软件的原始版本。这称为“滚动应用程序升级”。
例如,公司可能使用 HR 应用程序存储员工资料。以下架构可用于软件的原始版本和更新版本:
HRSchema — 此架构归原始 HR 应用程序的架构用户 HRUser 所有。
V2HRSchema — 此架构归新版 HR 应用程序的架构用户 V2HRUser 所有。
在上述示例显示的情况中,数据库中的所有架构都是专用的,且用户之间不共享信息。但是,用户可能希望共享公共信息。例如,在零售案例中,MartUser 和 PharmUser 可能希望将其每个商店的特定产品销售额与整个行业内每个商店销售额的平均值相比较。由于此信息是行业平均值,不是特定于任何零售连锁店,因此可以将其放置在两位用户都被授予 USAGE 权限的架构中。
此数据库中的架构示例可能是:
MartSchema — 归一家大型连锁百货商店 MartUser 所有的架构。
PharmSchema — 归一家大型连锁药店 PharmUser 所有的架构。
IndustrySchema — 此架构归 DBUser(来自零售市场分析公司)所有,而 MartUser 和 PharmUser 对此架构具有 USAGE 权限。零售商不太可能获得除 USAGE(对于此架构)和 SELECT(对于其中的一个或多个表)以外的任何权限。
您可以根据需要为数据库创建任意数量的架构。例如,您可以为每个数据库用户创建一个架构。但是,架构与用户并不像在 Oracle 中一样是同义词。
默认情况下,只有超级用户可以创建架构或者授予某个用户创建架构的权限。(请参阅《SQL 参考手册》中的GRANT(数据库)。)
要创建架构,请使用 CREATE SCHEMA 语句,如《SQL 参考手册》中所述。
创建两个或多个架构后,每个 SQL 语句或函数必须识别与所引用的对象相关联的架构。您可以通过以下方式在多个架构中指定一个对象:
通过使用以点分隔的架构名称和对象名称来限定对象名称。例如,若要指定位于 Schema1
中的 MyTable
,请将名称限定为 Schema1.MyTable
。
如果引用的某个对象未加以限定,可使用包括所需架构的搜索路径。通过 设置搜索路径,Vertica 将自动搜索指定架构来查找对象。
每个用户会话都有一个架构搜索路径。Vertica 使用此搜索路径来查找未按架构名称限定的表和用户定义函数 (UDF)。会话搜索路径最初是从用户的配置文件中设置的。您可以随时通过调用
SET SEARCH_PATH
来更改会话的搜索路径。此搜索路径一直有效,直到处理下一个 SET SEARCH_PATH
语句或会话结束为止。
SHOW SEARCH_PATH
返回会话的当前搜索路径。例如:
=> SHOW SEARCH_PATH;
name | setting
-------------+---------------------------------------------------
search_path | "$user", public, v_catalog, v_monitor, v_internal
架构按优先级降序排列。第一个架构在搜索顺序中具有最高优先级。如果此架构存在,它也会定义为当前架构,供以非限定名称创建的表使用。您可以通过调用函数
CURRENT_SCHEMA
来识别当前架构:
=> SELECT CURRENT_SCHEMA;
current_schema
----------------
public
(1 row)
会话搜索路径最初是从用户的配置文件中设置的。如果用户配置文件中的搜索路径不是通过
CREATE USER
或
ALTER USER
设置,则该搜索路径将设置为数据库默认值:
=> CREATE USER agent007;
CREATE USER
=> \c - agent007
You are now connected as user "agent007".
=> SHOW SEARCH_PATH;
name | setting
-------------+---------------------------------------------------
search_path | "$user", public, v_catalog, v_monitor, v_internal
$user
解析为会话用户名(在此示例中为 agent007
)且具有最高优先级。如果架构 agent007
存在,Vertica 将开始在该架构中搜索不合格的表。此外,
CURRENT_SCHEMA
的调用将返回此架构。否则,Vertica 使用 public
作为当前架构并开始在其中进行搜索。
使用
ALTER USER
可修改现有用户的搜索路径。这些更改会覆盖搜索路径中的所有非系统架构,其中包括 $USER
。系统架构保持不变。对用户搜索路径的更改仅在用户启动新会话时生效;当前会话不受影响。
例如,以下语句将修改 agent007
的搜索路径,并授予对新搜索路径上的架构和表的访问权限:
=> ALTER USER agent007 SEARCH_PATH store, public;
ALTER USER
=> GRANT ALL ON SCHEMA store, public TO agent007;
GRANT PRIVILEGE
=> GRANT SELECT ON ALL TABLES IN SCHEMA store, public TO agent007;
GRANT PRIVILEGE
=> \c - agent007
You are now connected as user "agent007".
=> SHOW SEARCH_PATH;
name | setting
-------------+-------------------------------------------------
search_path | store, public, v_catalog, v_monitor, v_internal
(1 row)
要验证用户的搜索路径,请查询系统表
USERS
:
=> SELECT search_path FROM USERS WHERE user_name='agent007';
search_path
-------------------------------------------------
store, public, v_catalog, v_monitor, v_internal
(1 row)
要将用户的搜索路径恢复为数据库默认设置,请调用 ALTER USER
并将搜索路径设置为 DEFAULT
。例如:
=> ALTER USER agent007 SEARCH_PATH DEFAULT;
ALTER USER
=> SELECT search_path FROM USERS WHERE user_name='agent007';
search_path
---------------------------------------------------
"$user", public, v_catalog, v_monitor, v_internal
(1 row)
Vertica 仅在当前用户具有访问权限的现有架构中进行搜索。如果搜索路径中的架构不存在或用户缺乏对其的访问权限,Vertica 会默认将其排除搜索。例如,如果 agent007
缺乏架构 public
的 SELECT 权限,Vertica 会默认为跳过此架构。仅当 Vertica 在搜索路径的任何位置都找不到表时,它才会返回错误。
Vertica 最初会根据用户的配置文件来设置会话的搜索路径。您可以使用
SET SEARCH_PATH
更改当前会话的搜索路径。您可以通过两种方式使用 SET SEARCH_PATH
:
显式将会话搜索路径设置为一个或多个架构。例如:
=> \c - agent007
You are now connected as user "agent007".
dbadmin=> SHOW SEARCH_PATH;
name | setting
-------------+---------------------------------------------------
search_path | "$user", public, v_catalog, v_monitor, v_internal
(1 row)
=> SET SEARCH_PATH TO store, public;
SET
=> SHOW SEARCH_PATH;
name | setting
-------------+-------------------------------------------------
search_path | store, public, v_catalog, v_monitor, v_internal
(1 row)
将会话搜索路径设置为数据库默认值:
=> SET SEARCH_PATH TO DEFAULT;
SET
=> SHOW SEARCH_PATH;
name | setting
-------------+---------------------------------------------------
search_path | "$user", public, v_catalog, v_monitor, v_internal
(1 row)
SET SEARCH_PATH
覆盖搜索路径中的所有非系统架构,其中包括 $USER
。系统架构保持不变。
Vertica 支持跨多个架构引用表的 视图。例如,用户可能需要将员工薪资与行业平均值进行比较。在这种情况下,应用程序将查询两个架构:
平均薪资的共享架构 IndustrySchema
特定于公司的工资信息的专用架构 HRSchema
最佳实践: 在创建跨越多个架构的对象时,请使用限定的表名。如果架构内的查询路径或表结构在未来的某个日期发生变化,此命名约定可避免发生混淆。