标签: postgresql

应用规则后如何查看查询?

来自文档- 37.3.1.1。“循序渐进的第一条规则”

CREATE TABLE shoelace_log (
    sl_name    text,          -- shoelace changed
    sl_avail   integer,       -- new available value
    log_who    text,          -- who did it
    log_when   timestamp      -- when
);

CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data
    WHERE NEW.sl_avail <> OLD.sl_avail
    DO INSERT INTO shoelace_log VALUES (
                                    NEW.sl_name,
                                    NEW.sl_avail,
                                    current_user,
                                    current_timestamp
                                );
Run Code Online (Sandbox Code Playgroud)

现在有人这样做:

(1) UPDATE shoelace_data SET sl_avail = 6 WHERE sl_name = 'sl7';
Run Code Online (Sandbox Code Playgroud)

解析器生成这个额外的查询

(2) INSERT INTO shoelace_log VALUES (
       shoelace_data.sl_name, 6,
       current_user, current_timestamp )
  FROM shoelace_data
 WHERE …
Run Code Online (Sandbox Code Playgroud)

postgresql

9
推荐指数
1
解决办法
124
查看次数

从 generate_series() 填写记录集中缺少的日期

考虑:

with days as (select day::date
from generate_series(date '2013-01-01', date '2013-01-01' + 365, interval '1 day' day) day
) 
select 'Inspections'::text as data_label,
count(i.reporting_id) as daily_count, d.day as date_column
from days d
left join inspection i on i.close_case_date = d.day
group by d.day
order by d.day
Run Code Online (Sandbox Code Playgroud)

这将返回一个如下所示的集合:

data_label | daily_count | date_column
Inspections    1           01/01/13
Inspections    2           01/02/13
Inspections    4           01/04/13
Inspections    8           01/06/13
Run Code Online (Sandbox Code Playgroud)

请注意记录集中的 1 天和 2 天间隔。我需要生成一个用 0 填充的值的集合,如下所示:

data_label | daily_count | date_column
Inspections    1           01/01/13
Inspections …
Run Code Online (Sandbox Code Playgroud)

postgresql aggregate postgresql-9.1 set-returning-functions

9
推荐指数
1
解决办法
1万
查看次数

未使用但影响查询的索引

我有一个 PostgreSQL 9.3 表,其中包含一些数字和一些附加数据:

CREATE TABLE mytable (
    myid BIGINT,
    somedata BYTEA
)
Run Code Online (Sandbox Code Playgroud)

该表目前有大约 10M 条记录,占用 1GB 磁盘空间。myid不连续。

我想计算 100000 个连续数字的每个块中有多少行:

SELECT myid/100000 AS block, count(*) AS total FROM mytable GROUP BY myid/100000;
Run Code Online (Sandbox Code Playgroud)

这将返回大约 3500 行。

我注意到某个索引的存在显着加快了这个查询,即使查询计划根本没有提到它。没有索引的查询计划:

db=> EXPLAIN (ANALYZE TRUE, VERBOSE TRUE) SELECT myid/100000 AS block, count(*) AS total FROM mytable GROUP BY myid/100000;
                                                               QUERY PLAN                                                               
