标签: postgresql-10

Postgres jsonb 与复合类型的性能差异

在 jsonb 列和相同结构的复合类型列之间进行选择需要考虑哪些因素?

例如,考虑 Postgres 文档中使用的类似列:

CREATE TYPE inventory_item AS (
name            text,
supplier_id     integer,
price           numeric
);
Run Code Online (Sandbox Code Playgroud)

这种方法与镜像这种结构的 jsonb 列之间的权衡是什么?

例如,我怀疑复合类型不需要存储每条记录的键名,而 jsonb 类型需要这样做。

postgresql database-design datatypes composite-types postgresql-10

9
推荐指数
2
解决办法
2055
查看次数

Postgresql 10 创建订阅挂起

在我的本地机器上,我刚刚升级到最新的 postgres.app 以获得版本 10。在此之前,我在 9.6 数据库上运行 pg_dumpall,然后在安装版本 10 后,我执行脚本以重新创建数据库、用户、等等...我还在从 dumpall 运行脚本并更新了一些日志记录设置后将 wal_level 更改为逻辑级别。

我首先在dot数据库中创建了一个订阅(作为超级用户)

bill=# \connect dot;
You are now connected to database "dot" as user "bill".
dot=# create publication foo for table dot.item;
CREATE PUBLICATION
Run Code Online (Sandbox Code Playgroud)

item 表中大约有 39k 行,所以同步数据应该不会花那么长时间。

接下来,我创建了一个新数据库dot2,该dot数据库由与该数据库相同的用户拥有,并在与dot数据库中存在的架构相同的模式中创建了一个空项目表,然后我尝试订阅另一个数据库中的发布(也作为超级用户)。

bill=# \connect dot2;
You are now connected to database "dot2" as user "bill".
dot2=# create subscription bar connection 'host=localhost port=5432 dbname=dot connect_timeout=10' PUBLICATION foo;
Run Code Online (Sandbox Code Playgroud)

然而,这只是挂起。它不会返回。

在我的日志中,我看到的只是这个......

2017-11-26 21:36:52.828 EST bill@dot2 54567 …
Run Code Online (Sandbox Code Playgroud)

postgresql replication postgresql-10

8
推荐指数
1
解决办法
2980
查看次数

如何将 PostgreSQL 10 标识列添加到现有表中?

我正在阅读有关新的Postgres 10 标识列的信息,并了解了如何使用它SERIALCREATE TABLE.

是否也可以向现有表添加标识列?

例如,使用旧SERIAL列,我可以执行以下操作:

ALTER TABLE sourceTable ADD  COLUMN ogc_fid SERIAL;
Run Code Online (Sandbox Code Playgroud)

对于标识列,是否有与上述相同的内容?我试过:

ALTER TABLE sourceTable ADD  COLUMN ogc_fid GENERATED BY DEFAULT AS IDENTITY;
Run Code Online (Sandbox Code Playgroud)

但是得到了一个错误:

错误:“BY”第 1 行或附近的语法错误:...R TABLE sourceTable ADD COLUMN ogc_fid GENERATED BY DEFAULT

我正在考虑用我的脚本中的SERIAL列替换列IDENTITY,只是想检查这是否可行。

postgresql alter-table identity postgresql-10

8
推荐指数
1
解决办法
7449
查看次数

PostgreSQL ANALYZE 执行时间超过 24 小时(仍在运行)

我使用 pg_upgrade(就地)升级了 Postgres DB 9.3.2-->10.5。我根据文档和 pg_upgrade 给出的说明做了一切。一切顺利,但后来我意识到索引没有在其中一个表中使用(也许其他表也受到影响)。

所以我ANALYZE昨天在那个桌子上开始了一个仍在运行的桌子上(超过 22 小时)......!

问题:ANALYZE执行时间这么长正常吗?

该表包含大约 30M 条记录。结构是:

