postgresql - search_path 如何影响标识符解析和 "current schema"

标签 postgresql schema database-table search-path

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

我看过一些关于在 Postgres 中使用“搜索路径”的细节,但我认为它只在检索数据时有效,而不是在创建数据时有效。

我有一堆 SQL 脚本,可以创建很多表。我不想修改脚本,而是希望默认情况下在特定模式中设置数据库创建表 - 当它们具有不合格的名称时。

这可能吗?

最佳答案

模式搜索路径search_path是什么?

The manual:

[...] tables are often referred to by unqualified names, which consist of just the table name. The system determines which table is meant by following a search path, which is a list of schemas to look in.

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

“当前模式”(或“默认模式”)是,per documentation:

The first schema named in the search path is called the current schema. Aside from being the first schema searched, it is also the schema in which new tables will be created if the CREATE TABLE command does not specify a schema name.

大胆强调我的。系统架构 pg_temp(当前 session 的临时对象架构)和 pg_catalog 自动成为搜索的一部分路径并按此顺序首先搜索。 The manual:

pg_catalog is always effectively part of the search path. If it is not named explicitly in the path then it is implicitly searched before searching the path's schemas. This ensures that built-in names will always be findable. However, you can explicitly place pg_catalog at the end of your search path if you prefer to have user-defined names override built-in names.

按照原文大胆强调。 pg_temp 出现在它之前,除非它被放在不同的位置。

如何设置?

有多种方法可以设置运行时变量search_path .

  1. postgresql.conf 中的所有数据库中的所有角色设置一个集群范围内的默认值(并重新加载)。小心!

     search_path = 'blarg,public'
    

    factory default for this setting是:

     search_path = "$user",public
    

    Note:

    The first element specifies that a schema with the same name as the current user is to be searched. If no such schema exists, the entry is ignored.

    和:

    If one of the list items is the special name $user, then the schema having the name returned by CURRENT_USER is substituted, if there is such a schema and the user has USAGE permission for it. (If not, $user is ignored.)

  2. 将其设置为一个数据库的默认值:

     ALTER DATABASE test SET search_path = blarg,public;
    
  3. 将其设置为您连接的角色的默认值(在整个集群范围内有效):

     ALTER ROLE foo SET search_path = blarg,public;
    
  4. 或者甚至(通常是最好的!)作为数据库中角色的默认值:

     ALTER ROLE foo IN DATABASE test SET search_path = blarg,public;
    
  5. 将命令写在脚本的顶部。或者在您的数据库 session 中执行它:

     SET search_path = blarg,public;
    
  6. 函数范围设置特定的search_path(以防止具有足够权限的恶意用户)。了解 Writing SECURITY DEFINER Functions Safely在手册中。

    CREATE FUNCTION foo()
      RETURNS void
      LANGUAGE plpgsql SECURITY DEFINER SET search_path=blarg,public,pg_temp
      AS
    $func$
    BEGIN
       -- do stuff
    END
    $func$;

Higher number in the list trumps lower number.
The manual has even more ways, like setting environment variables or using command-line options.

To see the current setting:

SHOW search_path;

收件人reset它:

RESET search_path;

The manual:

The default value is defined as the value that the parameter would have had, if no SET had ever been issued for it in the current session.

关于postgresql - search_path 如何影响标识符解析和 "current schema",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9067335/

相关文章:

sql - 将列从 varchar 更新为 jsonb

mysql - 尝试使用 MySQL Workbench 将 PostgreSQL 数据库迁移到 MySQL 数据库时遇到字符问题

sql - 从列表中选择具有特定字符串值结尾的表中的行

python - Django 测试错误 "Permission denied to create database"- 使用 Heroku Postgres

database - 许多 fk 表的一个表列?

sql - 在 SQL Server Management Studio 中编辑表后保存更改

schema - 如何从 icCube 中的 Builder Schema 文件自动生成立方体和维度设计?

database - 如何更改 postgresql 数据库上公共(public)模式的默认所有者?

简单类型字符串的 XML 模式不区分大小写枚举

php - 应该用什么表结构来维护登录注销日志?