标签: postgresql

如何在每次插入/更新中强制指定一列(不是默认为空)

下表:

CREATE TABLE kontrolle.negativtext
(
  id serial NOT NULL,
  ausschluss character varying(255) NOT NULL, 
  nur_domains character varying(255)[] NOT NULL DEFAULT '{}'::character varying[],
  nicht_domains character varying(255)[] NOT NULL DEFAULT '{}'::character varying[],
  bemerkung character varying(255), 
  last_change_user character varying(3) NOT NULL,
  last_change_timestamp timestamp without time zone,
  hits integer NOT NULL DEFAULT 0,
  is_regex boolean NOT NULL DEFAULT false, 
  check_doc negative_doc_check[] DEFAULT '{CONTENT_TXT_DIRTY, CONTENT_TXT_CLEAN}', 
  CONSTRAINT negativtext_pkey PRIMARY KEY (id)
);
Run Code Online (Sandbox Code Playgroud)

该表中数据记录的值应该可由多个用户更改。我想强制每个人更新或插入此表中的值以提供用户名(我们不需要讨论为什么这不是外键)。
将列设置为NOT NULL DEFAULT NULL将防止该值为空,这很好。但是,当用户abc插入一行并xyz稍后更新它时,xyz应该需要为 column …

postgresql update check-constraints

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

如何对键/值 JSONB 中的所有值求和(聚合)?

在 Postgres 10 中我有下表:

CREATE TABLE testtable (
    id  int   PRIMARY KEY,
    qty jsonb
);
INSERT INTO testtable (id,qty)
VALUES
  ( 1, '{"2018-08-01": 10, "2018-08-11": 20, "2018-10-23": 30}' ),
  ( 2, '{"2018-08-17": 100, "2018-11-01": 200}' ),
  ( 3, '{"2018-09-03": 1, "2018-09-01": 2, "2018-10-01": 3}' );
Run Code Online (Sandbox Code Playgroud)

有没有一种快速的方法,使用 SQL 返回每个 JSONB 字段的总和,以便结果为:

ID Total
1   60
2   300
3   6
Run Code Online (Sandbox Code Playgroud)

我已经看到使用 UNNEST 和/或替换(/sf/ask/1868972101/)更复杂的可能性。

然而,我希望有更优雅的东西。

postgresql json postgresql-10

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

Postgres、RDW、WHERE 条件未推送到远程(JSONB 属性,使用 postgres_rdw)

我有一个使用 RDW 的远程 postgres 表。它包含一个 JSONB 列,我使用该 JSONB 中的值作为条件WHERE

远程表在 JSONB 列上有一个 GIN 索引,在hostname我用于过滤的 -attribute 上有一个索引。

EXPLAIN ANALYZE VERBOSE
SELECT 
* 
FROM forein_table
WHERE details->>'hostname' = 'host-xyz'
Run Code Online (Sandbox Code Playgroud)

显示“远程 SQL”不包含-WHERE子句,并且过滤是在本地完成的。另一方面

EXPLAIN ANALYZE VERBOSE
SELECT 
* 
FROM forein_table
WHERE details@> '{"hostname": "host-xyz"}'
Run Code Online (Sandbox Code Playgroud)

发送“WHERE”子句,这显然要快得多。

文档说:

WHERE 子句不会发送到远程服务器,除非它们仅使用内置数据类型、运算符和函数。子句中的运算符和函数也必须是 IMMUTABLE。

->>和之间有区别吗@>

有没有办法在远程表上使用WHERE details->>'hostname' = 'host-xyz'并让它下推子句WHERE

(我找到了一种方法,通过创建将属性VIEW提取hostname为列,然后在此视图上创建远程表......但显然这不是一种非常灵活/优雅的方法)

postgresql postgresql-fdw

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

PostgreSQL - 我可以使用副本 WAL 的逻辑复制吗?

我想使用逻辑复制。然而,由于 PostgreSQL 现在的工作方式,它可以吃掉整个磁盘,然后阻塞数据库。特别是在 Amazon Web Services RDS 中,这是一个问题,因为 RDS 不会为您提供SUPERUSER角色,以便您可以连接和关闭插槽。

所以我设置了一个 RDS 副本并设置rds.logical_replication1. 但 RDS 副本似乎没有对此做出反应 -SHOW ALL虽然wal_level = hot_standby它应该如此logical

这就是我想要实现的目标:

RDS master
    WAL --> RDS replica
                logical replication ON
                WAL + wal2json  ---->    pg_recvlogical on remote client
Run Code Online (Sandbox Code Playgroud)

这可能吗?

参考:wal_level

当我尝试创建插槽时,我得到:

致命:没有来自主机“...”、用户“postgres”的复制连接的 pg_hba.conf 条目,SSL 关闭

这看起来 AWS 没有放置正确的条目pg_hba.conf- 即不允许 postgres 用户创建复制槽。

我的假设正确吗?有什么办法解决这个问题吗?

postgresql replication aws postgresql-9.5 amazon-rds

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

如何在 postgres 上同时通过连接对多个表运行更新查询?

在 MySQL 中,我可以执行这样的查询

UPDATE 
    prd_sectionshapename  se
inner join 
    prd_shape s
ON
    s.id = se.shape_id
SET
   se.company_shape_name = 'ABC',
   s.name_en = 'Another name'
WHERE s.serial_number = '1234ST';
Run Code Online (Sandbox Code Playgroud)

在 Postgres 中,我需要分成 2 个查询

UPDATE prd_shape AS s
SET name_en = 'Another name'
WHERE s.serial_number = '1234ST';


UPDATE prd_sectionshapename AS se
SET company_shape_name = 'ABC'
FROM prd_shape s
WHERE se.shape_id = s.id and s.serial_number = '1234ST';
Run Code Online (Sandbox Code Playgroud)

我的问题是可以像 MySQL 一样在 1 个查询中完成它吗?

请注意,我在互联网上找到的其他 postgres 更新联接答案通常表明,即使使用了联接,更新效果也仅发生在单个表上。

我的目的是在一个查询中更新多个表。不只是一张桌子。

postgresql join update

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

如何比较不同时区的时间戳?

例如,我有一个带有时间戳的表:

    2018-04-05 06:00:00 +01
    2018-04-05 06:00:00 +00
    2018-04-05 06:00:00 -01
    2018-04-05 04:00:00 -01
Run Code Online (Sandbox Code Playgroud)

我想要获得的条目是......

BETWEEN 2018-04-05 06:00:00+01 AND 2018-04-05 07:00:00+01
Run Code Online (Sandbox Code Playgroud)

所以我的输出是:

    2018-04-05 06:00:00 +01
    2018-04-05 04:00:00 -01
Run Code Online (Sandbox Code Playgroud)

操作员会BETWEEN自动处理时区差异并为我提供所需的输出吗?

postgresql timestamp timezone

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

动态定义一个RETURN表(列类型,名称)用于后续循环

我想对ST_Intersection(clipper_geom, clipped_geom)来自表的行数执行。

https://postgis.net/docs/ST_Intersection.html

https://postgis.net/docs/ST_Intersects.html

POSTGIS 交集本身不支持处理多个几何图形,这与ST_Intersects()我必须设计一个函数(返回一个表)来选择与我的clipper_geomusing相交的行ST_Intersects()、循环遍历结果集并计算与 的每个交集有关ST_Intersection()。字段geomclipped_geom_wkt是记录剪裁几何体的字段。

该功能有效,但我需要为每个要生成剪辑的表使用不同的功能。我想动态读取输入表(列名称和类型)并在RETURN语句中定义两者。

所有字段名称和类型都相同,只是geom更新和clipped_geom_wkt添加。

我尝试搜索 Stack Overflow,找到了有关如何创建动态表结构的示例,但没有一个LOOP对第一个结果执行后续操作,其中列名必须匹配才能插入/更新新数据。

这是我到目前为止所提出的,但我不确定如何执行该LOOP部分、添加clipped_geom_wkt字段和更新geom字段。一些回复建议RETURNS TABLE (...)如果添加更多字段SETOF...

/sf/ask/1247503771/

但似乎动态生成的列仅支持RETURNS SETOF ...

/sf/ask/821817951/#11751557

/sf/ask/602362211/#8611675

CREATE OR REPLACE FUNCTION clip_palin_polygon_complete(clipped_table text,clipper_geom text, age_sequence VARCHAR)
RETURNS TABLE (rec clipped_table, clipped_geom_wkt text)) AS $$ --not sure if this is the right way to …
Run Code Online (Sandbox Code Playgroud)

postgresql dynamic-sql plpgsql postgis

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

PostgreSQL autovacuum 忽略“非活动”表导致“事务 ID 环绕”

我有一个包含大量表(当前为 93k)的 PostgreSQL 数据库,并且我看到事务 ID 年龄威胁环绕的问题,因为对于长时间未写入的干净表,不会触发 autovacuum。

例如,我有一个表,我可以看出自“2018-09-19 10:30:43.625069+00”以来还没有被写入,这要归功于对该表的唯一插入总是设置一列updated_at(当前日期时间是“2018”) -10-04 23:58:25.545881+00'),有n_dead_tup = 0,并且有age(relfrozenxid) > 10000000