CREATE TABLE public.chs_contact_history_events (
    event_id bigint NOT NULL
           DEFAULT nextval('chs_contact_history_events_event_id_seq'::regclass),
    chs_id integer NOT NULL,
    event_timestamp bigint NOT NULL,
    party_id integer NOT NULL,
    event integer NOT NULL,
    cause integer NOT NULL,
    text text COLLATE pg_catalog."default",
    timestamp_offset integer,
    CONSTRAINT pk_contact_history_events PRIMARY KEY (event_id)
);

ALTER TABLE public.chs_contact_history_events OWNER to c_chs;

CREATE INDEX ix_chs_contact_history_events_chsid
    ON public.chs_contact_history_events USING hash (chs_id)
    TABLESPACE pg_default;

CREATE INDEX ix_chs_contact_history_events_id
    ON …
Run Code Online (Sandbox Code Playgroud)

postgresql performance index disaster-recovery postgresql-10

8
推荐指数
1
解决办法
872
查看次数

更新嵌套在 JSON 对象数组中给定键的所有值

我在 Postgres 表中有一个jsonb列。它包含以下数据:datamy_table

[
   {"id":"1","status":"test status1","updatedAt":"1571145003"},
   {"id":"2","status":"test status2","updatedAt":"1571145323"}
]
Run Code Online (Sandbox Code Playgroud)

我想updatedAt使用一个查询更新该数组中所有对象的键。我试过:

update my_table set data = data || '{"updatedAt": "1571150000"}';
Run Code Online (Sandbox Code Playgroud)

上面的查询在数组中添加了一个新对象,如下所示:

[
   {"id":"1","status":"test status1","updatedAt":"1571145003"},
   {"id":"2","status":"test status2","updatedAt":"1571145323"},
   {"updatedAt":"1571150000"}
]
Run Code Online (Sandbox Code Playgroud)

我想要的输出如下:

[
   {"id":"1","status":"test status1","updatedAt":"1571150000"},
   {"id":"2","status":"test status2","updatedAt":"1571150000"}
]
Run Code Online (Sandbox Code Playgroud)

我也尝试过jsonb_set(),但这需要第二个参数是数组索引。我无法确定数组中 JSON 对象的数量。

如果可以通过自定义函数解决这个问题,也很好。

postgresql update json postgresql-10 json-path

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

使用默认关键字插入多行时,PostgreSQL 10 标识列获得“空值”

我最近从 PostgreSQL 9.5 升级到 PostgreSQL 10。PostgreSQL 10 中的一个漂亮特性是新的标识列类型,它是 PostgreSQL串行伪类型的替代品。身份栏的官方文档可以在CREATE TABLE一页中找到。

但是,当将多行插入到带有GENERATED BY DEFAULT AS IDENTITY列的表中使用关键字DEFAULT获取下一个 ID 值时,默认值返回为null.

例如,假设我有一张桌子

CREATE TABLE test (
  id int GENERATED BY DEFAULT AS IDENTITY,
  t text
);
CREATE TABLE
Run Code Online (Sandbox Code Playgroud)

使用DEFAULT关键字插入单行似乎工作正常。

INSERT INTO test (id, t) VALUES (DEFAULT, 'a');
INSERT 0 1
Run Code Online (Sandbox Code Playgroud)

插入多行不会。

INSERT INTO test (id, t) VALUES (DEFAULT, 'b'), (DEFAULT, 'c');
ERROR:  null value in column "id" violates …
Run Code Online (Sandbox Code Playgroud)

postgresql identity postgresql-10

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

在参数化查询中传递数据类型区间的值

上下文正在从其余服务器连接到 Postgres 数据库。

考虑一个假设的代表性示例:我希望能够获取帐户创建日期比任意值早/新的名称列表。

在下面的示例查询中,表结构很简单 -name是 type text,并且creation_date是 type timestamp。所以当我做类似的事情时

