小编Erw*_*ter的帖子

在 9.1 下仍然推荐常规的 VACUUM ANALYZE 吗?

我在 Ubuntu 上使用 PostgreSQL 9.1。VACUUM ANALYZE仍然推荐预定,还是 autovacuum 足以满足所有需求?

如果答案是“视情况而定”,那么:

  • 我有一个较大的数据库(30 GiB 压缩转储大小,200 GiB 数据目录)
  • 我对数据库做 ETL,每周导入接近 300 万行
  • 变化最频繁的表全部继承自一个主表,主表中没有数据(数据按周分区)
  • 我创建每小时汇总,并从那里创建每日、每周和每月报告

我问是因为预定的时间VACUUM ANALYZE会影响我的报告。它运行了 5 个多小时,本周我不得不杀死它两次,因为它影响了常规的数据库导入。check_postgres不会报告数据库有任何显着膨胀,所以这不是真正的问题。

从文档中,autovacuum 也应该处理事务 ID 环绕。问题是:我还需要一个VACUUM ANALYZE吗?

postgresql etl vacuum

38
推荐指数
3
解决办法
4万
查看次数

Postgres 函数中的 SQL 注入与准备好的查询

在 Postgres 中,准备好的查询和用户定义的函数是否等同于一种防止 SQL 注入机制
一种方法比另一种方法有什么特别的优势吗?

postgresql sql-injection prepared-statement plpgsql functions

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

需要外键索引

我正在为索引、主键和外键苦苦挣扎……并且需要拥有所有这些。

如果我有两个表,它们都有一个整数作为主键。
第一个表通过 FK 引用第二个表的主键。

  • 在两个表上,我在 ID 列上都有一个主键索引
  • 我在table1.ref_field引用第二个表 ( table2.id)的 PK上创建了 FK 约束
  • 我在上面添加了一个索引 table1.ref_field

这是组织这些索引、主键和外键的最佳方式吗?

postgresql index foreign-key database-design primary-key

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

Postgres 函数将查询结果分配给多个变量

我需要在 Postgres 函数中为 2 个变量赋值,如下所示。

a := select col1 from tbl where ...
b := select col2 from tbl where ...
Run Code Online (Sandbox Code Playgroud)

如何在一行命令中为 2 个变量分配 2 个值?

喜欢

a,b := select col1,col2 from tbl where ...
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql functions

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

LC_CTYPE 对 PostgreSQL 数据库有什么影响?

所以,我有几个带有 PostgreSQL 的 Debian 服务器。从历史上看,这些服务器和 PostgreSQL 使用拉丁文 9 字符集进行了本地化,当时还可以。现在我们必须处理波兰语、希腊语或中文等问题,因此改变它成为一个日益严重的问题。

当我尝试创建 UTF8 数据库时,收到消息:

错误:编码 UTF8 与语言环境 fr_FR 不匹配 详细信息:所选的 LC_CTYPE 设置需要编码 LATIN9。

有几次我和我的老朋友 Google 对这个主题进行了一些研究,我能找到的只是一些过于复杂的过程,比如更新 Debian LANG、使用正确的字符集重新编译 PostgreSQL、编辑所有LC_系统变量和其他晦涩的解决方案。所以暂时,我们把这个问题放在一边。

最近,它又回来了,希腊人想要这些东西,而拉丁语 9 不想。当我再次研究这个问题时,一位同事冲我说:“不,这很容易,你看。”

他什么也没编辑,也没有做魔术,他只是做这个 SQL 查询:

CREATE DATABASE my_utf8_db
  WITH ENCODING='UTF8'
       OWNER=admin
       TEMPLATE=template0
       LC_COLLATE='C'
       LC_CTYPE='C'
       CONNECTION LIMIT=-1
       TABLESPACE=pg_default;
Run Code Online (Sandbox Code Playgroud)

它工作得很好。

我实际上并不知道,LC_CTYPE='C'而且我很惊讶在 Google 甚至 Stack Overflow 上的第一个解决方案中都没有使用它。我环顾四周,只在 PostgreSQL 文档中找到了一个提及。

当 LC_CTYPE 为 C 或 POSIX 时,允许使用任何字符集,但对于 LC_CTYPE 的其他设置,只有一种字符集可以正常工作。由于 LC_CTYPE 设置被 initdb 冻结,因此在集群的不同数据库中使用不同编码的明显灵活性比实际更具理论性,除非您选择 C ​​或 POSIX 语言环境(从而禁用任何真正的语言环境感知)。

所以这让我想知道,这太容易了,太完美了,有什么缺点?而且我还很难找到答案。所以我来这里发帖:

tl; dr:使用 …

postgresql collation

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

Postgres 多列到 json

我正在运行 postgresql 9.3.4。我有一个包含 3 个字段的表:

id   name  addr
---  ----  ----
1    n1    ad1
2    n2    ad2
...
Run Code Online (Sandbox Code Playgroud)

