10

为什么在 PostgreSQL 中,当不同模式中存在同名表时,\dt只包含搜索路径中列出的第一个模式中的表,如下例所示?

我感兴趣的是:

  1. 这将是可取的原因,以及

  2. 给定底层查询\dt(见下文),它是如何实际实现的。

(顺便说一句,我从这个答案中意识到,\dt *.*它将列出每个模式中的每个表——但对于下面的示例,除了我做的两个之外,这给了我 58 个我不想要的系统表!)


例子

dt_test=# CREATE SCHEMA first;
CREATE SCHEMA
dt_test=# CREATE SCHEMA second;
CREATE SCHEMA
dt_test=# CREATE TABLE first.my_table(id integer);
CREATE TABLE
dt_test=# CREATE TABLE second.my_table(id integer);
CREATE TABLE
dt_test=# set search_path to first,second;
SET
dt_test=# \dt
         List of relations
 Schema |   Name   | Type  | Owner  
--------+----------+-------+--------
 first  | my_table | table | postgres
(1 row)

dt_test=# set search_path to second,first;
SET
dt_test=# \dt
         List of relations
 Schema |   Name   | Type  | Owner  
--------+----------+-------+--------
 second | my_table | table | postgres
(1 row)

查询底层\dt(当 psql 使用 -E 命令启动时显示,例如 psql -E dt_test)

********* QUERY **********
SELECT n.nspname as "Schema",
  c.relname as "Name",
  CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'm' THEN 'materialized view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 's' THEN 'special' WHEN 'f' THEN 'foreign table' END as "Type",
  pg_catalog.pg_get_userbyid(c.relowner) as "Owner"
FROM pg_catalog.pg_class c
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('r','')
      AND n.nspname <> 'pg_catalog'
      AND n.nspname <> 'information_schema'
      AND n.nspname !~ '^pg_toast'
  AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 1,2;
**************************
4

3 回答 3

5

这是手册中的引述:http ://www.postgresql.org/docs/current/static/functions-info.html

表 9-61显示了确定某个对象在当前模式搜索路径中是否可见的函数。例如,如果一个表的包含模式在搜索路径中,并且在搜索路径的前面没有出现同名表,则称该表是可见的。

关键部分:没有同名表出现在搜索路径的前面

对于set search_path to first,second;second.my_table不可见,因为它被阻止first.my_table

于 2014-10-14T08:53:03.503 回答
1

要在所有模式中仅列出您想要的表:

\dt *.my_table
         List of relations
 Schema |   Name   | Type  | Owner 
--------+----------+-------+-------
 first  | my_table | table | cpn
 public | my_table | table | cpn
 second | my_table | table | cpn
于 2014-10-14T09:35:45.747 回答
0

列出所有带前缀的用户表

\dt *.<table_prefix>*

例子:

 \dt *.my*
于 2021-07-16T15:27:41.197 回答