如何确定Postgresql数据库是否为空的正确方法

Man*_*gor 3 database postgresql

编辑:在stackoverflow的第一次搜索中出现的答案对于postgresql 可能危险的和错误的。我被它咬了,删除了一个实际上充满了很多模式的数据库SQL检查数据库是否为空(无表)仅适用于mysql。

Postgresql具有“将search_path设置为.specified_name”的功能。
这样,您可以在不同的“名称空间”中创建表,人们可以使用这些表将多个“一个模式”放入一个物理的PostgreSQL数据库中。

旧答案中的查询将检查默认名称空间。如果为空,则假定数据库为空。但是在其他搜索路径中可以有20个其他数据库方案。购买“一个数据库”的用户经常使用该工具,但是为了避免额外费用,在不同的搜索路径中运行10个应用程序。

所以我再次提出问题。在postgresql中检查数据库是否为空的正确方法是什么?更具体地说,如何检查它是否是一个由createdb创建的“原始”数据库,而没有访问物理机的权限?

a_h*_*ame 5

正如其他人所评论的那样,链接的答案是关于MySQL的,“数据库”和“模式”之间没有区别。

但是,在Postgres中,一个实例(安装)可以有多个数据库,并且每个数据库可以有多个架构。

Postgres实例至少具有两个对它正常工作至关重要的数据库:template0template1

如果您要检查是否没有(非默认)数据库,或者是否要检查特定数据库是否不包含表,则不清楚您的问题。

情况1-检查是否不存在数据库

为此,您需要连接到template1数据库(因为那是您知道的唯一数据库。然后可以运行以下语句:

$ psql -X -U postgres template1
psql (9.6.2)
Type "help" for help.

template1=# select count(*) from pg_database where datname not like 'template%';
 count
-------
    33
(1 row)

template1=#
Run Code Online (Sandbox Code Playgroud)

如果返回0,则说明您的系统中没有其他数据库。通常,至少有一个名为的数据库postgres-这是默认安装的工作。但是该数据库不必一定存在。

情况2-检查特定数据库是否不包含表

如果要检查特定数据库是否不包含表,则需要连接到该数据库并检查表-不包括所有系统表。最简单的方法是查询pg_class,因为其中基本上包含可以在数据库中创建的所有内容(存储函数除外)。

$ psql -U postgres your_database 
psql (9.6.2)
Type "help" for help.

postgres=# select count(*)
postgres-# from pg_class c
postgres-#   join pg_namespace s on s.oid = c.relnamespace
postgres-# where s.nspname not in ('pg_catalog', 'information_schema')
postgres-#   and s.nspname not like 'pg_temp%'
postgres-# ;
 count
-------
   464
(1 row)

postgres=#
Run Code Online (Sandbox Code Playgroud)

这将计算不是“默认” Postgres表的表的数量。

上面的查询将具有许多模式但其中没有表的数据库也视为空。是否表示“空”取决于您的要求。

您可能还需要检查pg_proc以确保不存在任何存储的功能,并且可能pg_extension pg_foreign_server还有其他一些系统目录表


无关:

Postgres具有的功能SET search_path TO specified_name。这样,您可以在不同的“名称空间”中创建表

您无需更改搜索路径即可创建具有不同模式的表:

-- create two schemas
create schema one;
create schema two;

-- create a table in schema one
create table one.some_table;
-- create a table in schema two
create table two.other_table;
Run Code Online (Sandbox Code Playgroud)

仅存在search_path,因此您不必始终完全限定表的名称。