我有autovacuum_freeze_max_age = 10000000所以这应该意味着这个表将被自动清理,但相反我看到它超过了这一点,然后表的自动清理不会被触发(它目前处于age(relfrozenxid) > 70000000并且自动清理仍然没有触发。

我目前已将自动真空设置为最大程度地激进,但这种情况仍在发生。以下是自动清理设置:

track_counts = on
autovacuum = on
autovacuum_vacuum_cost_delay = 0
autovacuum_vacuum_cost_limit = 10000
autovacuum_vacuum_scale_factor = 0
autovacuum_vacuum_threshold = 1
autovacuum_freeze_max_age = 10000000
vacuum_freeze_min_age = 1000000
Run Code Online (Sandbox Code Playgroud)

(是的,我意识到autovacuum_vacuum_cost_limit这并不重要,autovacuum_vacuum_cost_delay因为0

目前,我被迫定期手动触发这些表的真空,以防止事情失控。不过,这感觉就像是黑客攻击。

有没有办法让 autovacuum 来清理这些表,或者相当于 autovacuum 忽略这些表的原因?

预计到达时间

如果有人来这里想看我处理这个问题的脚本,这里是:

#!/bin/bash -e
while true; do
  sleep 60 #just in case …
Run Code Online (Sandbox Code Playgroud)

postgresql autovacuum postgresql-10

5
推荐指数
0
解决办法
338
查看次数

为什么对带有 GIN 索引的表进行全文搜索仍然很慢

根据我迄今为止收集到的信息,如果您需要对 PostgreSQL(psql 9.6.2,服务器 9.6.5)数据库中包含大量条目(例如 1.2M+ 的订单)的表运行全文搜索),推荐的方法是为该表创建一个索引(在本例中我们创建了一个 GIN 索引),它应该允许您运行如下查询:

SELECT * FROM speech WHERE speech_tsv @@ plainto_tsquery('a text string')
Run Code Online (Sandbox Code Playgroud)

除了此查询的结果有时不包含任何相关搜索字符串之外,它通常需要 8 到 10 秒。

该数据库部署在一个相当大的多核 EC2 实例上,所以我在想,我们是否可以对数据库做其他事情来帮助这些查询运行得更快?

或者考虑到我们要求它搜索的大量文件和文本(即使通过索引),这个查询执行时间大约是合理的?

该表如下所示:

                                         Table "public.speech"
        Column     |            Type             |                      Modifiers                      
    ---------------+-----------------------------+-----------------------------------------------------
     speech_id     | integer                     | not null default nextval('speech_id_seq'::regclass)
     speechtype_id | smallint                    | not null
     title         | character varying           | not null default ''::character varying
     speechdate    | date                        | default now()
     location      | character varying           | not null default ''::character varying
     source        | character varying …
Run Code Online (Sandbox Code Playgroud)

postgresql index full-text-search

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

在冲突时更新具有相同值的目标列对性能的影响

这是一个关于 Postgres (v10) 的内部工作原理和性能的问题。

给定一个表 ,在和列github_repos上具有多列唯一索引,下面的两个批量更新插入操作之间是否存在任何性能差异(或其他需要注意的问题)?不同之处在于,在第一个查询中,和列包含在 UPDATE 中,而在第二个查询中则不包含。由于 UPDATE 在冲突时运行,因此和的更新值将与旧值相同,但这些列包含在 UPDATE 中,因为我正在使用的底层库就是这样设计的。我想知道按原样使用是否安全,或者我是否应该在更新中明确排除这些列。org_idgithub_idorg_idgithub_idorg_idgithub_id

查询#1:

INSERT INTO "github_repos" ("org_id","github_id","name")
VALUES (1,1,'foo')
ON CONFLICT (org_id, github_id)
DO UPDATE SET "org_id"=EXCLUDED."org_id","github_id"=EXCLUDED."github_id","name"=EXCLUDED."name"
RETURNING "id"
Run Code Online (Sandbox Code Playgroud)

查询#2:

INSERT INTO "github_repos" ("org_id","github_id","name")
VALUES (1,1,'foo')
ON CONFLICT (org_id, github_id)
DO UPDATE SET "name"=EXCLUDED."name"
RETURNING "id"
Run Code Online (Sandbox Code Playgroud)

github_repos桌子:

      Column       |       Type        | Collation | Nullable 
-------------------+-------------------+-----------+----------+
 id                | bigint            |           | not null |
 org_id            | bigint            |           | not null | …
Run Code Online (Sandbox Code Playgroud)

postgresql performance postgresql-performance

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