标签: postgresql

如何在 A 创建的表上默认将 SELECT 授予 B?

背景
在我的 PostgreSQL 实例中(比如只有一个表构成的一个唯一数据库),我有 2 个用户:

  • user_A, 谁可以创建和填充my_table,
  • user_B, 谁应该只能从中读取 ( SELECT) 。

碰巧的是,由于我无法控制的 API,user_A不断删除并my_table从头开始重新创建。
这会导致 上的user_B权限重置my_table

因此,我被迫

my_db=# GRANT SELECT on TABLE my_table TO user_B;
Run Code Online (Sandbox Code Playgroud)

每次user_A重新创建my_table.

注意:
我知道(参见。为在 postgresql 中创建的任何新表授予用户权限)只能为授予它们的用户创建的对象设置默认权限(即,user_B为创建的表设置默认权限会更容易)by user_B)——但这里的情况并非如此。

此外,如上面链接的问题所述,文档指定“您只能更改将由您自己或您所属的角色创建的对象的默认权限”
所以我可以有

CREATE ROLE super_role;
GRANT super_role TO user_A;
GRANT super_role TO user_B;
Run Code Online (Sandbox Code Playgroud)

然后SET ROLE super_roleuser_A创建表之前......但不幸的是我无法控制如何user_A创建它。 …

postgresql permissions

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

找到不受限制的数字类型的比例的最聪明方法是什么?

由于懒惰和方便,我在我的 PostgreSQL 数据库中以不受限制的数字类型集成了来自合作伙伴的大量数据。

然而,现在看来,根据该合作伙伴的不同出货量,数字的比例从零到超过 20 个小数位(或比例)不等,这没有多大意义,可能会无缘无故地消耗大量存储空间. 所以我想将我的数字字段限制在一个合理的范围内。

然而,因为我的合作伙伴没有提供任何建议,我想确定我的数据集中每个尺度的出现,以可能在 0 和 20 之间确定一个合理的中间地带(零显然不是一个选项,并且考虑到 1700 万行-算,总金额将受到我的决定的影响)。

在接下来的四舍五入过程中也需要使用它,以避免实际增加标度为零的值的标度。


长话短说,对于存储为任意数字的特定数字,计算它的最佳方法是什么?

我能想到的最好的方法是,但有没有更优雅的方法可以在不转换为文本的情况下做到这一点?

SELECT
  my_numeric,
  COALESCE(
    char_length(                            -- Finding size of string extracted by a...
      substring(my_numeric::text,'\.(\d*)') -- regexp to return all digits right from '.'
    ),                                      -- but if scale is 0 substring return NULL                               
  0                                         -- so I handled this inside a COALESCE
  ) AS my_numeric_scale
FROM
(VALUES
(0.1::numeric),
(0.12),(0.123),
(0.1234),
(0.12345),
(0.123456),
(0.000001),
(0.100000)
) foo …
Run Code Online (Sandbox Code Playgroud)

postgresql decimal

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

一次更新多个值

我的任务是更新数据库中的几行。有两列,其中一列是ID,另一列是CURRENCY。我已经使用下面的更新语句更新了这些行:

update account set currency = 'INR' where id =15;
update account set currency = 'EURO' where id =12;
update account set currency = 'DOLLAR' where id =18;
update account set currency = 'Pound' where id =13; 
-- and so on.
Run Code Online (Sandbox Code Playgroud)

实际上,在这种情况下,由于行数相对较少,我可以使用这些更新语句轻松完成,但是如果有数千或数十万行怎么办?这是更新它们的唯一方法,还是有其他方法或脚本?

postgresql update

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

PostgreSQL:将行转换为类型

我读过:使用复合类型创建新表

我有一个名为 的表locations,例如用 lat 表示对象。和长。坐标。

在另一个表中,我声明了一个类型的列locations(只是为了好玩,而不是试图变得聪明),即

CREATE TABLE XXX (..., some_column locations, ...);
Run Code Online (Sandbox Code Playgroud)