----------------------------------------------------------------------------------------------------------------------------------------
 GroupAggregate  (cost=1636639.92..1709958.65 rows=496942 width=8) (actual time=6783.763..8888.841 rows=3460 loops=1)
   Output: ((myid / 100000)), count(*)
   ->  Sort  (cost=1636639.92..1659008.91 rows=8947594 width=8) (actual time=6783.752..8005.831 …
Run Code Online (Sandbox Code Playgroud)

postgresql index execution-plan count index-tuning

9
推荐指数
2
解决办法
1014
查看次数

互斥的多对多关系

我有一个containers可以与多个表建立多对多关系的表,假设它们是plantsanimalsbacteria。每个容器可以包含任意数量的植物、动物或细菌,并且每个植物、动物或细菌可以在任意数量的容器中。

到目前为止,这非常简单,但我遇到的问题是每个容器应该只包含相同类型的元素。例如,同时包含植物和动物的混合容器应该是数据库中的约束违规。

我的原始架构如下:

containers
----------
id
...
...


containers_plants
-----------------
container_id
plant_id


containers_animals
------------------
container_id
animal_id


containers_bacteria
-------------------
container_id
bacterium_id
Run Code Online (Sandbox Code Playgroud)

但是对于这个模式,我无法想出如何实现容器应该是同构的约束。

有没有办法通过参照完整性来实现这一点,并在数据库级别确保容器是同类的?

我为此使用 Postgres 9.6。

postgresql database-design constraint many-to-many

9
推荐指数
2
解决办法
1891
查看次数

psql:致命数据库不存在错误

我有一个 linux 用户帐户、postgresql 角色和关联的数据库,都称为 foo。

从 linux 用户 foo,我运行了命令

dropdb foo
Run Code Online (Sandbox Code Playgroud)

现在,当我尝试从 linux 用户 foo 运行 psql 时,出现错误...

psql: FATAL:  database "foo" does not exist
Run Code Online (Sandbox Code Playgroud)

那么这是否意味着从 linux 用户帐户运行 psql 时,必须有一个与该 linux 用户帐户相关联的数据库?

postgresql

9
推荐指数
1
解决办法
5万
查看次数

如何在 Postgres 中的 CASE 表达式上创建索引

我正在尝试在 CASE 表达式上创建索引,如下所示

CREATE TABLE test(i INT, j INT);

CREATE UNIQUE INDEX test_index ON test(CASE WHEN i=1 THEN j END);
Run Code Online (Sandbox Code Playgroud)

收到此错误:

ERROR:  syntax error at or near "CASE"
LINE 1: CREATE UNIQUE INDEX test_index ON test(CASE WHEN i=1 THEN j ...
                                               ^

********** Error **********

ERROR: syntax error at or near "CASE"
SQL state: 42601
Character: 40
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

Postgres 9.5.2

postgresql postgresql-9.5

9
推荐指数
1
解决办法
4718
查看次数

PostgreSQL 自定义操作符 UUID 到 varchar

我有一个相当复杂的 Postgres 数据库,其中许多 UUID 字段被错误地存储为 VARCHAR。我想逐步迁移它们,但不幸的是,这样做打破了我的所有观点,因为 Postgres 没有内置的varchar = uuid. 而是重写我的所有视图或尝试一次大规模迁移,我想临时创建一个 uuid = varchar 运算符,直到迁移完成。

我以前从未创建过自定义运算符,并且我在下面的尝试不起作用:

CREATE OR REPLACE FUNCTION uuid_equal_varchar (varchar, uuid)
RETURNS boolean AS 'SELECT $1::text = $2::text;' LANGUAGE sql IMMUTABLE;

CREATE OPERATOR = (
    leftarg = character varying,
    rightarg = uuid,
    procedure = uuid_equal_varchar,
    commutator = =
);
Run Code Online (Sandbox Code Playgroud)

然而,这个运营商打破了一切。包括一个简单的 varchar = varchar 比较(见下文):

SELECT * FROM test WHERE pk_test = '123';
ERROR:  invalid input syntax for uuid: "123"
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释我做错了什么吗?我是否试图尝试不可能的事情?

postgresql datatypes cast operator uuid

9
推荐指数
1
解决办法
3万
查看次数

PostgreSQL 9.2 - 9.6 零停机升级

我必须从 PostgreSQL 9.2 升级到 9.6。以下是我面临的挑战:

  1. 由于我们有流式复制设置,并且PostgreSQL在流式复制模式下不支持从低到高的版本升级,当我升级主时,我必须重建从属,这需要3个小时。我没有那个时间可以闲下来。在任何给定的时间,我们都需要一个从站和一个主站可用。有没有其他方法可以升级而不必重建从属设备,使用流式复制?

  2. 为了构建逻辑复制,我们考虑使用 slony 但 slony 有一些限制,因为它不会自动复制:

    • 对大对象 (BLOBS) 的更改
    • DDL 命令所做的更改
    • 对用户和角色的更改
      ……我们的应用程序具有连续的创建命令。所以我们不能使用 slony。

请提出一些建议,以避免从属重建,并以最少的停机时间进行升级,并准备好一主一从。

postgresql upgrade

9
推荐指数
1
解决办法
3343
查看次数

为什么 RDS PostgreSQL 总是在重启时恢复?

我正在运行 PostgreSQL 9.6.3 的 RDS 实例:select version();返回PostgreSQL 9.6.3 on x86_64-pc-linux-gnu [...]

我发现在从 RDS 控制台发出停止命令并启动后,数据库总是报告数据库系统没有正确关闭,需要恢复。此行为已由至少一位其他 RDS PostgreSQL 用户 ( https://forums.aws.amazon.com/message.jspa?messageID=809401#809401 )独立验证。

查询

select name, setting
from pg_settings
where name in ('fsync', 'wal_sync_method', 'synchronous_commit');
Run Code Online (Sandbox Code Playgroud)

报告说fsync = onwal_sync_method = fdatasync(适用于 Linux 系统),和synchronous_commit = on

发出停止命令后,我在日志中看到以下内容:

2017-10-12 16:37:36 UTC::@:[3464]:LOG: received fast shutdown request
2017-10-12 16:37:36 UTC::@:[3464]:LOG: aborting any active transactions
2017-10-12 16:37:36 UTC::@:[3515]:LOG: autovacuum launcher shutting down
2017-10-12 16:37:36 UTC::@:[3512]:LOG: shutting down
2017-10-12 16:37:36 …
Run Code Online (Sandbox Code Playgroud)

postgresql aws postgresql-9.6 amazon-rds

9
推荐指数
1
解决办法
1283
查看次数

如何将 ORDER BY 和 LIMIT 与聚合函数结合使用?

我的问题的小提琴可以在https://dbfiddle.uk/?rdbms=postgres_10&fiddle=3cd9335fa07565960c1837aa65143685上找到。

我有一个简单的表格布局:

class
person: belongs to a class
Run Code Online (Sandbox Code Playgroud)

我想选择所有班级,对于每个班级,我想要按降序排列的所属人员的前两个人员标识符。

我通过以下查询解决了这个问题:

select     c.identifier, array_agg(p.identifier order by p.name desc) as persons
from       class as c
left join lateral (
             select   p.identifier, p.name
             from     person as p
             where    p.class_identifier = c.identifier
             order by p.name desc
             limit    2
           ) as p
on         true
group by   c.identifier
order by   c.identifier
Run Code Online (Sandbox Code Playgroud)

注意:我可以在SELECT子句中使用相关子查询,但作为学习过程的一部分,我试图避免这种情况。

如您所见,我order by p.name desc在两个地方申请:

  • 在子查询中
  • 在聚合函数中

有没有办法避免这种情况?我的坚持:

  • 首先,显然我不能删除order by子查询中的 ,因为这会给出一个不符合我上述要求的查询。

  • 其次,我认为order by聚合函数中的 不能被遗漏,因为子查询的行顺序不一定保留在聚合函数中?

我应该重写查询吗?

postgresql aggregate order-by subquery

9
推荐指数
1
解决办法
5936
查看次数