我需要将数据移动到包含以下字段的新表:

id   data
---  ----
1    {'name': 'n1', 'addr': 'ad1'}
2    {'name': 'n2', 'addr': 'ad2'}
...
Run Code Online (Sandbox Code Playgroud)

row_to_json对我来说不是解决方案,因为它也SELECT t.id, row_to_json(t) as data FROM (select id, name, addr from myt) t增加id了结果。有没有办法在我的数据字段中选择我需要的字段(名称和地址)?

postgresql row json

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

在另一个 SELECT 的 WHERE 子句中使用 SELECT

我在 libpq 之上为PostrgreSQL制作了一个远程应用程序草案。它表现良好,但我已经描述了应用程序的一般功能。对于我产生的每个最终业务结果,我碰巧调用了类似 40 select 子句(通过 tcpip)的东西。

我有 SQL-Server 的回忆,提醒我尽量减少远程应用程序和数据库之间的交互次数。分析了我的选择后,我确实认为我可以SELECT使用连接将这个数字减少到 3 个子句。但我不记得SELECT在 another 中使用 a 的结果的语法SELECT

例如:

SELECT * FROM individual
INNER JOIN publisher
ON individual.individual_id = publisher.individual_id
WHERE individual.individual_id = 'here I would like to use the results of a another select'
Run Code Online (Sandbox Code Playgroud)

另一个SELECT就是这样的:

SELECT identifier FROM another_table WHERE something='something'
Run Code Online (Sandbox Code Playgroud)

这是简化的表布局,针对不同的 item_types 拒绝了多次......(3 种完全不同的类型,因此如果优化了 3 个 SQL 查询)。

table passage
  id_passage PK
  business_field_passage bytea

table item
  id_item PK
  id_passage FK …
Run Code Online (Sandbox Code Playgroud)

postgresql join select

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

VACUUM 将磁盘空间返还给操作系统

VACUUM通常不会将磁盘空间返回给操作系统,除非在某些特殊情况下。
从文档:

VACUUM删除表和索引中的死行版本并标记可用空间以供将来重用的标准形式。但是,它不会将空间返回给操作系统,除非在表末尾的一个或多个页面完全空闲并且可以轻松获得排他表锁的特殊情况下。相比之下,VACUUM FULL通过编写一个没有死空间的完整新版本的表文件来主动压缩表。这最大限度地减少了表的大小,但可能需要很长时间。它还需要额外的磁盘空间用于表的新副本,直到操作完成。

问题是:如何实现这个数据库状态one or more pages at the end of a table become entirely free?这可以通过 完成VACUUM FULL,但我没有足够的空间来实现它。那么还有没有其他可能呢?

postgresql maintenance disk-space vacuum postgresql-9.2

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

在数据库中强制执行“至少一个”或“恰好一个”的约束

假设我们有用户,每个用户可以有多个电子邮件地址

CREATE TABLE emails (
    user_id integer,
    email_address text,
    is_active boolean
)
Run Code Online (Sandbox Code Playgroud)

一些示例行

user_id | email_address | is_active
1       | foo@bar.com   | t
1       | baz@bar.com   | f
1       | bar@foo.com   | f
2       | ccc@ddd.com   | t
Run Code Online (Sandbox Code Playgroud)

我想强制执行一个约束,即每个用户都只有一个活动地址。我怎样才能在 Postgres 中做到这一点?我可以这样做:

CREATE UNIQUE INDEX "user_email" ON emails(user_id) WHERE is_active=true;
Run Code Online (Sandbox Code Playgroud)

这可以防止用户拥有多个活动地址,但我相信不会防止他们的所有地址都设置为 false。

如果可能的话,我更愿意避免使用触发器或 pl/pgsql 脚本,因为我们目前没有这些脚本,而且设置起来会很困难。但我很感激知道“唯一的方法是使用触发器或 pl/pgsql”,如果是这样的话。

postgresql database-design constraint referential-integrity ddl

28
推荐指数
3
解决办法
8683
查看次数

UPSERT 与 ON CONFLICT 使用 UPDATE 部分中的源表中的值

鉴于:

CREATE TABLE A (
PK_A INT8 NOT NULL,
A INT8,
PRIMARY KEY (PK_A)
);

CREATE TABLE B (
PK_B INT8 NOT NULL,
B INT8,
PRIMARY KEY (PK_B)
);
Run Code Online (Sandbox Code Playgroud)

这个查询:

insert into table_b (pk_b, b) 
select pk_a,a from table_a 
on conflict (b) do update set b=a;
Run Code Online (Sandbox Code Playgroud)

导致以下错误:

ERROR:  column "a" does not exist
LINE 1: ...elect pk_a,a from table_a on conflict (b) do update set b=a;
                                                                 ^
HINT:  There is a column named "a" in table "*SELECT*", but it cannot …
Run Code Online (Sandbox Code Playgroud)

postgresql upsert postgresql-9.5

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