标签: postgresql

如何交换来自 Postgres 表中特定列的两个值?

考虑一个包含 id 和 name 属性的表测试。

那个值。

Id   |   Name
1    |   Raj
2    |   Kumar
Run Code Online (Sandbox Code Playgroud)

从上面的示例表中,我只知道 id,因此我需要通过 Id 交换名称,如下所示,

Id   |   Name
1    |   Kumar
2    |   Raj
Run Code Online (Sandbox Code Playgroud)

postgresql

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

当没有结果并且指定了 LIMIT 时,SELECT 非常慢

我遇到了一个问题,SELECT查询很慢,因为当最终结果的数量为 0并且LIMIT指定了一个子句时,它不使用索引。

如果结果数大于 0,则 Postgres 使用索引并在 ~ 1ms 内返回结果。据我所知,这似乎总是正确的。

如果结果数为 0 且没有LIMIT使用,则 Postgres 使用索引,结果在 ~ 1ms 内返回

如果结果数为 0 并且LIMIT指定了 a,则 Postgres 会执行顺序扫描,结果大约需要 13,000 毫秒。

为什么 PostgreSQL 在最后一种情况下不使用索引?

基数:

总计约 2100 万行。
~ 300 万行WHERE related_id=1
~ 300 万行WHERE related_id=1 AND platform=p1
2 行WHERE related_id=1 AND platform=p2
0 行WHERE related_id=1 AND platform=p3
~ 800 万行WHERE platform=p2

Postgres 版本:9.4.6

表架构:

CREATE TYPE platforms AS ENUM ('p1', …
Run Code Online (Sandbox Code Playgroud)

postgresql performance index statistics postgresql-9.4 postgresql-performance

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

使用通常唯一标识行的字段对表进行规范化,但有时为空

如果之前有人问过并回答过这个问题,请原谅我。

我正在粗略地制定一个库存管理系统的架构,将在 PostgreSQL 中实现。我们所有的产品和服务都有一个 SKU。我们的大部分产品来自制造商或分销商,并带有单独的“项目编号”(无论是分销商的目录号、制造商的型号,等等)。然而,并非所有人都有这样的数字。我们有内部制造的小组件,通常没有项目编号。我们的服务没有项目编号。由于这些原因,以下 CREATE TABLE 对我来说很有意义。

场景A:

CREATE TABLE product (
   sku            text PRIMARY KEY,
   name           text UNIQUE NOT NULL, -- alternate key
   price          numeric NOT NULL CHECK (price > 0),
   quantity       numeric NOT NULL CHECK (quantity > 0),
   item_number   text -- hmmm...
);
Run Code Online (Sandbox Code Playgroud)

但是,我对此有两个问题。

  1. 有时(可能有 3% 到 5% 的时间),item_number 实际上等于SKU。也就是说,我的一个供应商特别在他们的产品上贴上了我怀疑不是全球唯一的 SKU,按照他们的项目编号设计。

  2. 无论是否等于 SKU,item_number(如果存在)在几乎所有情况下都足以唯一标识我的小商店域中的产品。

我担心将其标准化为 3NF。如果 item_number 有时为 null,则显然不能将其声明为备用键。但是,从语义上讲,它是一个唯一标识符,在我能想到的每种情况下都存在。那么我上面的表格,其中每个属性在功能上都依赖于非主要属性 item_number每当 item_number 存在时,是否标准化?我想不,但我当然不是专家。我想过做以下事情:

情景B

CREATE TABLE product (
   sku            text PRIMARY KEY REFERENCES …
Run Code Online (Sandbox Code Playgroud)

postgresql normalization database-design

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

从 information_schema.schemata 返回行需要什么权限?

在 postgres 中(我在 9.3.4)返回行需要什么权限

select * from information_schema.schemata
Run Code Online (Sandbox Code Playgroud)

9.3文档说,“是由当前启用的角色拥有”。这是否意味着调用者schemata必须拥有(或属于拥有)各种模式的角色?

后来在9.5 文档中,它说模式“当前用户可以访问(通过成为所有者或拥有某些特权)”。

当前尝试运行查询并返回 0 行的帐户已应用于该帐户grant usage on schema

允许数据库帐户在 information_schema.schemata` 视图中查看架构的权限是什么?

postgresql permissions information-schema postgresql-9.3

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

避免冗余聚合函数和/或按列分组的最佳方法

假设我有两个表:

福:

id
baz
Run Code Online (Sandbox Code Playgroud)

酒吧:

id
foo_id
boom
Run Code Online (Sandbox Code Playgroud)

所以一个 Foo 有很多 Bars。我经常发现自己需要为给定的一组 Foo 计算跨条的聚合,但我也想要一些来自 Foo 的属性。这样做的两种最直接的方法是丑陋的:

方法#1:不必要的聚合函数

select
  foo.id,
  min(foo.baz) as baz,
  min(bar.boom) as min_boom
from
  foo
join
  bar on foo.id = bar.foo_id
group by
  foo.id;
Run Code Online (Sandbox Code Playgroud)

方法#2:不必要的按列分组

select
  foo.id,
  foo.baz,
  min(bar.boom) as min_boom
from
  foo
join
  bar on foo.id = bar.foo_id
group by
  foo.id,
  foo.baz;
Run Code Online (Sandbox Code Playgroud)

当 Foo 除了“id”之外只有一个额外的列时,这并不是那么糟糕,但是如果需要包含许多列,那么分组的效率就会大大降低。像这样的查询解决了这两个问题,但似乎很笨拙:

select
  foo.id,
  foo.baz,
  x.min_boom
from
  foo
join
  (select
    foo_id, 
    min(boom) as min_boom
  from
    bar
  group by
    foo_id) x on x.foo_id = foo.id; …
Run Code Online (Sandbox Code Playgroud)

postgresql performance subquery postgresql-9.3 query-performance

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

是否可以将一个表的两个副本无缝地聚集在不同的排列中?

我有一个大约有 100M 行的表。它每天只插入一次数据,但我们需要做select很多事情。该selects为通常比较简单,但需要有时返回几千行的100S。

它基于三列node_id,是唯一的pricedatehour分别是整数、时间戳、整数。大多数查询都很慢,但我将它聚集到node_idpricedate这解决了大多数查询的缓慢问题。这些查询属于以下类型:

select * from mytable where node_id in (1,2,3,4)
Run Code Online (Sandbox Code Playgroud)

我们仍然偶尔需要做这样的查询:

select * from mytable where pricedate>='2016-05-01'
Run Code Online (Sandbox Code Playgroud)

这些仍然很慢,因为它是由node_id第一个聚集的。我们已经有了一个索引pricedate。问题是用户通常需要足够的数据,查询引擎会抛出索引并使用 seq 扫描。一旦它使用了 seq 扫描,它就会从以查询方式对数据进行聚类中受益匪浅。这导致了我遇到的问题,其中一些查询从一个聚类中受益,而其他查询从另一个中受益:

如果有一种方法可以拥有表的两个物理副本,其中一个副本以一种方式聚集,另一个以另一种方式聚集,但用户对它的访问似乎只有一张表,并且数据库引擎将确保它们是同步的。显然,这样做会受到写入处罚,但这对我们的使用来说无关紧要。

这样的事情可能吗?

我猜没有一种内置的方式来做我所描述的。无论如何,我想我会mytable_dup使用相同的唯一键约束调用一个表,但使用备用集群,然后设置触发器在插入/更新/删除主服务器时插入它。这似乎可行,但从这里开始,是否有一种合理的方法select可以有效地从复制表中提取?

我在家里运行 PostgreSQL 9.4,在 Google 上运行 9.5。

postgresql performance query-performance

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

使用与源数据库相同的语言环境设置还原 PostgreSQL 数据库

我在Ubuntu 14.04 LTS生产机器上有一个 PostreSQL 9.x 数据库。我的开发机器是基于Windows 7的,提供 PostreSQL 9.y。

我想在我的开发机器上恢复 Ubuntu PostreSQL 数据库。

我注意到 Ubuntu 数据库使用以下语言环境设置:

  • 字符集编码=UTF8
  • 整理顺序,字符串排序顺序=en_US.UTF-8
  • 字符类型,字符分类=en_US.UTF-8

当我在没有指定语言环境的情况下在 Windows 机器上恢复数据库时,它将被设置为

  • 字符集编码=UTF8
  • 整理顺序,字符串排序顺序=German_Germany.1252
  • 字符类型,字符分类=German_Germany.1252

我的计划是让我的开发机器上的数据库尽可能类似于我的 Ubuntu 机器上的数据库。所以我的想法是首先在我的 Windows 机器上创建一个具有生产匹配语言环境的数据库,然后将我的 Ubuntu 数据库prod-db.backup备份文件恢复到该创建的数据库中:

createdb --host=localhost --username=postgres --encoding=Unicode --lc-collate=en_US.UTF-8 --lc-ctype=en_US.UTF-8 --owner=prod prod-db
pg_restore --host=localhost --username=postgres --format=custom prod-db.backup --dbname=prod-db
Run Code Online (Sandbox Code Playgroud)

这个想法不起作用,因为createdb在 Windows 上会抱怨错误无效的语言环境名称 en_US.UTF-8

我去了一个狩猎找到Windows区域名称相匹配的Ubuntu的语言环境名称,其中包括使用的解决方案template0中模板的数据库,不同的区域设置标识符,如实验en_US.UTF-8 …

postgresql pg-restore

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

查找列中最常用的非停用词

简而言之,我有一个包含普通散文的 Postgres 列,我想确定所有行中x最常用的单词(“单词”是由空格分隔的一组字符,但不是停用词)。

我找到了两个几乎达到目标的解决方案:

SELECT *                                       
FROM   ts_stat($$SELECT to_tsvector('english', title) FROM item$$) 
ORDER  BY ndoc DESC
LIMIT  50;
Run Code Online (Sandbox Code Playgroud)

这很好,除了它返回词干。

SELECT   UNNEST(string_to_array(title, ' ')) AS word, COUNT(*) AS ct
FROM     item 
GROUP    BY 1 
ORDER    BY 2 DESC
LIMIT    50;
Run Code Online (Sandbox Code Playgroud)

这个返回完整的词,但包括停用词。

为简单起见:应该在 上找到停用词TABLE stop_words (lowercase_stopword text PRIMARY KEY)

有人可以帮我上网吗?

postgresql full-text-search string-manipulation

7
推荐指数
2
解决办法
2542
查看次数

平均年龄的天数的含义?

我想知道我的用户的平均年龄并执行以下操作:

# SELECT avg(age(birthday)) FROM "user";
                   avg
------------------------------------------
 33 years 10 mons 32 days 08:33:10.577946
Run Code Online (Sandbox Code Playgroud)

天数是什么意思?怎么可能超过31天?

我有 3746 条记录,而且我在 UTC 时区。

PS:我使用的是 Postgres 9.5.3

postgresql

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

如何在 RDS PostgreSQL 上授予设置复制属性?

在 AWS RDS 文档中,我看到rds_superuser可以:

授予和撤销所有不是 rds_superuser 角色的角色的复制属性。有关更多信息,请参阅 PostgreSQL 文档中的此部分。

来源:http : //docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html

但是,如果我尝试,在以我的身份登录时rds_superuser

ALTER ROLE ROLENAME WITH REPLICATION;
Run Code Online (Sandbox Code Playgroud)

我收到一条错误消息,指出由于不是超级用户,我无法执行该操作。

你们知道如何为用户设置复制属性吗?

postgresql amazon-rds

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