tangguo

search_path如何影响标识符解析和“当前模式”

java

是否可以定义默认情况下在哪个架构中创建新表?(由“不合格的表名”引用。)

我已经在Postgres中看到了有关使用“搜索路径”的一些详细信息,但是我认为它仅在检索数据而不是创建时才起作用。

我有一堆SQL脚本,它们创建许多表。我不想修改脚本,而是希望在默认模式下将数据库创建表设置为特定的模式-当它们具有非限定名称时。

这可能吗?


阅读 353

收藏
2020-10-26

共2个答案

小编典典

搜索路径的确是您想要的:

% create schema blarg; % set search_path to blarg; % create table foo (id int); % \d List of relations Schema | Name | Type | Owner --------+------+-------+------- blarg | foo | table | pgsql

2020-10-26
小编典典

模式搜索路径是search_path什么?
手册:

经常用不合格的名称来引用表,这些名称仅由表名称组成。系统通过遵循搜索路径(查找的模式列表)来确定要使用哪个表。

大胆强调我的。这解释了标识符解析。

根据文档,“当前模式”(或“默认模式”)为:

在搜索路径中命名的第一个模式称为当前模式。除了作为第一个搜索的架构之外,如果CREATE TABLE命令未指定架构名称,它也是将在其中创建新表的架构。

大胆强调我的。系统模式pg_temp(当前会话的临时对象的模式)pg_catalog自动成为搜索路径的一部分,并按此顺序首先搜索。手册:

pg_catalog始终是搜索路径的有效部分。如果未在路径中明确命名,则在 搜索路径的架构之前将对其进行隐式搜索。这样可以确保始终可以找到内置名称。但是,pg_catalog如果您希望用户定义的名称覆盖内置名称,则可以将其显式放置在搜索路径的末尾。

按照原著大胆强调。并且pg_temp在此之前,除非将其置于其他位置。

如何设置?
有多种方法可以设置运行时变量search_path。

  1. 为所有数据库中的所有角色设置一个群集范围的默认值postgresql.conf(并重新加载)。小心点!
search_path = 'blarg,public'

此设置的出厂默认值为:

search_path = "$user",public

第一个元素指定要搜索与当前用户同名的架构。如果不存在这样的架构,则该条目将被忽略。

  1. 将其设置为一个数据库的默认值:
ALTER DATABASE test SET search_path = blarg,public;
  1. 将其设置为与您连接的角色的默认角色(在整个群集范围内有效):
ALTER ROLE foo SET search_path = blarg,public;
  1. 甚至默认(通常是最好!)作为数据库中角色的默认值:
ALTER ROLE foo IN DATABASE test SET search_path = blarg,public;
  1. 在脚本顶部编写命令。或在您的数据库会话中执行它:
SET search_path = blarg,public;
  1. search_path为功能范围设置特定的名称(以防止受到具有足够特权的恶意用户的侵害)。在手册中阅读有关安全编写SECURITY DEFINER函数的信息。
CREATE FUNCTION foo() RETURNS void AS
$func$
BEGIN
   -- do stuff
END
$func$ LANGUAGE plpgsql SECURITY DEFINER
       SET search_path=blarg,public,pg_temp;

我列表中较高的数字胜过较低的数字。
该手册还有更多方法,例如设置环境变量或使用命令行选项。

要查看当前设置:

SHOW search_path;

要重置它:

RESET search_path;

手册:

默认值定义为该参数本应具有的值,如果SET在当前会话中未为其发出任何值。

2020-10-26