标签: postgresql

PostgreSQL 如何向 regexp_split_to_table() 创建的行添加序数?

我有两张桌子。表logfile在一个属性中包含整个文本文件;表的rawtext每一行应包含文本文件中的一行文本:

create table LOGFILE ( LOGF_PK serial primary key, TEXT_CONTENT text ) ;
create table LOGTEXT ( LT_PK serial primary key, 
  LOGF_PK integer not null references LOGFILE( LOGF_PK ),
  LINENUM  integer,
  LINETEXT varchar(255)
);
Run Code Online (Sandbox Code Playgroud)

我可以将 TEXT_CONTENT 拆分为一组行,但我无法(不知道如何)在表 LOGTEXT 中生成行号,例如 LOGFILE.TEXT_CONTENT 中的第一行将位于一行 <LT_PK>、<LOGF_PK> 中, 1、‘第一行文字’等

此查询返回我期望获得的内容,但没有行号:

select LOGF_PK, regexp_split_to_table( TEXT_CONTENT, '\r?\n' ) as LINETEXT ;
Run Code Online (Sandbox Code Playgroud)

但是,我无法获得任何行号。我尝试了变体1:

select LOGF_PK
  , row_number() over (partition by LOGFILE.LOGF_PK) as LINENUM
  , regexp_split_to_table( TEXT_CONTENT, '\r?\n' )) as LINETEXT
from LOGFILE
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,LINENUM 始终为 …

postgresql

2
推荐指数
1
解决办法
2030
查看次数

删除 postgres 表中的旧数据但保留已删除数据的副本的最佳实践

