教学文章
Technology Exchange
400电话

免费咨询热线
400-090-9964

教学文章

PostgreSQL教程-数据定义-模式搜索路径

时间:2021-10-22 来源:

5.9.3. 模式搜索路径

限定名写起来很冗长,通常最好不要把一个特定模式名拉到应用中。因此,表名通常被使用非限定名来引用,它只由表名构成。系统将沿着一条搜索路径来决定该名称指的是哪个表,搜索路径是一个进行查看的模式列表。 搜索路径中第一个匹配的表将被认为是所需要的。如果在搜索路径中没有任何匹配,即使在数据库的其他模式中存在匹配的表名也将会报告一个错误。

在不同方案中创建命名相同的对象的能力使得编写每次都准确引用相同对象的查询变得复杂。这也使得用户有可能更改其他用户查询的行为,不管是出于恶意还是无意。由于未经限定的名称在查询中以及在PostgreSQL内部的广泛使用,在search_path中增加一个方案实际上是信任所有在该方案中具有CREATE特权的用户。在你运行一个普通查询时,恶意用户可以在你的搜索路径中的以方案中创建能够夺取控制权并且执行任意SQL函数的对象,而这些事情就像是你在执行一样。

搜索路径中的第一个模式被称为当前模式。除了是第一个被搜索的模式外,如果CREATE TABLE命令没有指定模式名,它将是新创建表所在的模式。

要显示当前搜索路径,使用下面的命令:

SHOW search_path;

在默认设置下这将返回:

search_path

-?-?-?-?-?-?-?

"$user", public

第一个元素说明一个和当前用户同名的模式会被搜索。如果不存在这个模式,该项将被忽略。第二个元素指向我们已经见过的公共模式。

搜索路径中的第一个模式是创建新对象的默认存储位置。这就是默认情况下对象会被创建在公共模式中的原因。当对象在任何其他没有模式限定的环境中被引用(表修改、数据修改或查询命令)时,搜索路径将被遍历直到一个匹配对象被找到。因此,在默认配置中,任何非限定访问将只能指向公共模式。

要把新模式放在搜索路径中,我们可以使用:

SET search_path TO myschema,public;

(我们在这里省略了$user,因为我们并不立即需要它)。然后我们可以删除该表而无需使用方案进行限定:

DROP TABLE mytable;

同样,由于myschema是路径中的第一个元素,新对象会被默认创建在其中。

我们也可以这样写:

SET search_path TO myschema;

这样我们在没有显式限定时再也不必去访问公共模式了。公共模式没有什么特别之处,它只是默认存在而已,它也可以被删除。

其他操作模式搜索路径的方法请见第 9.25 节。

搜索路径对于数据类型名称、函数名称和操作符名称的作用与表名一样。数据类型和函数名称可以使用和表名完全相同的限定方式。如果我们需要在一个表达式中写一个限定的操作符名称,我们必须写成一种特殊的形式:

OPERATOR(schema.operator)

这是为了避免句法歧义。例如:

SELECT 3 OPERATOR(pg_catalog.+) 4;

实际上我们通常都会依赖于搜索路径来查找操作符,因此没有必要去写如此“丑陋”的东西。