现在我在问自己这意味着什么,是否可以locations在其中存储一个对象。

这就是我试图做的:

SELECT pg_typeof(ROW(x)) FROM locations x LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

返回record. 我尝试将其转换为locations,即

SELECT ROW(x)::locations FROM locations X LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

这产生

ERROR:  cannot cast type record to locations
Run Code Online (Sandbox Code Playgroud)

接下来我尝试type_location根据locations表的列定义一个复合类型,并基于它创建一个类型化表( CREATE TABLE ... OF ...)。我仍然无法做到ROW(x)::locations

最终,我试图将一个值存储到XXX类型locations(或type_location)表中,但我不明白我的推理哪一部分是错误的。

PS:我并不是要使用这种结构来创建一个健全的数据库设计,而实际上只是在玩弄 PostgreSQL 及其类型系统。

postgresql datatypes composite-types

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

无法在 PostgreSQL 11.5 中创建 COMMIT 过程

我正在尝试学习 PostgreSQL 存储过程。具体在 PSQL 中创建以下过程。

CREATE OR REPLACE PROCEDURE BUILD_AND_POPULATE(INOUT cresults refcursor) 
    LANGUAGE PLPGSQL 
    AS $$
    BEGIN
        BEGIN; -- I've tried removing this but the behaviour is the same
        cresults:= 'cur';
        DROP TABLE IF EXISTS procsampledata;
        CREATE TABLE procsampledata as select x,1 as c2,2 as c3, md5(random()::text) from generate_series(1,10) x;  
        COMMIT;
        OPEN cresults FOR SELECT * FROM procsampledata;  
    END;
$$;
Run Code Online (Sandbox Code Playgroud)

然后我像这样执行它,但收到一个错误:

postgres=# call build_and_populate(null);
ERROR:  invalid transaction termination
CONTEXT:  PL/pgSQL function build_and_populate(refcursor) line 6 at COMMIT
Run Code Online (Sandbox Code Playgroud)

我试过将 AUTOCOMMIT 设置为打开和关闭。

这是我的 …

postgresql plpgsql

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

Postgres 对单词的全文搜索,而不是词素

我有一个包含文本列的表格,我想按word搜索,而不是lexeme。更重要的是,我想按单词而不是词素进行索引。我们有大量代码引用的错误转储,它们不适用于任何自然语言词典。

Postgres 有没有办法让 FTS 按单词边界解析而不将单词解析为词素?如果我必须定义一个边界字符列表和一个跳过词目录,那可能没问题。这是否需要制作某种自定义词典,还是已经有类似的东西可用?

我一直认为我错过了一些明显的东西,然后找不到它。

目前,trigram 索引还可以,但我真的更喜欢文本的唯一关键字解析器。

RDS 上的 Postgres 11.4。

postgresql full-text-search

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

查询挂在 ClientRead 中并阻止所有其他查询

这与调试挂起的会话/锁定有关

每隔一段时间(大约一个月 1-2 次)我们就会锁定我们的数据库,因为有一个查询没有完成,并且请求的锁阻塞了所有其他查询。这是我们业务的核心所在,因此会导致停机。

有问题的查询是几个候选之一,所有这些都只是UPDATE在 1 行上运行的simple s。迄今为止我拥有的最好的线索(我对其他途径持开放态度)来自 RDS 性能见解,我看到虽然所有其他查询都锁定在“元组”上,但总是有 1 个查询锁定在“ClientRead”上。根据我的研究,这似乎是 Postgres 等待客户端库向它发送绑定参数或类似的。所以我的理论是,有一个查询有时会随机地以这种状态结束,这会阻止它之后的所有其他查询。这是一个合理的评价吗?

如果是这种情况,我该如何进行调查和解决?我们使用sequelize 5.9.4(node-js)。我们最近确实升级了它,大约 1-2 个月前,所以我想知道这个版本中是否可能存在一个错误,这可能会在处理查询时导致 sequelize 方面的错误,这可能吗?它也可能是一个错误node-postgres,这在我的搜索https://github.com/brianc/node-postgres/issues/1952 中出现