server_pg_module:query("select name from new_table where 
current_timestamp - creation_date < '6 days'") 
Run Code Online (Sandbox Code Playgroud)

它工作得很好。但我真正想做的是6 days从服务器获取该值。所以我尝试像

server_pg_module:query("select name from new_table where
current_timestamp - timestamp < $1", ["6 days"]
Run Code Online (Sandbox Code Playgroud)

它抛出一个错误。我试过'6 days'"'6 days'"以及其他一些混合物,都抛出错误。所以为了检查我添加了一个新interval的类型列interval并尝试了一个查询

server_pg_module:query("insert into new_table (name, interval) values ($1, '3 day')", ["fooo"]). 
Run Code Online (Sandbox Code Playgroud)

哪个有效,但是

server_pg_module:query("insert into new_table (name, interval) values ($1, $2)", ["fooo", "3 days"]). 
Run Code Online (Sandbox Code Playgroud)

休息。为了更好的衡量,除了"'3 days'"上面提到的混合物之外,我还尝试过 …

postgresql datatypes parameter interval postgresql-10

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

在 postgreSQL-10 中创建存储过程时出错

我无法让我的第一个存储过程工作,所以我从手册中复制了这个例子:

CREATE PROCEDURE insert_data(a integer, b integer)
LANGUAGE SQL
AS $$
INSERT INTO tbl VALUES (a);
INSERT INTO tbl VALUES (b);
$$;

CALL insert_data(1, 2);
Run Code Online (Sandbox Code Playgroud)

我收到以下错误消息:

ERROR:  syntax error at or near "PROCEDURE"
LINE 1: CREATE PROCEDURE insert_data(a integer, b integer)
               ^
SQL state: 42601
Character: 8
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

我在本地主机上运行数据库,以管理员用户身份运行。我自己安装的。安装过程无错误完成,我能够创建表、函数、触发器等。

postgresql stored-procedures errors postgresql-10

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

字段名称中的 json_object_agg 错误为 null

PostgreSQL 版本:我的本地安装是 11.3,下面的小提琴是 10.0。两者的行为相同。

我有一个页面架构,每个页面都有部分,每个部分可以有不同类型的内容。当我查询某个页面时,我希望在 JSON 文档中输出有关该页面的所有信息。

我将 CTE 用于json_agg()每个部分的各种内容。最后,我将各个部分连接起来json_object_agg(),将部分标题映射到部分内容。

问题: json_object_agg()当页面没有任何部分时抛出错误。我已经通过使用没有章节标题的常规来验证有罪json_agg()。确切的错误:

error: field name must not be null
Run Code Online (Sandbox Code Playgroud)

我想要的:无论如何都不是错误。我不想在接收方进行自定义错误处理。如果查询可以返回 JSONNull来代替json_object_agg()没有部分的情况,那就更好了,但这是可选的。(欢迎其他优雅的解决方案)

文档

可能文档不完整或者我遗漏了一些东西。仅供参考。

聚合表达式上它说(强调我的):

大多数聚合函数都会忽略 null 输入,因此一个或多个表达式产生null 的行将被丢弃。除非另有说明,对于所有内置聚合,这可以 假定为 true 。

聚合函数中,json_object_agg()没有评论不处理null

将名称/值对聚合为 JSON 对象

摆弄错误的域参数。将域更改为其他选项可以使其正常工作。使用不存在的域也可以正常工作并返回 0 行。

询问

with secs as (
    select p.page_id, p.domain, s.section_id as sid, s.title as title
    from pages p
    left …
Run Code Online (Sandbox Code Playgroud)

postgresql aggregate json postgresql-10 postgresql-11

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

为什么没有 max(uuid)/min(uuid) 函数?

为什么我可以使用 UUID 对行进行排序:

SELECT uuid_nil()
ORDER BY 1;
Run Code Online (Sandbox Code Playgroud)

但我无法计算最大值:

SELECT max(uuid_nil());
Run Code Online (Sandbox Code Playgroud)

[42883] 错误:函数 max(uuid) 不存在
提示:没有函数与给定名称和参数类型匹配。您可能需要添加显式类型转换。

我知道我可以转换为字符类型 orORDER BYLIMIT 1。我只是好奇为什么我必须使用解决方法。

postgresql max uuid postgresql-10

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