目前,我们的数据库服务器中有一个大约有 20 列(其中一列是 timestamptz 数据类型)的表,该表有 8.34 亿行。就大小而言,这是一个很大的表(大约 250GB(包括索引等)。

我想找到最有效和最好的方法来删除超过 2 年的旧数据,但如果我们需要它用于报告目的,也可以定期保留这些数据,该表也有 FK 约束。

处理这个问题的最佳方法是什么?我们希望能够在需要时查看这些数据。可能位于也可能不在同一服务器上。

最好首先运行选择数据的 COPY

COPY (SELECT * FROM TABLENAME WHERE CAST((timecreated_on AT TIME ZONE 'GMT') AS date) > DATE '2020-01-01 00:00:01') TO '/path/to/a/dump/file';
Run Code Online (Sandbox Code Playgroud)

那么删除表中的数据呢?

DELETE FROM TABLENAME where CAST((timecreated_on AT TIME ZONE 'GMT') AS date) > DATE '2020-01-01 00:00:01'
Run Code Online (Sandbox Code Playgroud)

我只是在寻找一种方法,这是一个自动化的过程,我可以通过 Linux 服务器上的 cronjob 安排每年之后删除超过 1 年的数据。

知道这可能不是最好的方法,但需要查看如何管理 FK 键约束,我是否会删除它们并重新应用,这可能会导致数据完整性问题?

任何帮助深表感谢。

postgresql delete archive

2
推荐指数
1
解决办法
2838
查看次数

PostgreSQL 11.9 无法重新启动服务器,错误 -- pg_ctl: 目录“/var/lib/postgresql/11/main”不是数据库集群目录

我们一直在努力重启停电后关闭的数据库集群服务器。我们尝试过 systemctl 、 pg_ctl 和 pg_ctlcluster 命令,但我们总是遇到同样的错误。

目录“/var/lib/postgresql/11/main”不是数据库集群目录

在我们的配置文件(postgresql.conf)中提到了相同的路径:

data_directory = '/var/lib/postgresql/11/main'

我无法理解为什么我们会收到此错误,即使服务器在断电之前以相同的配置运行。

这是我们的生产服务器。

我输入这些命令的命令行是:

  • pg_ctl : /usr/lib/postgresql/11/bin/pg_ctl 启动 -D /var/lib/postgresql/11/main
  • pg_ctlcluster : /usr/bin/pg_ctlcluster --skip-systemctl-redirect 11-main start (这与 postgresql@.service 的 ExecStart 参数下提到的命令相同)
  • systemctl : systemctl 状态 postgresql@11-main.service

postgresql postgresql-11

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

Postgres 是否可以保护硬盘免受重复写入相同存储单元的影响?

如果我每天向同一个表的同一列中的同一行写入 4 个字节(整数)100,000 次,这会磨损 SSD 吗?对于 SSD 来说,每天 400 kb 不算什么,但将其写入同一个存储单元就会弹出它。

  • Postgres 数据库管理系统是否在幕后以某种方式处理这些单元?
  • 或者现代 SSD 芯片在硬件中做到了这一点吗?
  • 还是所有数据都写入同一个存储单元,随着时间的推移,我们只是交换失效的 SSD?

postgresql disk-space

2
推荐指数
1
解决办法
620
查看次数

Postgresql pg_toast 表,它们是强制性的吗?

我在 PostgreSQL v13 中有一个小模式,只有模式结构,但仍然没有数据。

我所看到的是,我得到了一些pg_toast普通表的表,尽管里面没有数据。我有一个包含 5 列的简单表,其中一些是 varchar=200 长度和 inte=19 长度。

pg_toast当我没有向表中插入任何数据时,为什么我会得到这些表。pg_toast我可以看到表pg_class与列的关系reltoastrelid

这些表有 0 KB 数据,根据:

pg_relation_size(reltoastrelid) AS toast_size
Run Code Online (Sandbox Code Playgroud)

唯一拥有pg_toast数据的是:pg_rewritepg_statistic

postgresql

2
推荐指数
1
解决办法
3077
查看次数

无需超级用户权限即可导出 Postgres 数据

我在 CentOS 7 上使用 Postgres 14。我想导出单个表的数据,但我没有超级用户权限。毫不奇怪,我收到此错误

myapp=> COPY myapp_currencyprice to '/tmp/prices.csv' DELIMITER ',' CSV HEADER;
ERROR:  must be superuser or a member of the pg_write_server_files role to COPY to a file
HINT:  Anyone can COPY to stdout or from stdin. psql's \copy command also works for anyone.
Run Code Online (Sandbox Code Playgroud)

对于没有超级用户权限的用户导出表数据(用于稍后导入)的正确方法是什么?

postgresql export table

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

从客户端角度升级 postgres 主要版本是否安全?

假设我创建了一个应用程序并将其连接到 Postgres 9,然后我决定升级到 Postgres 14,我的应用程序会崩溃吗(比如不再支持某些 SQL 查询/语句)

Postgres 作者是否有关于从客户端角度向后兼容的官方声明?我的应用程序是否可以在不更改任何未来 Postgres 版本的情况下继续工作?

postgresql

2
推荐指数
1
解决办法
1916
查看次数

如何在 PostgreSQL 13 中将 id 更新为行号

我的表article_favorites没有行号,现在它包含 100000 条记录。我想在表中添加一个 bigint id 列,并将 id 默认设置为行号。我尝试了这个sql:

update article_favorites  set id = row_number() OVER ()
Run Code Online (Sandbox Code Playgroud)

但它告诉我window functions are not allowed in UPDATE,我应该怎么做才能将 id 更新为行号?

postgresql

2
推荐指数
1
解决办法
5181
查看次数

PostgreSQL中的递归CTE生成不同频率的数据

我正在尝试编写一个在 Postgresql 14 中使用递归 CTE 的数据生成查询。

考虑包含函数 getfreq 的模式“sc”。getfreq 将 int 作为参数(代表另一个表的外键),并返回 int,代表频率。

现在考虑这个查询:

WITH RECURSIVE rec AS 
(
SELECT 1 as fk FROM generate_series(1, sc.getfreq(1), 1)
UNION ALL
SELECT r.fk + 1 FROM rec AS r WHERE r.fk + 1 <= 10
)
select row_number() OVER () as pk, fk from rec
Run Code Online (Sandbox Code Playgroud)

getfreq 期望一个从 1 到 10 的 int(因此 r.fk <= 10 退出条件)。它返回频率 N。我希望递归 CTE 的每次迭代都创建 N 行。每次迭代的结果将通过 UNION ALL 子句组合在一起。最后,我想要一个结果,其中行数等于 getfreq 在 10 次迭代中返回的频率之和。

在上面的示例中,sc.getfreq(1) 将始终返回 5,因此我得到 50 …

postgresql cte recursive

2
推荐指数
1
解决办法
619
查看次数

Postgres C 扩展中的环境变量

我无法在 PostgreSQL C 扩展代码中获取环境变量。

例如,此函数始终返回111

#include "postgres.h"
#include "fmgr.h"
#include <stdlib.h>

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(myinc);
Datum
myinc(PG_FUNCTION_ARGS)
{
  int32 arg = PG_GETARG_INT32(0);
  char* envar = getenv("MYINC");
  if (envar) {
    PG_RETURN_INT32(arg + atoi(envar));
  } else {
    PG_RETURN_INT32(111);
  }
}
Run Code Online (Sandbox Code Playgroud)

虽然此 C 程序按预期工作,但它会打印以下内容MYINC

#include <stdio.h>
#include <stdlib.h>

int main()
{
  printf("MYINC: %s", getenv("MYINC"));
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

postgresql environment-variables postgresql-extensions c

2
推荐指数
1
解决办法
463
查看次数