下次发生时,我将尝试使用 RDS 性能洞察的屏幕截图进行更新,其保留时间比预期的要短。

postgresql locking sequelize

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

为什么 log(greatest()) 这么慢?

我们有一些非常慢的复杂查询。我设法将查询简化为简单的复制。看来,组合greatestlog是原因,但我不明白为什么。

这是运行查询的完整sql-fiddle 示例- 您也可以View the execution Plans查询(按 sql-fiddle 页面上查询结果底部的链接)

所以这里是查询:

select count(value)
from (
         SELECT  log(greatest(1e-9, x)) as value
         from (select generate_series(1, 20000, 1) as x) as d
     ) t;
Run Code Online (Sandbox Code Playgroud)

我们只是生成一系列 20k 数字并使用log(greatest()). 此查询大约需要1.5秒。

我认为计算日志可能需要很长时间,但以下查询也很快(~5ms):

select count(value)
from (
         SELECT  log(x) as value
         from (select generate_series(1, 20000, 1) as x) as d
     ) t;
Run Code Online (Sandbox Code Playgroud)

正如测试我交换greatestlog-这也是快速(大约为5ms):

select count(value)
from …
Run Code Online (Sandbox Code Playgroud)

postgresql performance query-performance

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

具有 NULL 值的复合唯一约束

具有以下表结构

CREATE TABLE favorite_comments(
   id SERIAL PRIMARY KEY NOT NULL,
   opinion_id BIGINT REFERENCES opinions(id),
   review_id BIGINT REFERENCES reviews(id),
   list_id INTEGER REFERENCES lists(id) NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

这是有效记录(与同一列表相关的评论和意见):

id,  opinion_id,  review_id,  list_id
-------------------------------------
1,          333,       NULL,        4
2,         NULL,        444,        4
Run Code Online (Sandbox Code Playgroud)

但我想防止相同的评论或意见可能出现两次与同一个列表相关:

id,  opinion_id,  review_id,  list_id
-------------------------------------
1,          333,       NULL,        4
2,         NULL,        444,        4
3,         NULL,        444,        4 <- WRONG
Run Code Online (Sandbox Code Playgroud)

我想添加一个检查条件唯一性的约束UNIQUE(opinion_id, list_id) OR UNIQUE(review_id, list_id),但是因为opinion_id,review_id可以是 NULL 我对此有一些麻烦

我试过这个但不起作用

ALTER TABLE favorite_comments ADD CONSTRAINT comments_can_only_be_saved_once_per_list UNIQUE …

postgresql constraint check-constraints unique-constraint

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

尽管 Postgres 中的排序规则相同,但排序不同

尽管使用的排序规则显然相同,但我对带有变音符号的项目得到了不同的排序结果。

因此,在我的 mac 盒中安装Postgress.app进行开发后,我创建了下表:

create table names (
    id int primary key,
    name varchar
)
Run Code Online (Sandbox Code Playgroud)

然后插入一些值

insert into names values (1, "Francisco");
insert into names values (2, "Ana");
insert into names values (3, "Ágata");
Run Code Online (Sandbox Code Playgroud)

然后像这样查询它们:

select name from names order by name;
Run Code Online (Sandbox Code Playgroud)

我得到了一个错误的排序顺序,如下所示:

Ana
Francisco
Ágata
Run Code Online (Sandbox Code Playgroud)

我可以确认

select datname, 
       datcollate
from pg_database;
Run Code Online (Sandbox Code Playgroud)

datcollate所有数据库值en_US.UTF-8

为了帮助我调试这个问题,我快速启动了一个具有相同数据、查询和整理的 RDS 实例,但这次我得到了正确的预期排序顺序:

Ágata
Ana
Francisco
Run Code Online (Sandbox Code Playgroud)

我在这里缺少什么,如何在我的开发框中配置 postgres 以使其按预期运行?

postgresql collation

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