如何正确判断postgresql数据库是否为空

问题描述 投票:0回答:2

编辑: 在 stackoverflow 上第一次搜索时出现的答案对于 postgresql 来说是“潜在危险且错误的”。我被它咬住了,我删除了一个实际上充满了很多模式的数据库: 检查数据库是否为空(无表)的SQL仅适用于mysql。 Postgresql 具有“SET search_path TO .specified_name”功能。

通过这种方式,您可以在不同的“名称空间”中创建表,人们使用它来将多个“一个模式”放入一个物理 postgresql 数据库中。


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

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

database postgresql
2个回答
7
投票

在 Postgres 中,一个实例(安装)可以有多个数据库,每个数据库可以有多个模式。

Postgres 实例具有

至少

两个对其工作至关重要的数据库:template0

template1

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

案例 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=#

如果返回 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=#

这会计算非“默认”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;

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


0
投票

select count(s.nspname) from pg_class c join pg_namespace s on s.oid = c.relnamespace where s.nspname in ('public');

如果数据库中没有表,则返回 0。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.